From 9af6789314a01af17924b1c0ee06ac5d66016e00 Mon Sep 17 00:00:00 2001
From: librelois <c@elo.tf>
Date: Thu, 22 Apr 2021 21:28:12 +0200
Subject: [PATCH] [chore] move most of rust code in repos duniter-core &
 duniter-gva

---
 Cargo.lock                                    | 1820 ++++-------------
 Cargo.toml                                    |   15 -
 deny.toml                                     |    1 -
 neon/native/Cargo.toml                        |    2 +-
 rust-bins/duniter-dbex/Cargo.toml             |    7 +-
 rust-bins/duniter-dbex/src/export_bc.rs       |    2 +-
 rust-bins/duniter-dbex/src/main.rs            |   12 +-
 rust-bins/duniter-dbex/src/migrate.rs         |    6 +-
 rust-libs/dubp-wot/Cargo.toml                 |   23 -
 rust-libs/dubp-wot/README.md                  |   10 -
 rust-libs/dubp-wot/src/data/mod.rs            |  196 --
 rust-libs/dubp-wot/src/data/rusty.rs          |  258 ---
 rust-libs/dubp-wot/src/lib.rs                 |  561 -----
 .../dubp-wot/src/operations/centrality.rs     |  192 --
 rust-libs/dubp-wot/src/operations/density.rs  |   31 -
 rust-libs/dubp-wot/src/operations/distance.rs |  211 --
 rust-libs/dubp-wot/src/operations/mod.rs      |   21 -
 rust-libs/dubp-wot/src/operations/path.rs     |  107 -
 rust-libs/dubp-wot/tests/g1_genesis.bin       |  Bin 3223 -> 0 bytes
 rust-libs/dubp-wot/tests/g1_genesis.bin.gz    |  Bin 917 -> 0 bytes
 rust-libs/duniter-bc-reader/Cargo.toml        |   21 -
 rust-libs/duniter-bc-reader/src/lib.rs        |   30 -
 rust-libs/duniter-conf/Cargo.toml             |   10 -
 rust-libs/duniter-conf/src/gva_conf.rs        |  113 -
 rust-libs/duniter-conf/src/lib.rs             |   54 -
 rust-libs/duniter-dbs-write-ops/Cargo.toml    |   35 -
 .../duniter-dbs-write-ops/src/apply_block.rs  |  173 --
 rust-libs/duniter-dbs-write-ops/src/bc.rs     |  325 ---
 .../src/bc/identities.rs                      |   95 -
 rust-libs/duniter-dbs-write-ops/src/bc/txs.rs |  130 --
 rust-libs/duniter-dbs-write-ops/src/bc/uds.rs |   69 -
 rust-libs/duniter-dbs-write-ops/src/cm.rs     |   51 -
 rust-libs/duniter-dbs-write-ops/src/lib.rs    |   55 -
 rust-libs/duniter-dbs-write-ops/src/txs_mp.rs |  225 --
 rust-libs/duniter-dbs/Cargo.toml              |   48 -
 rust-libs/duniter-dbs/src/databases.rs        |   20 -
 rust-libs/duniter-dbs/src/databases/bc_v1.rs  |  158 --
 rust-libs/duniter-dbs/src/databases/bc_v2.rs  |   30 -
 rust-libs/duniter-dbs/src/databases/cm_v1.rs  |   18 -
 .../duniter-dbs/src/databases/network_v1.rs   |   24 -
 .../duniter-dbs/src/databases/txs_mp_v2.rs    |   29 -
 rust-libs/duniter-dbs/src/keys.rs             |   28 -
 rust-libs/duniter-dbs/src/keys/all.rs         |   57 -
 .../duniter-dbs/src/keys/block_number.rs      |   72 -
 rust-libs/duniter-dbs/src/keys/blockstamp.rs  |  100 -
 .../duniter-dbs/src/keys/dunp_node_id.rs      |  111 -
 rust-libs/duniter-dbs/src/keys/hash.rs        |  106 -
 rust-libs/duniter-dbs/src/keys/pubkey.rs      |  117 --
 .../duniter-dbs/src/keys/pubkey_and_sig.rs    |   69 -
 rust-libs/duniter-dbs/src/keys/source_key.rs  |   93 -
 rust-libs/duniter-dbs/src/keys/timestamp.rs   |   56 -
 rust-libs/duniter-dbs/src/keys/ud_id.rs       |  123 --
 rust-libs/duniter-dbs/src/keys/uid.rs         |   65 -
 rust-libs/duniter-dbs/src/keys/utxo_id.rs     |  124 --
 .../duniter-dbs/src/keys/wallet_conditions.rs |  112 -
 rust-libs/duniter-dbs/src/lib.rs              |  144 --
 rust-libs/duniter-dbs/src/open_dbs.rs         |  109 -
 rust-libs/duniter-dbs/src/values.rs           |   35 -
 rust-libs/duniter-dbs/src/values/block_db.rs  |  152 --
 .../duniter-dbs/src/values/block_head_db.rs   |   85 -
 .../duniter-dbs/src/values/block_meta.rs      |  133 --
 .../src/values/block_number_array_db.rs       |   53 -
 rust-libs/duniter-dbs/src/values/cindex_db.rs |   98 -
 rust-libs/duniter-dbs/src/values/dunp_head.rs |  124 --
 rust-libs/duniter-dbs/src/values/idty_db.rs   |   52 -
 rust-libs/duniter-dbs/src/values/iindex_db.rs |   81 -
 rust-libs/duniter-dbs/src/values/kick_db.rs   |   55 -
 rust-libs/duniter-dbs/src/values/mindex_db.rs |  105 -
 rust-libs/duniter-dbs/src/values/peer_card.rs |   58 -
 rust-libs/duniter-dbs/src/values/pubkey_db.rs |  149 --
 rust-libs/duniter-dbs/src/values/sindex_db.rs |  123 --
 .../duniter-dbs/src/values/source_amount.rs   |   67 -
 rust-libs/duniter-dbs/src/values/tx_db.rs     |   51 -
 rust-libs/duniter-dbs/src/values/txs.rs       |   51 -
 .../duniter-dbs/src/values/ud_entry_db.rs     |   79 -
 rust-libs/duniter-dbs/src/values/utxo.rs      |  159 --
 rust-libs/duniter-dbs/src/values/wallet_db.rs |   55 -
 .../src/values/wallet_script_with_sa.rs       |   52 -
 rust-libs/duniter-dbs/tests/test_explorer.rs  |  253 ---
 .../duniter-dbs/tests/test_read_write.rs      |  405 ----
 rust-libs/duniter-dbs/tests/test_tmp_real.rs  |  767 -------
 rust-libs/duniter-global/Cargo.toml           |   18 -
 rust-libs/duniter-global/src/lib.rs           |  155 --
 rust-libs/duniter-mempools/Cargo.toml         |   22 -
 rust-libs/duniter-mempools/src/lib.rs         |  133 --
 rust-libs/duniter-module/Cargo.toml           |   22 -
 rust-libs/duniter-module/src/lib.rs           |  344 ----
 rust-libs/duniter-server/Cargo.toml           |   12 +-
 rust-libs/duniter-server/src/fill_cm.rs       |    4 +-
 .../src/legacy/block_indexer.rs               |    8 +-
 rust-libs/duniter-server/src/legacy/dunp.rs   |   25 +-
 .../duniter-server/src/legacy/txs_mempool.rs  |   10 +-
 rust-libs/duniter-server/src/lib.rs           |   32 +-
 rust-libs/modules/gva/Cargo.toml              |   42 -
 rust-libs/modules/gva/bca/Cargo.toml          |   33 -
 .../modules/gva/bca/src/exec_req_type.rs      |   99 -
 .../gva/bca/src/exec_req_type/balances.rs     |   61 -
 .../gva/bca/src/exec_req_type/current_ud.rs   |   30 -
 .../last_blockstamp_out_of_fork_window.rs     |   99 -
 .../bca/src/exec_req_type/members_count.rs    |   52 -
 .../exec_req_type/prepare_simple_payment.rs   |  223 --
 .../gva/bca/src/exec_req_type/send_txs.rs     |   63 -
 .../gva/bca/src/exec_req_type/utxos.rs        |   58 -
 rust-libs/modules/gva/bca/src/lib.rs          |  412 ----
 rust-libs/modules/gva/bca/types/Cargo.toml    |   20 -
 rust-libs/modules/gva/bca/types/src/amount.rs |   46 -
 .../modules/gva/bca/types/src/identity.rs     |   22 -
 rust-libs/modules/gva/bca/types/src/lib.rs    |  144 --
 .../gva/bca/types/src/prepare_payment.rs      |   32 -
 .../modules/gva/bca/types/src/rejected_tx.rs  |   30 -
 rust-libs/modules/gva/bca/types/src/utxo.rs   |   23 -
 rust-libs/modules/gva/db/Cargo.toml           |   32 -
 rust-libs/modules/gva/db/src/keys.rs          |   17 -
 .../modules/gva/db/src/keys/gva_utxo_id.rs    |  166 --
 .../gva/db/src/keys/wallet_hash_with_bn.rs    |  119 --
 rust-libs/modules/gva/db/src/lib.rs           |   71 -
 rust-libs/modules/gva/db/src/values.rs        |   18 -
 .../modules/gva/db/src/values/gva_idty_db.rs  |   54 -
 rust-libs/modules/gva/db/src/values/gva_tx.rs |   56 -
 .../gva/db/src/values/wallet_script_array.rs  |   53 -
 rust-libs/modules/gva/dbs-reader/Cargo.toml   |   31 -
 rust-libs/modules/gva/dbs-reader/src/block.rs |  228 ---
 .../gva/dbs-reader/src/current_frame.rs       |   33 -
 .../modules/gva/dbs-reader/src/find_inputs.rs |  241 ---
 rust-libs/modules/gva/dbs-reader/src/idty.rs  |   70 -
 rust-libs/modules/gva/dbs-reader/src/lib.rs   |  341 ---
 .../modules/gva/dbs-reader/src/network.rs     |  200 --
 .../modules/gva/dbs-reader/src/pagination.rs  |  144 --
 .../modules/gva/dbs-reader/src/txs_history.rs |  836 --------
 .../gva/dbs-reader/src/uds_of_pubkey.rs       |  829 --------
 rust-libs/modules/gva/dbs-reader/src/utxos.rs |  500 -----
 rust-libs/modules/gva/gql/Cargo.toml          |   37 -
 rust-libs/modules/gva/gql/src/entities.rs     |  112 -
 .../modules/gva/gql/src/entities/block_gva.rs |  176 --
 .../modules/gva/gql/src/entities/idty_gva.rs  |   20 -
 .../modules/gva/gql/src/entities/network.rs   |   74 -
 .../modules/gva/gql/src/entities/tx_gva.rs    |   84 -
 .../modules/gva/gql/src/entities/ud_gva.rs    |   48 -
 .../modules/gva/gql/src/entities/utxos_gva.rs |   42 -
 rust-libs/modules/gva/gql/src/inputs.rs       |   57 -
 .../modules/gva/gql/src/inputs_validators.rs  |   36 -
 rust-libs/modules/gva/gql/src/lib.rs          |  157 --
 rust-libs/modules/gva/gql/src/mutations.rs    |   86 -
 rust-libs/modules/gva/gql/src/pagination.rs   |   73 -
 rust-libs/modules/gva/gql/src/queries.rs      |   86 -
 .../gva/gql/src/queries/account_balance.rs    |  143 --
 .../modules/gva/gql/src/queries/block.rs      |  142 --
 .../gva/gql/src/queries/current_block.rs      |   65 -
 .../gva/gql/src/queries/current_frame.rs      |   94 -
 .../gql/src/queries/first_utxos_of_scripts.rs |   65 -
 .../modules/gva/gql/src/queries/gen_tx.rs     |  277 ---
 rust-libs/modules/gva/gql/src/queries/idty.rs |   81 -
 .../modules/gva/gql/src/queries/network.rs    |  144 --
 .../gva/gql/src/queries/txs_history.rs        |  345 ----
 rust-libs/modules/gva/gql/src/queries/uds.rs  |  185 --
 .../gva/gql/src/queries/utxos_of_script.rs    |  103 -
 rust-libs/modules/gva/gql/src/scalars.rs      |   83 -
 rust-libs/modules/gva/gql/src/schema.rs       |   74 -
 .../modules/gva/gql/src/subscriptions.rs      |   62 -
 .../gva/gql/src/subscriptions/new_blocks.rs   |   51 -
 .../src/subscriptions/receive_pending_txs.rs  |   52 -
 rust-libs/modules/gva/indexer/Cargo.toml      |   25 -
 .../modules/gva/indexer/src/identities.rs     |   80 -
 rust-libs/modules/gva/indexer/src/lib.rs      |  593 ------
 rust-libs/modules/gva/indexer/src/tx.rs       |  514 -----
 rust-libs/modules/gva/indexer/src/utxos.rs    |   86 -
 rust-libs/modules/gva/src/anti_spam.rs        |  201 --
 rust-libs/modules/gva/src/lib.rs              |  367 ----
 rust-libs/modules/gva/src/warp_.rs            |  323 ---
 .../duniter-integration-tests/Cargo.toml      |    7 +-
 rust-libs/tools/kv_typed/Cargo.toml           |   59 -
 .../kv_typed/benches/compare_backends.rs      |  146 --
 rust-libs/tools/kv_typed/src/as_bytes.rs      |   86 -
 rust-libs/tools/kv_typed/src/backend.rs       |  100 -
 .../tools/kv_typed/src/backend/leveldb.rs     |  364 ----
 rust-libs/tools/kv_typed/src/backend/lmdb.rs  |  404 ----
 .../tools/kv_typed/src/backend/memory.rs      |  284 ---
 .../kv_typed/src/backend/memory_singleton.rs  |  186 --
 rust-libs/tools/kv_typed/src/backend/mock.rs  |   85 -
 rust-libs/tools/kv_typed/src/backend/sled.rs  |  205 --
 rust-libs/tools/kv_typed/src/batch.rs         |  106 -
 rust-libs/tools/kv_typed/src/bytes.rs         |   62 -
 .../tools/kv_typed/src/collection_inner.rs    |   43 -
 rust-libs/tools/kv_typed/src/collection_ro.rs |  267 ---
 rust-libs/tools/kv_typed/src/collection_rw.rs |  100 -
 rust-libs/tools/kv_typed/src/db_schema.rs     |  242 ---
 rust-libs/tools/kv_typed/src/error.rs         |   75 -
 rust-libs/tools/kv_typed/src/event.rs         |   31 -
 rust-libs/tools/kv_typed/src/explorer.rs      |  529 -----
 rust-libs/tools/kv_typed/src/from_bytes.rs    |  127 --
 rust-libs/tools/kv_typed/src/iter.rs          |  214 --
 rust-libs/tools/kv_typed/src/iter/keys.rs     |   53 -
 rust-libs/tools/kv_typed/src/iter/values.rs   |   59 -
 rust-libs/tools/kv_typed/src/key.rs           |   93 -
 rust-libs/tools/kv_typed/src/lib.rs           |  153 --
 rust-libs/tools/kv_typed/src/subscription.rs  |  102 -
 .../tools/kv_typed/src/transactional_read.rs  |  211 --
 .../tools/kv_typed/src/transactional_write.rs |  237 ---
 .../src/transactional_write/tx_iter.rs        |  157 --
 rust-libs/tools/kv_typed/src/utils.rs         |   24 -
 rust-libs/tools/kv_typed/src/utils/arc.rs     |  267 ---
 rust-libs/tools/kv_typed/src/utils/ivec.rs    |  314 ---
 rust-libs/tools/kv_typed/src/value.rs         |  155 --
 .../tools/kv_typed/tests/test_db_schema.rs    |  221 --
 rust-libs/tools/kv_typed/tests/test_mock.rs   |   54 -
 205 files changed, 463 insertions(+), 26831 deletions(-)
 delete mode 100644 rust-libs/dubp-wot/Cargo.toml
 delete mode 100644 rust-libs/dubp-wot/README.md
 delete mode 100644 rust-libs/dubp-wot/src/data/mod.rs
 delete mode 100644 rust-libs/dubp-wot/src/data/rusty.rs
 delete mode 100644 rust-libs/dubp-wot/src/lib.rs
 delete mode 100644 rust-libs/dubp-wot/src/operations/centrality.rs
 delete mode 100644 rust-libs/dubp-wot/src/operations/density.rs
 delete mode 100644 rust-libs/dubp-wot/src/operations/distance.rs
 delete mode 100644 rust-libs/dubp-wot/src/operations/mod.rs
 delete mode 100644 rust-libs/dubp-wot/src/operations/path.rs
 delete mode 100644 rust-libs/dubp-wot/tests/g1_genesis.bin
 delete mode 100644 rust-libs/dubp-wot/tests/g1_genesis.bin.gz
 delete mode 100644 rust-libs/duniter-bc-reader/Cargo.toml
 delete mode 100644 rust-libs/duniter-bc-reader/src/lib.rs
 delete mode 100644 rust-libs/duniter-conf/Cargo.toml
 delete mode 100644 rust-libs/duniter-conf/src/gva_conf.rs
 delete mode 100644 rust-libs/duniter-conf/src/lib.rs
 delete mode 100644 rust-libs/duniter-dbs-write-ops/Cargo.toml
 delete mode 100644 rust-libs/duniter-dbs-write-ops/src/apply_block.rs
 delete mode 100644 rust-libs/duniter-dbs-write-ops/src/bc.rs
 delete mode 100644 rust-libs/duniter-dbs-write-ops/src/bc/identities.rs
 delete mode 100644 rust-libs/duniter-dbs-write-ops/src/bc/txs.rs
 delete mode 100644 rust-libs/duniter-dbs-write-ops/src/bc/uds.rs
 delete mode 100644 rust-libs/duniter-dbs-write-ops/src/cm.rs
 delete mode 100644 rust-libs/duniter-dbs-write-ops/src/lib.rs
 delete mode 100644 rust-libs/duniter-dbs-write-ops/src/txs_mp.rs
 delete mode 100644 rust-libs/duniter-dbs/Cargo.toml
 delete mode 100644 rust-libs/duniter-dbs/src/databases.rs
 delete mode 100644 rust-libs/duniter-dbs/src/databases/bc_v1.rs
 delete mode 100644 rust-libs/duniter-dbs/src/databases/bc_v2.rs
 delete mode 100644 rust-libs/duniter-dbs/src/databases/cm_v1.rs
 delete mode 100644 rust-libs/duniter-dbs/src/databases/network_v1.rs
 delete mode 100644 rust-libs/duniter-dbs/src/databases/txs_mp_v2.rs
 delete mode 100644 rust-libs/duniter-dbs/src/keys.rs
 delete mode 100644 rust-libs/duniter-dbs/src/keys/all.rs
 delete mode 100644 rust-libs/duniter-dbs/src/keys/block_number.rs
 delete mode 100644 rust-libs/duniter-dbs/src/keys/blockstamp.rs
 delete mode 100644 rust-libs/duniter-dbs/src/keys/dunp_node_id.rs
 delete mode 100644 rust-libs/duniter-dbs/src/keys/hash.rs
 delete mode 100644 rust-libs/duniter-dbs/src/keys/pubkey.rs
 delete mode 100644 rust-libs/duniter-dbs/src/keys/pubkey_and_sig.rs
 delete mode 100644 rust-libs/duniter-dbs/src/keys/source_key.rs
 delete mode 100644 rust-libs/duniter-dbs/src/keys/timestamp.rs
 delete mode 100644 rust-libs/duniter-dbs/src/keys/ud_id.rs
 delete mode 100644 rust-libs/duniter-dbs/src/keys/uid.rs
 delete mode 100644 rust-libs/duniter-dbs/src/keys/utxo_id.rs
 delete mode 100644 rust-libs/duniter-dbs/src/keys/wallet_conditions.rs
 delete mode 100644 rust-libs/duniter-dbs/src/lib.rs
 delete mode 100644 rust-libs/duniter-dbs/src/open_dbs.rs
 delete mode 100644 rust-libs/duniter-dbs/src/values.rs
 delete mode 100644 rust-libs/duniter-dbs/src/values/block_db.rs
 delete mode 100644 rust-libs/duniter-dbs/src/values/block_head_db.rs
 delete mode 100644 rust-libs/duniter-dbs/src/values/block_meta.rs
 delete mode 100644 rust-libs/duniter-dbs/src/values/block_number_array_db.rs
 delete mode 100644 rust-libs/duniter-dbs/src/values/cindex_db.rs
 delete mode 100644 rust-libs/duniter-dbs/src/values/dunp_head.rs
 delete mode 100644 rust-libs/duniter-dbs/src/values/idty_db.rs
 delete mode 100644 rust-libs/duniter-dbs/src/values/iindex_db.rs
 delete mode 100644 rust-libs/duniter-dbs/src/values/kick_db.rs
 delete mode 100644 rust-libs/duniter-dbs/src/values/mindex_db.rs
 delete mode 100644 rust-libs/duniter-dbs/src/values/peer_card.rs
 delete mode 100644 rust-libs/duniter-dbs/src/values/pubkey_db.rs
 delete mode 100644 rust-libs/duniter-dbs/src/values/sindex_db.rs
 delete mode 100644 rust-libs/duniter-dbs/src/values/source_amount.rs
 delete mode 100644 rust-libs/duniter-dbs/src/values/tx_db.rs
 delete mode 100644 rust-libs/duniter-dbs/src/values/txs.rs
 delete mode 100644 rust-libs/duniter-dbs/src/values/ud_entry_db.rs
 delete mode 100644 rust-libs/duniter-dbs/src/values/utxo.rs
 delete mode 100644 rust-libs/duniter-dbs/src/values/wallet_db.rs
 delete mode 100644 rust-libs/duniter-dbs/src/values/wallet_script_with_sa.rs
 delete mode 100644 rust-libs/duniter-dbs/tests/test_explorer.rs
 delete mode 100644 rust-libs/duniter-dbs/tests/test_read_write.rs
 delete mode 100644 rust-libs/duniter-dbs/tests/test_tmp_real.rs
 delete mode 100644 rust-libs/duniter-global/Cargo.toml
 delete mode 100644 rust-libs/duniter-global/src/lib.rs
 delete mode 100644 rust-libs/duniter-mempools/Cargo.toml
 delete mode 100644 rust-libs/duniter-mempools/src/lib.rs
 delete mode 100644 rust-libs/duniter-module/Cargo.toml
 delete mode 100644 rust-libs/duniter-module/src/lib.rs
 delete mode 100644 rust-libs/modules/gva/Cargo.toml
 delete mode 100644 rust-libs/modules/gva/bca/Cargo.toml
 delete mode 100644 rust-libs/modules/gva/bca/src/exec_req_type.rs
 delete mode 100644 rust-libs/modules/gva/bca/src/exec_req_type/balances.rs
 delete mode 100644 rust-libs/modules/gva/bca/src/exec_req_type/current_ud.rs
 delete mode 100644 rust-libs/modules/gva/bca/src/exec_req_type/last_blockstamp_out_of_fork_window.rs
 delete mode 100644 rust-libs/modules/gva/bca/src/exec_req_type/members_count.rs
 delete mode 100644 rust-libs/modules/gva/bca/src/exec_req_type/prepare_simple_payment.rs
 delete mode 100644 rust-libs/modules/gva/bca/src/exec_req_type/send_txs.rs
 delete mode 100644 rust-libs/modules/gva/bca/src/exec_req_type/utxos.rs
 delete mode 100644 rust-libs/modules/gva/bca/src/lib.rs
 delete mode 100644 rust-libs/modules/gva/bca/types/Cargo.toml
 delete mode 100644 rust-libs/modules/gva/bca/types/src/amount.rs
 delete mode 100644 rust-libs/modules/gva/bca/types/src/identity.rs
 delete mode 100644 rust-libs/modules/gva/bca/types/src/lib.rs
 delete mode 100644 rust-libs/modules/gva/bca/types/src/prepare_payment.rs
 delete mode 100644 rust-libs/modules/gva/bca/types/src/rejected_tx.rs
 delete mode 100644 rust-libs/modules/gva/bca/types/src/utxo.rs
 delete mode 100644 rust-libs/modules/gva/db/Cargo.toml
 delete mode 100644 rust-libs/modules/gva/db/src/keys.rs
 delete mode 100644 rust-libs/modules/gva/db/src/keys/gva_utxo_id.rs
 delete mode 100644 rust-libs/modules/gva/db/src/keys/wallet_hash_with_bn.rs
 delete mode 100644 rust-libs/modules/gva/db/src/lib.rs
 delete mode 100644 rust-libs/modules/gva/db/src/values.rs
 delete mode 100644 rust-libs/modules/gva/db/src/values/gva_idty_db.rs
 delete mode 100644 rust-libs/modules/gva/db/src/values/gva_tx.rs
 delete mode 100644 rust-libs/modules/gva/db/src/values/wallet_script_array.rs
 delete mode 100644 rust-libs/modules/gva/dbs-reader/Cargo.toml
 delete mode 100644 rust-libs/modules/gva/dbs-reader/src/block.rs
 delete mode 100644 rust-libs/modules/gva/dbs-reader/src/current_frame.rs
 delete mode 100644 rust-libs/modules/gva/dbs-reader/src/find_inputs.rs
 delete mode 100644 rust-libs/modules/gva/dbs-reader/src/idty.rs
 delete mode 100644 rust-libs/modules/gva/dbs-reader/src/lib.rs
 delete mode 100644 rust-libs/modules/gva/dbs-reader/src/network.rs
 delete mode 100644 rust-libs/modules/gva/dbs-reader/src/pagination.rs
 delete mode 100644 rust-libs/modules/gva/dbs-reader/src/txs_history.rs
 delete mode 100644 rust-libs/modules/gva/dbs-reader/src/uds_of_pubkey.rs
 delete mode 100644 rust-libs/modules/gva/dbs-reader/src/utxos.rs
 delete mode 100644 rust-libs/modules/gva/gql/Cargo.toml
 delete mode 100644 rust-libs/modules/gva/gql/src/entities.rs
 delete mode 100644 rust-libs/modules/gva/gql/src/entities/block_gva.rs
 delete mode 100644 rust-libs/modules/gva/gql/src/entities/idty_gva.rs
 delete mode 100644 rust-libs/modules/gva/gql/src/entities/network.rs
 delete mode 100644 rust-libs/modules/gva/gql/src/entities/tx_gva.rs
 delete mode 100644 rust-libs/modules/gva/gql/src/entities/ud_gva.rs
 delete mode 100644 rust-libs/modules/gva/gql/src/entities/utxos_gva.rs
 delete mode 100644 rust-libs/modules/gva/gql/src/inputs.rs
 delete mode 100644 rust-libs/modules/gva/gql/src/inputs_validators.rs
 delete mode 100644 rust-libs/modules/gva/gql/src/lib.rs
 delete mode 100644 rust-libs/modules/gva/gql/src/mutations.rs
 delete mode 100644 rust-libs/modules/gva/gql/src/pagination.rs
 delete mode 100644 rust-libs/modules/gva/gql/src/queries.rs
 delete mode 100644 rust-libs/modules/gva/gql/src/queries/account_balance.rs
 delete mode 100644 rust-libs/modules/gva/gql/src/queries/block.rs
 delete mode 100644 rust-libs/modules/gva/gql/src/queries/current_block.rs
 delete mode 100644 rust-libs/modules/gva/gql/src/queries/current_frame.rs
 delete mode 100644 rust-libs/modules/gva/gql/src/queries/first_utxos_of_scripts.rs
 delete mode 100644 rust-libs/modules/gva/gql/src/queries/gen_tx.rs
 delete mode 100644 rust-libs/modules/gva/gql/src/queries/idty.rs
 delete mode 100644 rust-libs/modules/gva/gql/src/queries/network.rs
 delete mode 100644 rust-libs/modules/gva/gql/src/queries/txs_history.rs
 delete mode 100644 rust-libs/modules/gva/gql/src/queries/uds.rs
 delete mode 100644 rust-libs/modules/gva/gql/src/queries/utxos_of_script.rs
 delete mode 100644 rust-libs/modules/gva/gql/src/scalars.rs
 delete mode 100644 rust-libs/modules/gva/gql/src/schema.rs
 delete mode 100644 rust-libs/modules/gva/gql/src/subscriptions.rs
 delete mode 100644 rust-libs/modules/gva/gql/src/subscriptions/new_blocks.rs
 delete mode 100644 rust-libs/modules/gva/gql/src/subscriptions/receive_pending_txs.rs
 delete mode 100644 rust-libs/modules/gva/indexer/Cargo.toml
 delete mode 100644 rust-libs/modules/gva/indexer/src/identities.rs
 delete mode 100644 rust-libs/modules/gva/indexer/src/lib.rs
 delete mode 100644 rust-libs/modules/gva/indexer/src/tx.rs
 delete mode 100644 rust-libs/modules/gva/indexer/src/utxos.rs
 delete mode 100644 rust-libs/modules/gva/src/anti_spam.rs
 delete mode 100644 rust-libs/modules/gva/src/lib.rs
 delete mode 100644 rust-libs/modules/gva/src/warp_.rs
 delete mode 100644 rust-libs/tools/kv_typed/Cargo.toml
 delete mode 100644 rust-libs/tools/kv_typed/benches/compare_backends.rs
 delete mode 100644 rust-libs/tools/kv_typed/src/as_bytes.rs
 delete mode 100644 rust-libs/tools/kv_typed/src/backend.rs
 delete mode 100644 rust-libs/tools/kv_typed/src/backend/leveldb.rs
 delete mode 100644 rust-libs/tools/kv_typed/src/backend/lmdb.rs
 delete mode 100644 rust-libs/tools/kv_typed/src/backend/memory.rs
 delete mode 100644 rust-libs/tools/kv_typed/src/backend/memory_singleton.rs
 delete mode 100644 rust-libs/tools/kv_typed/src/backend/mock.rs
 delete mode 100644 rust-libs/tools/kv_typed/src/backend/sled.rs
 delete mode 100644 rust-libs/tools/kv_typed/src/batch.rs
 delete mode 100644 rust-libs/tools/kv_typed/src/bytes.rs
 delete mode 100644 rust-libs/tools/kv_typed/src/collection_inner.rs
 delete mode 100644 rust-libs/tools/kv_typed/src/collection_ro.rs
 delete mode 100644 rust-libs/tools/kv_typed/src/collection_rw.rs
 delete mode 100644 rust-libs/tools/kv_typed/src/db_schema.rs
 delete mode 100644 rust-libs/tools/kv_typed/src/error.rs
 delete mode 100644 rust-libs/tools/kv_typed/src/event.rs
 delete mode 100644 rust-libs/tools/kv_typed/src/explorer.rs
 delete mode 100644 rust-libs/tools/kv_typed/src/from_bytes.rs
 delete mode 100644 rust-libs/tools/kv_typed/src/iter.rs
 delete mode 100644 rust-libs/tools/kv_typed/src/iter/keys.rs
 delete mode 100644 rust-libs/tools/kv_typed/src/iter/values.rs
 delete mode 100644 rust-libs/tools/kv_typed/src/key.rs
 delete mode 100644 rust-libs/tools/kv_typed/src/lib.rs
 delete mode 100644 rust-libs/tools/kv_typed/src/subscription.rs
 delete mode 100644 rust-libs/tools/kv_typed/src/transactional_read.rs
 delete mode 100644 rust-libs/tools/kv_typed/src/transactional_write.rs
 delete mode 100644 rust-libs/tools/kv_typed/src/transactional_write/tx_iter.rs
 delete mode 100644 rust-libs/tools/kv_typed/src/utils.rs
 delete mode 100644 rust-libs/tools/kv_typed/src/utils/arc.rs
 delete mode 100644 rust-libs/tools/kv_typed/src/utils/ivec.rs
 delete mode 100644 rust-libs/tools/kv_typed/src/value.rs
 delete mode 100644 rust-libs/tools/kv_typed/tests/test_db_schema.rs
 delete mode 100644 rust-libs/tools/kv_typed/tests/test_mock.rs

diff --git a/Cargo.lock b/Cargo.lock
index 7dd78769f..8e4c7d79f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -12,61 +12,24 @@ dependencies = [
 
 [[package]]
 name = "addr2line"
-version = "0.13.0"
+version = "0.14.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b6a2d3371669ab3ca9797670853d61402b03d0b4b9ebf33d677dfa720203072"
+checksum = "a55f82cfe485775d02112886f4169bde0c5894d75e79ead7eafe7e40a25e45f7"
 dependencies = [
  "gimli",
 ]
 
 [[package]]
 name = "adler"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
-
-[[package]]
-name = "aes"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "884391ef1066acaa41e766ba8f596341b96e93ce34f9a43e7d24bf0a0eaf0561"
-dependencies = [
- "aes-soft",
- "aesni",
- "cipher",
-]
-
-[[package]]
-name = "aes-soft"
-version = "0.6.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be14c7498ea50828a38d0e24a765ed2effe92a705885b57d029cd67d45744072"
-dependencies = [
- "cipher",
- "opaque-debug 0.3.0",
-]
-
-[[package]]
-name = "aesni"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea2e11f5e94c2f7d386164cc2aa1f97823fed6f259e486940a71c174dd01b0ce"
-dependencies = [
- "cipher",
- "opaque-debug 0.3.0",
-]
-
-[[package]]
-name = "ahash"
-version = "0.3.8"
+version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8fd72866655d1904d6b0997d0b07ba561047d070fbe29de039031c641b61217"
+checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
 
 [[package]]
 name = "aho-corasick"
-version = "0.7.14"
+version = "0.7.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b476ce7103678b0c6d3d395dbbae31d48ff910bd28be979ba5d48c6351131d0d"
+checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
 dependencies = [
  "memchr",
 ]
@@ -80,26 +43,11 @@ dependencies = [
  "winapi",
 ]
 
-[[package]]
-name = "ansi_term"
-version = "0.12.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
-dependencies = [
- "winapi",
-]
-
 [[package]]
 name = "anyhow"
-version = "1.0.34"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf8dcb5b4bbaa28653b647d8c77bd4ed40183b48882e130c1f1ffb73de069fd7"
-
-[[package]]
-name = "arc-swap"
-version = "0.4.7"
+version = "1.0.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4d25d88fd6b8041580a654f9d0c581a047baee2b3efee13275f2fc392fc75034"
+checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b"
 
 [[package]]
 name = "arrayref"
@@ -116,16 +64,6 @@ dependencies = [
  "serde",
 ]
 
-[[package]]
-name = "async-attributes"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "efd3d156917d94862e779f356c5acae312b08fd3121e792c857d7928c8088423"
-dependencies = [
- "quote",
- "syn",
-]
-
 [[package]]
 name = "async-bincode"
 version = "0.6.1"
@@ -141,87 +79,38 @@ dependencies = [
  "tokio",
 ]
 
-[[package]]
-name = "async-channel"
-version = "1.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59740d83946db6a5af71ae25ddf9562c2b176b2ca42cf99a455f09f4a220d6b9"
-dependencies = [
- "concurrent-queue",
- "event-listener",
- "futures-core",
-]
-
-[[package]]
-name = "async-executor"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d373d78ded7d0b3fa8039375718cde0aace493f2e34fb60f51cbf567562ca801"
-dependencies = [
- "async-task",
- "concurrent-queue",
- "fastrand",
- "futures-lite",
- "once_cell",
- "vec-arena",
-]
-
-[[package]]
-name = "async-global-executor"
-version = "1.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "124ac8c265e407641c3362b8f4d39cdb4e243885b71eef087be27199790f5a3a"
-dependencies = [
- "async-executor",
- "async-io",
- "futures-lite",
- "num_cpus",
- "once_cell",
-]
-
 [[package]]
 name = "async-graphql"
-version = "2.2.0"
+version = "2.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2c961bdf28cec79b4254c642cf8e55071ec6b7101b3a189ce17a61b909d70951"
+checksum = "bb5e71af65ee4a367603829e92b26710caf4116d1eaca8953dedf1809b33694a"
 dependencies = [
  "async-graphql-derive",
  "async-graphql-parser",
  "async-graphql-value",
- "async-mutex",
  "async-stream",
  "async-trait",
- "blocking",
- "bson",
- "chrono",
- "chrono-tz",
  "fnv",
  "futures-util",
+ "http",
  "indexmap",
  "log",
- "lru",
  "multer",
- "num-traits",
  "once_cell",
- "pin-project-lite 0.2.0",
+ "pin-project-lite",
  "regex",
  "serde",
  "serde_json",
- "sha2",
- "spin 0.7.0",
  "static_assertions",
  "tempfile",
  "thiserror",
- "tracing",
- "url",
- "uuid",
 ]
 
 [[package]]
 name = "async-graphql-derive"
-version = "2.2.0"
+version = "2.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87e8975da7722a0f338b3df87214299e5655bba607ce15eeb15d82daf2820333"
+checksum = "6fd4c2eb837e894909fe13509f2351fa3990c114426e41255936800892ccbe26"
 dependencies = [
  "Inflector",
  "async-graphql-parser",
@@ -235,9 +124,9 @@ dependencies = [
 
 [[package]]
 name = "async-graphql-parser"
-version = "2.1.2"
+version = "2.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee04e49c932b12a7a18163a59ee5596a83422e4b91cb64ca63e3545bd4c4560e"
+checksum = "2a8d8116f3015b7686ef98ffb70a74183c3c17bf45135993d3f095812e09e786"
 dependencies = [
  "async-graphql-value",
  "pest",
@@ -248,34 +137,14 @@ dependencies = [
 
 [[package]]
 name = "async-graphql-value"
-version = "2.0.5"
+version = "2.6.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57d3aa3cd3696ffd8decb10f5053affc78cb33ecfc545e480072bbc600e6723d"
+checksum = "d8342ada84efe4b3d59e1313d1d2740a8ccfc76ddb57ccf55e45a6464dd7d0d3"
 dependencies = [
  "serde",
  "serde_json",
 ]
 
-[[package]]
-name = "async-io"
-version = "1.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d54bc4c1c7292475efb2253227dbcfad8fe1ca4c02bc62c510cc2f3da5c4704e"
-dependencies = [
- "concurrent-queue",
- "fastrand",
- "futures-lite",
- "libc",
- "log",
- "nb-connect",
- "once_cell",
- "parking",
- "polling",
- "vec-arena",
- "waker-fn",
- "winapi",
-]
-
 [[package]]
 name = "async-mutex"
 version = "1.4.0"
@@ -304,39 +173,11 @@ dependencies = [
  "event-listener",
 ]
 
-[[package]]
-name = "async-std"
-version = "1.6.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a9fa76751505e8df1c7a77762f60486f60c71bbd9b8557f4da6ad47d083732ed"
-dependencies = [
- "async-attributes",
- "async-global-executor",
- "async-io",
- "async-mutex",
- "blocking",
- "crossbeam-utils 0.7.2",
- "futures-channel",
- "futures-core",
- "futures-io",
- "futures-lite",
- "gloo-timers",
- "kv-log-macro",
- "log",
- "memchr",
- "num_cpus",
- "once_cell",
- "pin-project-lite 0.1.11",
- "pin-utils",
- "slab",
- "wasm-bindgen-futures",
-]
-
 [[package]]
 name = "async-stream"
-version = "0.3.0"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3670df70cbc01729f901f94c887814b3c68db038aad1329a418bae178bc5295c"
+checksum = "0a26cb53174ddd320edfff199a853f93d571f48eeb4dde75e67a9a3dbb7b7e5e"
 dependencies = [
  "async-stream-impl",
  "futures-core",
@@ -344,26 +185,20 @@ dependencies = [
 
 [[package]]
 name = "async-stream-impl"
-version = "0.3.0"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a3548b8efc9f8e8a5a0a2808c5bd8451a9031b9e5b879a79590304ae928b0a70"
+checksum = "db134ba52475c060f3329a8ef0f8786d6b872ed01515d4b79c162e5798da1340"
 dependencies = [
  "proc-macro2",
  "quote",
  "syn",
 ]
 
-[[package]]
-name = "async-task"
-version = "4.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e91831deabf0d6d7ec49552e489aed63b7456a7a3c46cff62adad428110b0af0"
-
 [[package]]
 name = "async-trait"
-version = "0.1.41"
+version = "0.1.50"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b246867b8b3b6ae56035f1eb1ed557c1d8eae97f0d53696138a50fa0e3a3b8c0"
+checksum = "0b98e84bbb4cbcdd97da190ba0c58a1bb0de2c1fdf67d159e192ed766aeca722"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -381,12 +216,6 @@ dependencies = [
  "tokio",
 ]
 
-[[package]]
-name = "atomic-waker"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a"
-
 [[package]]
 name = "atty"
 version = "0.2.14"
@@ -398,12 +227,6 @@ dependencies = [
  "winapi",
 ]
 
-[[package]]
-name = "autocfg"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
-
 [[package]]
 name = "autocfg"
 version = "1.0.1"
@@ -412,9 +235,9 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
 
 [[package]]
 name = "backtrace"
-version = "0.3.53"
+version = "0.3.57"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "707b586e0e2f247cbde68cdd2c3ce69ea7b7be43e1c5b426e37c9319c4b9838e"
+checksum = "78ed203b9ba68b242c62b3fb7480f589dd49829be1edb3fe8fc8b4ffda2dcb8d"
 dependencies = [
  "addr2line",
  "cfg-if 1.0.0",
@@ -424,12 +247,6 @@ dependencies = [
  "rustc-demangle",
 ]
 
-[[package]]
-name = "base64"
-version = "0.12.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
-
 [[package]]
 name = "base64"
 version = "0.13.0"
@@ -444,20 +261,13 @@ checksum = "6736e2428df2ca2848d846c43e88745121a6654696e349ce0054a420815a7409"
 
 [[package]]
 name = "bincode"
-version = "1.3.2"
+version = "1.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d175dfa69e619905c4c3cdb7c3c203fa3bdd5d51184e3afdb2742c0280493772"
+checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
 dependencies = [
- "byteorder",
  "serde",
 ]
 
-[[package]]
-name = "bitflags"
-version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
-
 [[package]]
 name = "bitflags"
 version = "1.2.1"
@@ -466,9 +276,9 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
 
 [[package]]
 name = "blake2b_simd"
-version = "0.5.10"
+version = "0.5.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a"
+checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587"
 dependencies = [
  "arrayref",
  "arrayvec",
@@ -499,7 +309,7 @@ dependencies = [
  "block-padding",
  "byte-tools",
  "byteorder",
- "generic-array 0.12.3",
+ "generic-array 0.12.4",
 ]
 
 [[package]]
@@ -520,20 +330,6 @@ dependencies = [
  "byte-tools",
 ]
 
-[[package]]
-name = "blocking"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c5e170dbede1f740736619b776d7251cb1b9095c435c34d8ca9f57fcd2f335e9"
-dependencies = [
- "async-channel",
- "async-task",
- "atomic-waker",
- "fastrand",
- "futures-lite",
- "once_cell",
-]
-
 [[package]]
 name = "bs58"
 version = "0.3.1"
@@ -546,34 +342,6 @@ version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3"
 
-[[package]]
-name = "bson"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c11f16001d679cb13d14b2c93c7d0fa13bb484a87c34a6c4c39707ad936499b5"
-dependencies = [
- "base64 0.12.3",
- "chrono",
- "hex",
- "lazy_static",
- "linked-hash-map",
- "rand 0.7.3",
- "serde",
- "serde_json",
-]
-
-[[package]]
-name = "bstr"
-version = "0.2.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "473fc6b38233f9af7baa94fb5852dca389e3d95b8e21c8e3719301462c5d9faf"
-dependencies = [
- "lazy_static",
- "memchr",
- "regex-automata",
- "serde",
-]
-
 [[package]]
 name = "buf_redux"
 version = "0.8.4"
@@ -586,9 +354,9 @@ dependencies = [
 
 [[package]]
 name = "bumpalo"
-version = "3.4.0"
+version = "3.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820"
+checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe"
 
 [[package]]
 name = "byte-tools"
@@ -598,9 +366,9 @@ checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
 
 [[package]]
 name = "byteorder"
-version = "1.3.4"
+version = "1.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
+checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
 
 [[package]]
 name = "bytes"
@@ -614,21 +382,6 @@ version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040"
 
-[[package]]
-name = "cache-padded"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba"
-
-[[package]]
-name = "cast"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0"
-dependencies = [
- "rustc_version 0.2.3",
-]
-
 [[package]]
 name = "cc"
 version = "1.0.67"
@@ -663,16 +416,6 @@ dependencies = [
  "winapi",
 ]
 
-[[package]]
-name = "chrono-tz"
-version = "0.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2554a3155fec064362507487171dcc4edc3df60cb10f3a1fb10ed8094822b120"
-dependencies = [
- "chrono",
- "parse-zoneinfo",
-]
-
 [[package]]
 name = "ci_info"
 version = "0.10.2"
@@ -682,53 +425,26 @@ dependencies = [
  "envmnt",
 ]
 
-[[package]]
-name = "cipher"
-version = "0.2.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12f8e7987cbd042a63249497f41aed09f8e65add917ea6566effbc56578d6801"
-dependencies = [
- "generic-array 0.14.4",
-]
-
 [[package]]
 name = "clap"
 version = "2.33.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
 dependencies = [
- "ansi_term 0.11.0",
+ "ansi_term",
  "atty",
- "bitflags 1.2.1",
+ "bitflags",
  "strsim 0.8.0",
  "textwrap",
  "unicode-width",
  "vec_map",
 ]
 
-[[package]]
-name = "cloudabi"
-version = "0.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
-dependencies = [
- "bitflags 1.2.1",
-]
-
-[[package]]
-name = "cloudabi"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4344512281c643ae7638bbabc3af17a11307803ec8f0fcad9fae512a8bf36467"
-dependencies = [
- "bitflags 1.2.1",
-]
-
 [[package]]
 name = "cmake"
-version = "0.1.44"
+version = "0.1.45"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e56268c17a6248366d66d4a47a3381369d068cce8409bb1716ed77ea32163bb"
+checksum = "eb6210b637171dfba4cda12e579ac6dc73f5165ad56133e5d72ef3131f320855"
 dependencies = [
  "cc",
 ]
@@ -744,27 +460,18 @@ dependencies = [
  "strum_macros",
 ]
 
-[[package]]
-name = "concurrent-queue"
-version = "1.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3"
-dependencies = [
- "cache-padded",
-]
-
-[[package]]
-name = "const_fn"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce90df4c658c62f12d78f7508cf92f9173e5184a539c10bfe54a3107b3ffd0f2"
-
 [[package]]
 name = "constant_time_eq"
 version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
 
+[[package]]
+name = "convert_case"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
+
 [[package]]
 name = "cpuid-bool"
 version = "0.1.2"
@@ -780,50 +487,14 @@ dependencies = [
  "cfg-if 1.0.0",
 ]
 
-[[package]]
-name = "criterion"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70daa7ceec6cf143990669a04c7df13391d55fb27bd4079d252fca774ba244d8"
-dependencies = [
- "atty",
- "cast",
- "clap",
- "criterion-plot",
- "csv",
- "itertools",
- "lazy_static",
- "num-traits",
- "oorandom",
- "plotters",
- "rayon",
- "regex",
- "serde",
- "serde_cbor",
- "serde_derive",
- "serde_json",
- "tinytemplate",
- "walkdir",
-]
-
-[[package]]
-name = "criterion-plot"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e022feadec601fba1649cfa83586381a4ad31c6bf3a9ab7d408118b05dd9889d"
-dependencies = [
- "cast",
- "itertools",
-]
-
 [[package]]
 name = "crossbeam-channel"
-version = "0.5.0"
+version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775"
+checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"
 dependencies = [
  "cfg-if 1.0.0",
- "crossbeam-utils 0.8.0",
+ "crossbeam-utils",
 ]
 
 [[package]]
@@ -834,18 +505,17 @@ checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
 dependencies = [
  "cfg-if 1.0.0",
  "crossbeam-epoch",
- "crossbeam-utils 0.8.0",
+ "crossbeam-utils",
 ]
 
 [[package]]
 name = "crossbeam-epoch"
-version = "0.9.0"
+version = "0.9.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec0f606a85340376eef0d6d8fec399e6d4a544d648386c6645eb6d0653b27d9f"
+checksum = "2584f639eb95fea8c798496315b297cf81b9b58b6d30ab066a75455333cf4b12"
 dependencies = [
  "cfg-if 1.0.0",
- "const_fn",
- "crossbeam-utils 0.8.0",
+ "crossbeam-utils",
  "lazy_static",
  "memoffset",
  "scopeguard",
@@ -853,24 +523,12 @@ dependencies = [
 
 [[package]]
 name = "crossbeam-utils"
-version = "0.7.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
-dependencies = [
- "autocfg 1.0.1",
- "cfg-if 0.1.10",
- "lazy_static",
-]
-
-[[package]]
-name = "crossbeam-utils"
-version = "0.8.0"
+version = "0.8.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec91540d98355f690a86367e566ecad2e9e579f230230eb7c21398372be73ea5"
+checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49"
 dependencies = [
- "autocfg 1.0.1",
+ "autocfg",
  "cfg-if 1.0.0",
- "const_fn",
  "lazy_static",
 ]
 
@@ -880,7 +538,7 @@ version = "0.19.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7c36c10130df424b2f3552fcc2ddcd9b28a27b1e54b358b45874f88d1ca6888c"
 dependencies = [
- "bitflags 1.2.1",
+ "bitflags",
  "crossterm_winapi",
  "lazy_static",
  "libc",
@@ -921,45 +579,13 @@ version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "697c714f50560202b1f4e2e09cd50a421881c83e9025db75d15f276616f04f40"
 
-[[package]]
-name = "csv"
-version = "1.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "00affe7f6ab566df61b4be3ce8cf16bc2576bca0963ceb0955e45d514bf9a279"
-dependencies = [
- "bstr",
- "csv-core",
- "itoa",
- "ryu",
- "serde",
-]
-
-[[package]]
-name = "csv-core"
-version = "0.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "ctor"
-version = "0.1.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fbaabec2c953050352311293be5c6aba8e141ba19d6811862b232d6fd020484"
-dependencies = [
- "quote",
- "syn",
-]
-
 [[package]]
 name = "ctrlc"
-version = "3.1.7"
+version = "3.1.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b57a92e9749e10f25a171adcebfafe72991d45e7ec2dcb853e8f83d9dafaeb08"
+checksum = "232295399409a8b7ae41276757b5a1cc21032848d42bff2352261f958b3ca29a"
 dependencies = [
- "nix 0.18.0",
+ "nix 0.20.0",
  "winapi",
 ]
 
@@ -976,9 +602,9 @@ dependencies = [
 
 [[package]]
 name = "darling"
-version = "0.10.2"
+version = "0.12.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858"
+checksum = "5f2c43f534ea4b0b049015d00269734195e6d3f0f6635cb692251aca6f9f8b3c"
 dependencies = [
  "darling_core",
  "darling_macro",
@@ -986,23 +612,23 @@ dependencies = [
 
 [[package]]
 name = "darling_core"
-version = "0.10.2"
+version = "0.12.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b"
+checksum = "8e91455b86830a1c21799d94524df0845183fa55bafd9aa137b01c7d1065fa36"
 dependencies = [
  "fnv",
  "ident_case",
  "proc-macro2",
  "quote",
- "strsim 0.9.3",
+ "strsim 0.10.0",
  "syn",
 ]
 
 [[package]]
 name = "darling_macro"
-version = "0.10.2"
+version = "0.12.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72"
+checksum = "29b5acf0dea37a7f66f7b25d2c5e93fd46f8f6968b1a5d7a3e02e97768afc95a"
 dependencies = [
  "darling_core",
  "quote",
@@ -1011,34 +637,23 @@ dependencies = [
 
 [[package]]
 name = "derive_more"
-version = "0.99.11"
+version = "0.99.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41cb0e6161ad61ed084a36ba71fbba9e3ac5aee3606fb607fe08da6acbcf3d8c"
+checksum = "f82b1b72f1263f214c0f823371768776c4f5841b942c9883aa8e5ec584fd0ba6"
 dependencies = [
+ "convert_case",
  "proc-macro2",
  "quote",
  "syn",
 ]
 
-[[package]]
-name = "diff"
-version = "0.1.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499"
-
-[[package]]
-name = "difference"
-version = "2.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
-
 [[package]]
 name = "digest"
 version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
 dependencies = [
- "generic-array 0.12.3",
+ "generic-array 0.12.4",
 ]
 
 [[package]]
@@ -1076,17 +691,11 @@ version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
 
-[[package]]
-name = "downcast"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4bb454f0228b18c7f4c3b0ebbee346ed9c52e7443b0999cd543ff3571205701d"
-
 [[package]]
 name = "dubp"
-version = "0.51.0"
+version = "0.51.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "21dac0f098a82c2782208a2bbd64caf27daafbf439d783e8a2b6589efc9e3dae"
+checksum = "914faa8052c72c8b2f513a44398123379d70a59dfedf0aa8dc7b581ee223fbfc"
 dependencies = [
  "dubp-block",
  "dubp-common",
@@ -1098,9 +707,9 @@ dependencies = [
 
 [[package]]
 name = "dubp-block"
-version = "0.51.0"
+version = "0.51.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc7db42ae9c39478b09d08b56fe7c5acfc31317a46fe3c3ba9df3438154c1410"
+checksum = "b15cc90473a86c4987ea34211829d491dfb56f7c09ba79ac3d57d9430782d038"
 dependencies = [
  "dubp-documents",
  "dubp-documents-parser",
@@ -1113,9 +722,9 @@ dependencies = [
 
 [[package]]
 name = "dubp-common"
-version = "0.51.0"
+version = "0.51.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "328a6ae4c29ae95253a18314cd2d7f5e04bf48a8de40a473172734e485370fd9"
+checksum = "b3a5a6cc11940e0a85f492325fec45c557c5f103c92ea445427b4272c1a12395"
 dependencies = [
  "dup-crypto",
  "serde",
@@ -1126,9 +735,9 @@ dependencies = [
 
 [[package]]
 name = "dubp-documents"
-version = "0.51.0"
+version = "0.51.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05c501db59e9334ac22022baae5f51bb6e73d53a38b9f015015c770f83437da4"
+checksum = "85d43233426a5a24a5d22e98da2d8f0efab9739a58af15fa27e74a213b2d5bb9"
 dependencies = [
  "beef",
  "dubp-wallet",
@@ -1140,9 +749,9 @@ dependencies = [
 
 [[package]]
 name = "dubp-documents-parser"
-version = "0.51.0"
+version = "0.51.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12c38b138c7f5b6fbc219062548e04fce72dbf263400e50b106f39dec2b94f1d"
+checksum = "ac382364d99af3c235530f9de41a1833d18a16dff8833a7b351e8946d378de18"
 dependencies = [
  "dubp-documents",
  "json-pest-parser",
@@ -1154,9 +763,9 @@ dependencies = [
 
 [[package]]
 name = "dubp-wallet"
-version = "0.51.0"
+version = "0.51.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4bc7edb25227bbcfda2026a208022cc2ab8c43be0b7923f8281d572d253085a6"
+checksum = "47cc059e6b139def809f9d0bf776a21f5c2d59fefc20ed30c7aceedfef8de703"
 dependencies = [
  "byteorder",
  "dubp-common",
@@ -1169,8 +778,8 @@ dependencies = [
 [[package]]
 name = "dubp-wot"
 version = "0.11.0"
+source = "git+https://git.duniter.org/nodes/rust/duniter-core#f9abadd0145d848ba4df2ab545639355c7f20386"
 dependencies = [
- "bincode",
  "log",
  "rayon",
  "serde",
@@ -1179,17 +788,18 @@ dependencies = [
 [[package]]
 name = "duniter-bc-reader"
 version = "0.1.0"
+source = "git+https://git.duniter.org/nodes/rust/duniter-core#f9abadd0145d848ba4df2ab545639355c7f20386"
 dependencies = [
  "anyhow",
  "dubp",
  "duniter-dbs",
  "resiter",
- "smallvec",
 ]
 
 [[package]]
 name = "duniter-bca"
 version = "0.1.0"
+source = "git+https://git.duniter.org/nodes/rust/modules/duniter-gva#7c1f8e58872fe2931f780c9b5e6b80caa3f3683a"
 dependencies = [
  "anyhow",
  "arrayvec",
@@ -1198,14 +808,11 @@ dependencies = [
  "bincode",
  "dubp",
  "duniter-bca-types",
- "duniter-dbs",
- "duniter-global",
+ "duniter-core",
  "duniter-gva-db",
  "duniter-gva-dbs-reader",
- "duniter-mempools",
  "fast-threadpool",
  "futures",
- "mockall",
  "once_cell",
  "smallvec",
  "tokio",
@@ -1215,6 +822,7 @@ dependencies = [
 [[package]]
 name = "duniter-bca-types"
 version = "0.1.0"
+source = "git+https://git.duniter.org/nodes/rust/modules/duniter-gva#7c1f8e58872fe2931f780c9b5e6b80caa3f3683a"
 dependencies = [
  "arrayvec",
  "bincode",
@@ -1227,11 +835,26 @@ dependencies = [
 [[package]]
 name = "duniter-conf"
 version = "0.1.0"
+source = "git+https://git.duniter.org/nodes/rust/duniter-core#f9abadd0145d848ba4df2ab545639355c7f20386"
 dependencies = [
  "dubp",
  "serde",
 ]
 
+[[package]]
+name = "duniter-core"
+version = "1.8.1"
+source = "git+https://git.duniter.org/nodes/rust/duniter-core#f9abadd0145d848ba4df2ab545639355c7f20386"
+dependencies = [
+ "duniter-bc-reader",
+ "duniter-conf",
+ "duniter-dbs",
+ "duniter-dbs-write-ops",
+ "duniter-global",
+ "duniter-mempools",
+ "duniter-module",
+]
+
 [[package]]
 name = "duniter-dbex"
 version = "0.1.0"
@@ -1241,8 +864,7 @@ dependencies = [
  "comfy-table",
  "dirs",
  "dubp",
- "duniter-dbs",
- "duniter-dbs-write-ops",
+ "duniter-core",
  "duniter-gva-db",
  "duniter-gva-indexer",
  "fast-threadpool",
@@ -1259,8 +881,8 @@ dependencies = [
 [[package]]
 name = "duniter-dbs"
 version = "0.1.0"
+source = "git+https://git.duniter.org/nodes/rust/duniter-core#f9abadd0145d848ba4df2ab545639355c7f20386"
 dependencies = [
- "anyhow",
  "arrayvec",
  "bincode",
  "byteorder",
@@ -1268,25 +890,22 @@ dependencies = [
  "dubp",
  "kv_typed",
  "log",
- "mockall",
  "parking_lot",
  "paste",
  "rand 0.7.3",
  "serde",
  "serde_json",
  "smallvec",
- "tempfile",
  "thiserror",
  "uninit",
- "unwrap",
  "zerocopy",
 ]
 
 [[package]]
 name = "duniter-dbs-write-ops"
 version = "0.1.0"
+source = "git+https://git.duniter.org/nodes/rust/duniter-core#f9abadd0145d848ba4df2ab545639355c7f20386"
 dependencies = [
- "anyhow",
  "chrono",
  "dubp",
  "duniter-dbs",
@@ -1294,20 +913,18 @@ dependencies = [
  "fast-threadpool",
  "flume",
  "log",
- "maplit",
  "resiter",
- "serde_json",
 ]
 
 [[package]]
 name = "duniter-global"
 version = "1.8.1"
+source = "git+https://git.duniter.org/nodes/rust/duniter-core#f9abadd0145d848ba4df2ab545639355c7f20386"
 dependencies = [
  "async-rwlock",
  "dubp",
  "duniter-dbs",
  "flume",
- "mockall",
  "once_cell",
  "tokio",
 ]
@@ -1315,6 +932,7 @@ dependencies = [
 [[package]]
 name = "duniter-gva"
 version = "0.1.0"
+source = "git+https://git.duniter.org/nodes/rust/modules/duniter-gva#7c1f8e58872fe2931f780c9b5e6b80caa3f3683a"
 dependencies = [
  "anyhow",
  "arrayvec",
@@ -1324,39 +942,32 @@ dependencies = [
  "bytes 1.0.1",
  "dubp",
  "duniter-bca",
- "duniter-conf",
- "duniter-dbs",
- "duniter-global",
+ "duniter-core",
  "duniter-gva-db",
  "duniter-gva-dbs-reader",
  "duniter-gva-gql",
  "duniter-gva-indexer",
- "duniter-mempools",
- "duniter-module",
  "fast-threadpool",
  "flume",
  "futures",
  "http",
  "log",
- "mockall",
  "resiter",
  "serde",
- "serde_json",
  "serde_urlencoded",
  "tokio",
- "unwrap",
  "warp",
 ]
 
 [[package]]
 name = "duniter-gva-db"
 version = "0.1.0"
+source = "git+https://git.duniter.org/nodes/rust/modules/duniter-gva#7c1f8e58872fe2931f780c9b5e6b80caa3f3683a"
 dependencies = [
  "bincode",
  "chrono",
  "dubp",
- "duniter-dbs",
- "kv_typed",
+ "duniter-core",
  "parking_lot",
  "paste",
  "serde",
@@ -1368,62 +979,49 @@ dependencies = [
 [[package]]
 name = "duniter-gva-dbs-reader"
 version = "0.1.0"
+source = "git+https://git.duniter.org/nodes/rust/modules/duniter-gva#7c1f8e58872fe2931f780c9b5e6b80caa3f3683a"
 dependencies = [
  "anyhow",
  "arrayvec",
  "dubp",
  "duniter-bca-types",
- "duniter-dbs",
+ "duniter-core",
  "duniter-gva-db",
- "maplit",
- "mockall",
  "resiter",
- "smallvec",
- "unwrap",
 ]
 
 [[package]]
 name = "duniter-gva-gql"
 version = "0.1.0"
+source = "git+https://git.duniter.org/nodes/rust/modules/duniter-gva#7c1f8e58872fe2931f780c9b5e6b80caa3f3683a"
 dependencies = [
  "anyhow",
  "arrayvec",
  "async-graphql",
  "async-trait",
  "dubp",
- "duniter-bc-reader",
- "duniter-conf",
- "duniter-dbs",
- "duniter-global",
+ "duniter-core",
  "duniter-gva-db",
  "duniter-gva-dbs-reader",
- "duniter-mempools",
- "duniter-module",
  "fast-threadpool",
  "flume",
  "futures",
  "log",
- "mockall",
- "pretty_assertions",
  "resiter",
  "serde",
- "serde_json",
- "tokio",
- "unwrap",
 ]
 
 [[package]]
 name = "duniter-gva-indexer"
 version = "0.1.0"
+source = "git+https://git.duniter.org/nodes/rust/modules/duniter-gva#7c1f8e58872fe2931f780c9b5e6b80caa3f3683a"
 dependencies = [
  "anyhow",
  "dubp",
- "duniter-dbs",
+ "duniter-core",
  "duniter-gva-db",
- "maplit",
  "once_cell",
  "resiter",
- "smallvec",
 ]
 
 [[package]]
@@ -1432,12 +1030,7 @@ version = "0.1.0"
 dependencies = [
  "anyhow",
  "dubp",
- "duniter-bc-reader",
- "duniter-conf",
- "duniter-dbs",
- "duniter-dbs-write-ops",
- "duniter-mempools",
- "duniter-module",
+ "duniter-core",
  "duniter-server",
  "fast-threadpool",
  "flume",
@@ -1467,6 +1060,7 @@ dependencies = [
 [[package]]
 name = "duniter-mempools"
 version = "0.1.0"
+source = "git+https://git.duniter.org/nodes/rust/duniter-core#f9abadd0145d848ba4df2ab545639355c7f20386"
 dependencies = [
  "dubp",
  "duniter-bc-reader",
@@ -1479,6 +1073,7 @@ dependencies = [
 [[package]]
 name = "duniter-module"
 version = "0.1.0"
+source = "git+https://git.duniter.org/nodes/rust/duniter-core#f9abadd0145d848ba4df2ab545639355c7f20386"
 dependencies = [
  "anyhow",
  "async-trait",
@@ -1489,8 +1084,6 @@ dependencies = [
  "duniter-mempools",
  "fast-threadpool",
  "log",
- "paste",
- "tokio",
 ]
 
 [[package]]
@@ -1500,14 +1093,8 @@ dependencies = [
  "anyhow",
  "cfg-if 1.0.0",
  "dubp",
- "duniter-bc-reader",
- "duniter-conf",
- "duniter-dbs",
- "duniter-dbs-write-ops",
- "duniter-global",
+ "duniter-core",
  "duniter-gva",
- "duniter-mempools",
- "duniter-module",
  "fast-threadpool",
  "flume",
  "log",
@@ -1537,20 +1124,16 @@ dependencies = [
 
 [[package]]
 name = "dup-crypto"
-version = "0.51.0"
+version = "0.51.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "431ee425d40a19ac98b70b91b3afbbb3e5853397e95430694d07bb96a977a729"
+checksum = "c3b8d3e1c65e3ed89db6973e807e9c355c8f9078866402e695a16683f1e226d2"
 dependencies = [
- "aes",
- "arrayvec",
- "base64 0.13.0",
+ "base64",
  "blake3",
  "bs58 0.4.0",
  "byteorder",
  "cryptoxide",
- "ed25519-bip32",
  "getrandom 0.2.2",
- "once_cell",
  "ring",
  "serde",
  "thiserror",
@@ -1558,15 +1141,6 @@ dependencies = [
  "zeroize",
 ]
 
-[[package]]
-name = "ed25519-bip32"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8827180a2b511141fbe49141e50b31a8d542465e0fb572f81f36feea2addfe92"
-dependencies = [
- "cryptoxide",
-]
-
 [[package]]
 name = "either"
 version = "1.6.1"
@@ -1575,11 +1149,11 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
 
 [[package]]
 name = "encoding_rs"
-version = "0.8.24"
+version = "0.8.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a51b8cf747471cb9499b6d59e59b0444f4c90eba8968c4e44874e92b5b64ace2"
+checksum = "80df024fbc5ac80f87dfef0d9f5209a252f2a497f7f42944cff24d8253cac065"
 dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
 ]
 
 [[package]]
@@ -1625,22 +1199,13 @@ dependencies = [
  "num_cpus",
 ]
 
-[[package]]
-name = "fastrand"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca5faf057445ce5c9d4329e382b2ce7ca38550ef3b73a5348362d5f24e0c7fe3"
-dependencies = [
- "instant",
-]
-
 [[package]]
 name = "flate2"
-version = "1.0.18"
+version = "1.0.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da80be589a72651dcda34d8b35bcdc9b7254ad06325611074d9cc0fbb19f60ee"
+checksum = "cd3aec53de10fe96d7d8c565eb17f2c687bb5518a2ec453b5b1252964526abe0"
 dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
  "crc32fast",
  "libc",
  "miniz_oxide",
@@ -1659,24 +1224,16 @@ dependencies = [
  "thiserror",
 ]
 
-[[package]]
-name = "float-cmp"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e1267f4ac4f343772758f7b1bdcbe767c218bbab93bb432acbf5162bbf85a6c4"
-dependencies = [
- "num-traits",
-]
-
 [[package]]
 name = "flume"
-version = "0.10.0"
+version = "0.10.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e727ae0c455db3603e32c03fa722a8ccbd616b394eca686d76f9b2c9a91bb91"
+checksum = "11fce69af4d4582ea989e6adfc5c9b81fd2071ff89234e5c14675c82a85217df"
 dependencies = [
  "futures-core",
  "futures-sink",
  "nanorand",
+ "pin-project",
  "spinning_top",
 ]
 
@@ -1688,20 +1245,14 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
 
 [[package]]
 name = "form_urlencoded"
-version = "1.0.0"
+version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ece68d15c92e84fa4f19d3780f1294e5ca82a78a6d515f1efaabcc144688be00"
+checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
 dependencies = [
  "matches",
  "percent-encoding",
 ]
 
-[[package]]
-name = "fragile"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69a039c3498dc930fe810151a34ba0c1c70b02b8625035592e74432f678591f2"
-
 [[package]]
 name = "fs2"
 version = "0.4.3"
@@ -1722,17 +1273,11 @@ dependencies = [
  "users",
 ]
 
-[[package]]
-name = "fuchsia-cprng"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
-
 [[package]]
 name = "futures"
-version = "0.3.7"
+version = "0.3.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95314d38584ffbfda215621d723e0a3906f032e03ae5551e650058dac83d4797"
+checksum = "a9d5813545e459ad3ca1bff9915e9ad7f1a47dc6a91b627ce321d5863b7dd253"
 dependencies = [
  "futures-channel",
  "futures-core",
@@ -1745,9 +1290,9 @@ dependencies = [
 
 [[package]]
 name = "futures-channel"
-version = "0.3.8"
+version = "0.3.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b7109687aa4e177ef6fe84553af6280ef2778bdb7783ba44c9dc3399110fe64"
+checksum = "ce79c6a52a299137a6013061e0cf0e688fce5d7f1bc60125f520912fdb29ec25"
 dependencies = [
  "futures-core",
  "futures-sink",
@@ -1755,15 +1300,15 @@ dependencies = [
 
 [[package]]
 name = "futures-core"
-version = "0.3.8"
+version = "0.3.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "847ce131b72ffb13b6109a221da9ad97a64cbe48feb1028356b836b47b8f1748"
+checksum = "098cd1c6dda6ca01650f1a37a794245eb73181d0d4d4e955e2f3c37db7af1815"
 
 [[package]]
 name = "futures-executor"
-version = "0.3.7"
+version = "0.3.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f5f8e0c9258abaea85e78ebdda17ef9666d390e987f006be6080dfe354b708cb"
+checksum = "10f6cb7042eda00f0049b1d2080aa4b93442997ee507eb3828e8bd7577f94c9d"
 dependencies = [
  "futures-core",
  "futures-task",
@@ -1772,30 +1317,15 @@ dependencies = [
 
 [[package]]
 name = "futures-io"
-version = "0.3.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "611834ce18aaa1bd13c4b374f5d653e1027cf99b6b502584ff8c9a64413b30bb"
-
-[[package]]
-name = "futures-lite"
-version = "1.11.2"
+version = "0.3.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e6c079abfac3ab269e2927ec048dabc89d009ebfdda6b8ee86624f30c689658"
-dependencies = [
- "fastrand",
- "futures-core",
- "futures-io",
- "memchr",
- "parking",
- "pin-project-lite 0.1.11",
- "waker-fn",
-]
+checksum = "365a1a1fb30ea1c03a830fdb2158f5236833ac81fa0ad12fe35b29cddc35cb04"
 
 [[package]]
 name = "futures-macro"
-version = "0.3.8"
+version = "0.3.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77408a692f1f97bcc61dc001d752e00643408fbc922e4d634c655df50d595556"
+checksum = "668c6733a182cd7deb4f1de7ba3bf2120823835b3bcfbeacf7d2c4a773c1bb8b"
 dependencies = [
  "proc-macro-hack",
  "proc-macro2",
@@ -1811,24 +1341,21 @@ checksum = "61e9325be55c5581082cd110294fa988c1f920bc573ec370ef201e33c469a95a"
 
 [[package]]
 name = "futures-sink"
-version = "0.3.8"
+version = "0.3.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f878195a49cee50e006b02b93cf7e0a95a38ac7b776b4c4d9cc1207cd20fcb3d"
+checksum = "5c5629433c555de3d82861a7a4e3794a4c40040390907cfbfd7143a92a426c23"
 
 [[package]]
 name = "futures-task"
-version = "0.3.8"
+version = "0.3.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c554eb5bf48b2426c4771ab68c6b14468b6e76cc90996f528c3338d761a4d0d"
-dependencies = [
- "once_cell",
-]
+checksum = "ba7aa51095076f3ba6d9a1f702f74bd05ec65f555d70d2033d55ba8d69f581bc"
 
 [[package]]
 name = "futures-util"
-version = "0.3.8"
+version = "0.3.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d304cff4a7b99cfb7986f7d43fbe93d175e72e704a8860787cc95e9ffd85cbd2"
+checksum = "3c144ad54d60f23927f0a6b6d816e4271278b64f005ad65e4e35291d2de9c025"
 dependencies = [
  "futures-channel",
  "futures-core",
@@ -1837,7 +1364,7 @@ dependencies = [
  "futures-sink",
  "futures-task",
  "memchr",
- "pin-project 1.0.1",
+ "pin-project-lite",
  "pin-utils",
  "proc-macro-hack",
  "proc-macro-nested",
@@ -1853,17 +1380,11 @@ dependencies = [
  "byteorder",
 ]
 
-[[package]]
-name = "gcc"
-version = "0.3.55"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
-
 [[package]]
 name = "generic-array"
-version = "0.12.3"
+version = "0.12.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
+checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd"
 dependencies = [
  "typenum",
 ]
@@ -1889,11 +1410,11 @@ dependencies = [
 
 [[package]]
 name = "getrandom"
-version = "0.1.15"
+version = "0.1.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6"
+checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
 dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
  "libc",
  "wasi 0.9.0+wasi-snapshot-preview1",
 ]
@@ -1913,9 +1434,9 @@ dependencies = [
 
 [[package]]
 name = "gimli"
-version = "0.22.0"
+version = "0.23.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724"
+checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce"
 
 [[package]]
 name = "glob"
@@ -1923,24 +1444,11 @@ version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
 
-[[package]]
-name = "gloo-timers"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "47204a46aaff920a1ea58b11d03dec6f704287d27561724a4631e450654a891f"
-dependencies = [
- "futures-channel",
- "futures-core",
- "js-sys",
- "wasm-bindgen",
- "web-sys",
-]
-
 [[package]]
 name = "h2"
-version = "0.3.0"
+version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6b67e66362108efccd8ac053abafc8b7a8d86a37e6e48fc4f6f7485eb5e9e6a5"
+checksum = "fc018e188373e2777d0ef2467ebff62a08e66c3f5857b23c8fbec3018210dc00"
 dependencies = [
  "bytes 1.0.1",
  "fnv",
@@ -1953,23 +1461,6 @@ dependencies = [
  "tokio",
  "tokio-util",
  "tracing",
- "tracing-futures",
-]
-
-[[package]]
-name = "half"
-version = "1.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d36fab90f82edc3c747f9d438e06cf0a491055896f2a279638bb5beed6c40177"
-
-[[package]]
-name = "hashbrown"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e91b62f79061a0bc2e046024cb7ba44b08419ed238ecbd9adbd787434b9e8c25"
-dependencies = [
- "ahash",
- "autocfg 1.0.1",
 ]
 
 [[package]]
@@ -1980,17 +1471,17 @@ checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
 
 [[package]]
 name = "headers"
-version = "0.3.2"
+version = "0.3.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed18eb2459bf1a09ad2d6b1547840c3e5e62882fa09b9a6a20b1de8e3228848f"
+checksum = "f0b7591fb62902706ae8e7aaff416b1b0fa2c0fd0878b46dc13baa3712d8a855"
 dependencies = [
- "base64 0.12.3",
- "bitflags 1.2.1",
- "bytes 0.5.6",
+ "base64",
+ "bitflags",
+ "bytes 1.0.1",
  "headers-core",
  "http",
  "mime",
- "sha-1 0.8.2",
+ "sha-1 0.9.4",
  "time",
 ]
 
@@ -2005,66 +1496,61 @@ dependencies = [
 
 [[package]]
 name = "heck"
-version = "0.3.1"
+version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
+checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac"
 dependencies = [
  "unicode-segmentation",
 ]
 
 [[package]]
 name = "hermit-abi"
-version = "0.1.17"
+version = "0.1.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8"
+checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
 dependencies = [
  "libc",
 ]
 
-[[package]]
-name = "hex"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35"
-
 [[package]]
 name = "http"
-version = "0.2.1"
+version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28d569972648b2c512421b5f2a405ad6ac9666547189d0c5477a3f200f3e02f9"
+checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11"
 dependencies = [
- "bytes 0.5.6",
+ "bytes 1.0.1",
  "fnv",
  "itoa",
 ]
 
 [[package]]
 name = "http-body"
-version = "0.4.0"
+version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2861bd27ee074e5ee891e8b539837a9430012e249d7f0ca2d795650f579c1994"
+checksum = "5dfb77c123b4e2f72a2069aeae0b4b4949cc7e966df277813fc16347e7549737"
 dependencies = [
  "bytes 1.0.1",
  "http",
+ "pin-project-lite",
 ]
 
 [[package]]
 name = "httparse"
-version = "1.3.4"
+version = "1.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9"
+checksum = "4a1ce40d6fc9764887c2fdc7305c3dcc429ba11ff981c1509416afd5697e4437"
 
 [[package]]
 name = "httpdate"
-version = "0.3.2"
+version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47"
+checksum = "05842d0d43232b23ccb7060ecb0f0626922c21f30012e97b767b30afd4a5d4b9"
 
 [[package]]
 name = "hyper"
-version = "0.14.4"
+version = "0.14.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8e946c2b1349055e0b72ae281b238baf1a3ea7307c7e9f9d64673bdd9c26ac7"
+checksum = "1e5f105c494081baa3bf9e200b279e27ec1623895cd504c7dbef8d0b080fcf54"
 dependencies = [
  "bytes 1.0.1",
  "futures-channel",
@@ -2076,7 +1562,7 @@ dependencies = [
  "httparse",
  "httpdate",
  "itoa",
- "pin-project 1.0.1",
+ "pin-project",
  "socket2",
  "tokio",
  "tower-service",
@@ -2092,9 +1578,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
 
 [[package]]
 name = "idna"
-version = "0.2.0"
+version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"
+checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
 dependencies = [
  "matches",
  "unicode-bidi",
@@ -2103,12 +1589,12 @@ dependencies = [
 
 [[package]]
 name = "indexmap"
-version = "1.6.0"
+version = "1.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "55e2e4c765aa53a0424761bf9f41aa7a6ac1efa87238f59560640e27fca028f2"
+checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3"
 dependencies = [
- "autocfg 1.0.1",
- "hashbrown 0.9.1",
+ "autocfg",
+ "hashbrown",
 ]
 
 [[package]]
@@ -2122,9 +1608,9 @@ dependencies = [
 
 [[package]]
 name = "instant"
-version = "0.1.8"
+version = "0.1.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb1fc4429a33e1f80d41dc9fea4d108a88bec1de8053878898ae448a0b52f613"
+checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec"
 dependencies = [
  "cfg-if 1.0.0",
 ]
@@ -2140,24 +1626,24 @@ dependencies = [
 
 [[package]]
 name = "itoa"
-version = "0.4.6"
+version = "0.4.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
+checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
 
 [[package]]
 name = "jobserver"
-version = "0.1.21"
+version = "0.1.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c71313ebb9439f74b00d9d2dcec36440beaf57a6aa0623068441dd7cd81a7f2"
+checksum = "972f5ae5d1cb9c6ae417789196c803205313edde988685da5e3aae0827b9e7fd"
 dependencies = [
  "libc",
 ]
 
 [[package]]
 name = "js-sys"
-version = "0.3.45"
+version = "0.3.50"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca059e81d9486668f12d455a4ea6daa600bd408134cd17e3d3fb5a32d1f016f8"
+checksum = "2d99f9e3e84b8f67f846ef5b4cbbc3b1c29f6c759fcbce6f01aa0e73d932a24c"
 dependencies = [
  "wasm-bindgen",
 ]
@@ -2174,28 +1660,15 @@ dependencies = [
  "unwrap",
 ]
 
-[[package]]
-name = "kv-log-macro"
-version = "1.0.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f"
-dependencies = [
- "log",
-]
-
 [[package]]
 name = "kv_typed"
 version = "0.1.0"
+source = "git+https://git.duniter.org/nodes/rust/duniter-core#f9abadd0145d848ba4df2ab545639355c7f20386"
 dependencies = [
- "async-std",
  "byteorder",
  "cfg-if 0.1.10",
- "criterion",
  "flume",
  "leveldb_minimal",
- "lmdb-zero",
- "maybe-async",
- "mockall",
  "parking_lot",
  "paste",
  "rayon",
@@ -2203,10 +1676,8 @@ dependencies = [
  "serde_json",
  "sled",
  "smallvec",
- "tempfile",
  "thiserror",
  "uninit",
- "unwrap",
  "zerocopy",
 ]
 
@@ -2239,54 +1710,26 @@ dependencies = [
 
 [[package]]
 name = "libc"
-version = "0.2.86"
+version = "0.2.93"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c"
-
-[[package]]
-name = "liblmdb-sys"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "feed38a3a580f60bf61aaa067b0ff4123395966839adeaf67258a9e50c4d2e49"
-dependencies = [
- "gcc",
- "libc",
-]
-
-[[package]]
-name = "linked-hash-map"
-version = "0.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a"
-
-[[package]]
-name = "lmdb-zero"
-version = "0.4.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "13416eee745b087c22934f35f1f24da22da41ba2a5ce197143d168ce055cc58d"
-dependencies = [
- "bitflags 0.9.1",
- "libc",
- "liblmdb-sys",
- "supercow",
-]
+checksum = "9385f66bf6105b241aa65a61cb923ef20efc665cb9f9bb50ac2f0c4b7f378d41"
 
 [[package]]
 name = "lock_api"
-version = "0.4.1"
+version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28247cc5a5be2f05fbcd76dd0cf2c7d3b5400cb978a28042abcd4fa0b3f8261c"
+checksum = "5a3c91c24eae6777794bb1997ad98bbb87daf92890acab859f7eaa4320333176"
 dependencies = [
  "scopeguard",
 ]
 
 [[package]]
 name = "log"
-version = "0.4.11"
+version = "0.4.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
+checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
 dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
 ]
 
 [[package]]
@@ -2295,15 +1738,6 @@ version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3d0925aed5b12ed59857f438d25a910cf051dbcd4107907be1e7abf6c44ec903"
 
-[[package]]
-name = "lru"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "111b945ac72ec09eb7bc62a0fbdc3cc6e80555a7245f52a69d3921a75b53b153"
-dependencies = [
- "hashbrown 0.8.2",
-]
-
 [[package]]
 name = "maplit"
 version = "1.0.2"
@@ -2316,30 +1750,19 @@ version = "0.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
 
-[[package]]
-name = "maybe-async"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd1afac51d14f8056cd544c83239b961c464e0a98c2ca65353195df93e636a20"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
 [[package]]
 name = "memchr"
-version = "2.3.3"
+version = "2.3.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
+checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
 
 [[package]]
 name = "memoffset"
-version = "0.5.6"
+version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa"
+checksum = "f83fb6581e8ed1f85fd45c116db8405483899489e38406156c25eb743554361d"
 dependencies = [
- "autocfg 1.0.1",
+ "autocfg",
 ]
 
 [[package]]
@@ -2360,19 +1783,19 @@ dependencies = [
 
 [[package]]
 name = "miniz_oxide"
-version = "0.4.3"
+version = "0.4.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d"
+checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
 dependencies = [
  "adler",
- "autocfg 1.0.1",
+ "autocfg",
 ]
 
 [[package]]
 name = "mio"
-version = "0.7.8"
+version = "0.7.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc250d6848c90d719ea2ce34546fb5df7af1d3fd189d10bf7bad80bfcebecd95"
+checksum = "cf80d3e903b34e0bd7282b218398aec54e082c840d9baf8339e0080a0c542956"
 dependencies = [
  "libc",
  "log",
@@ -2383,41 +1806,13 @@ dependencies = [
 
 [[package]]
 name = "miow"
-version = "0.3.6"
+version = "0.3.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a33c1b55807fbed163481b5ba66db4b2fa6cde694a5027be10fb724206c5897"
+checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
 dependencies = [
- "socket2",
  "winapi",
 ]
 
-[[package]]
-name = "mockall"
-version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "18d614ad23f9bb59119b8b5670a85c7ba92c5e9adf4385c81ea00c51c8be33d5"
-dependencies = [
- "cfg-if 1.0.0",
- "downcast",
- "fragile",
- "lazy_static",
- "mockall_derive",
- "predicates",
- "predicates-tree",
-]
-
-[[package]]
-name = "mockall_derive"
-version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5dd4234635bca06fc96c7368d038061e0aae1b00a764dc817e900dc974e3deea"
-dependencies = [
- "cfg-if 1.0.0",
- "proc-macro2",
- "quote",
- "syn",
-]
-
 [[package]]
 name = "multer"
 version = "1.2.2"
@@ -2439,9 +1834,9 @@ dependencies = [
 
 [[package]]
 name = "multipart"
-version = "0.17.0"
+version = "0.17.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8209c33c951f07387a8497841122fc6f712165e3f9bda3e6be4645b58188f676"
+checksum = "d050aeedc89243f5347c3e237e3e13dc76fbe4ae3742a57b94dc14f69acf76d4"
 dependencies = [
  "buf_redux",
  "httparse",
@@ -2449,7 +1844,7 @@ dependencies = [
  "mime",
  "mime_guess",
  "quick-error",
- "rand 0.6.5",
+ "rand 0.7.3",
  "safemem",
  "tempfile",
  "twoway 0.1.8",
@@ -2457,23 +1852,13 @@ dependencies = [
 
 [[package]]
 name = "nanorand"
-version = "0.5.1"
+version = "0.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3173d7bb904c5a3a2f9167eb936916a39e97124846b8316223323aed9a34d1e7"
+checksum = "ac1378b66f7c93a1c0f8464a19bf47df8795083842e5090f4b7305973d5a22d0"
 dependencies = [
  "getrandom 0.2.2",
 ]
 
-[[package]]
-name = "nb-connect"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8123a81538e457d44b933a02faf885d3fe8408806b23fa700e8f01c6c3a98998"
-dependencies = [
- "libc",
- "winapi",
-]
-
 [[package]]
 name = "neon"
 version = "0.4.0"
@@ -2541,7 +1926,7 @@ version = "0.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "50e4785f2c3b7589a0d0c1dd60285e1188adac4006e8abd6dd578e1567027363"
 dependencies = [
- "bitflags 1.2.1",
+ "bitflags",
  "cc",
  "cfg-if 0.1.10",
  "libc",
@@ -2550,22 +1935,16 @@ dependencies = [
 
 [[package]]
 name = "nix"
-version = "0.18.0"
+version = "0.20.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "83450fe6a6142ddd95fb064b746083fc4ef1705fe81f64a64e1d4b39f54a1055"
+checksum = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a"
 dependencies = [
- "bitflags 1.2.1",
+ "bitflags",
  "cc",
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
  "libc",
 ]
 
-[[package]]
-name = "normalize-line-endings"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be"
-
 [[package]]
 name = "ntapi"
 version = "0.3.6"
@@ -2594,27 +1973,27 @@ version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95"
 dependencies = [
- "autocfg 1.0.1",
+ "autocfg",
  "num-traits",
 ]
 
 [[package]]
 name = "num-integer"
-version = "0.1.43"
+version = "0.1.44"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b"
+checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
 dependencies = [
- "autocfg 1.0.1",
+ "autocfg",
  "num-traits",
 ]
 
 [[package]]
 name = "num-iter"
-version = "0.1.41"
+version = "0.1.42"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a6e6b7c748f995c4c29c5f5ae0248536e04a5739927c74ec0fa564805094b9f"
+checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59"
 dependencies = [
- "autocfg 1.0.1",
+ "autocfg",
  "num-integer",
  "num-traits",
 ]
@@ -2625,18 +2004,18 @@ version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef"
 dependencies = [
- "autocfg 1.0.1",
+ "autocfg",
  "num-integer",
  "num-traits",
 ]
 
 [[package]]
 name = "num-traits"
-version = "0.2.12"
+version = "0.2.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
+checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
 dependencies = [
- "autocfg 1.0.1",
+ "autocfg",
 ]
 
 [[package]]
@@ -2651,21 +2030,15 @@ dependencies = [
 
 [[package]]
 name = "object"
-version = "0.21.1"
+version = "0.23.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37fd5004feb2ce328a52b0b3d01dbf4ffff72583493900ed15f22d4111c51693"
+checksum = "a9a7ab5d64814df0fe4a4b5ead45ed6c5f181ee3ff04ba344313a6c80446c5d4"
 
 [[package]]
 name = "once_cell"
-version = "1.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0"
-
-[[package]]
-name = "oorandom"
-version = "11.1.2"
+version = "1.7.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a170cebd8021a008ea92e4db85a72f80b35df514ec664b296fdcbb654eac0b2c"
+checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3"
 
 [[package]]
 name = "opaque-debug"
@@ -2679,26 +2052,11 @@ version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
 
-[[package]]
-name = "output_vt100"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9"
-dependencies = [
- "winapi",
-]
-
-[[package]]
-name = "parking"
-version = "2.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72"
-
 [[package]]
 name = "parking_lot"
-version = "0.11.0"
+version = "0.11.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4893845fa2ca272e647da5d0e46660a314ead9c2fdd9a883aabc32e481a8733"
+checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb"
 dependencies = [
  "instant",
  "lock_api",
@@ -2707,33 +2065,23 @@ dependencies = [
 
 [[package]]
 name = "parking_lot_core"
-version = "0.8.0"
+version = "0.8.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b"
+checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018"
 dependencies = [
- "cfg-if 0.1.10",
- "cloudabi 0.1.0",
+ "cfg-if 1.0.0",
  "instant",
  "libc",
- "redox_syscall 0.1.57",
+ "redox_syscall 0.2.6",
  "smallvec",
  "winapi",
 ]
 
-[[package]]
-name = "parse-zoneinfo"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41"
-dependencies = [
- "regex",
-]
-
 [[package]]
 name = "paste"
-version = "1.0.2"
+version = "1.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba7ae1a2180ed02ddfdb5ab70c70d596a26dd642e097bb6fe78b1bde8588ed97"
+checksum = "acbf547ad0c65e31259204bd90935776d1c693cec2f4ff7abb7a1bbbd40dfe58"
 
 [[package]]
 name = "percent-encoding"
@@ -2786,140 +2134,49 @@ dependencies = [
 
 [[package]]
 name = "pin-project"
-version = "0.4.27"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2ffbc8e94b38ea3d2d8ba92aea2983b503cd75d0888d75b86bb37970b5698e15"
-dependencies = [
- "pin-project-internal 0.4.27",
-]
-
-[[package]]
-name = "pin-project"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee41d838744f60d959d7074e3afb6b35c7456d0f61cad38a24e35e6553f73841"
-dependencies = [
- "pin-project-internal 1.0.1",
-]
-
-[[package]]
-name = "pin-project-internal"
-version = "0.4.27"
+version = "1.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "65ad2ae56b6abe3a1ee25f15ee605bacadb9a764edaba9c2bf4103800d4a1895"
+checksum = "c7509cc106041c40a4518d2af7a61530e1eed0e6285296a3d8c5472806ccc4a4"
 dependencies = [
- "proc-macro2",
- "quote",
- "syn",
+ "pin-project-internal",
 ]
 
 [[package]]
 name = "pin-project-internal"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81a4ffa594b66bff340084d4081df649a7dc049ac8d7fc458d8e628bfbbb2f86"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "pin-project-lite"
-version = "0.1.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c917123afa01924fc84bb20c4c03f004d9c38e5127e3c039bbf7f4b9c76a2f6b"
-
-[[package]]
-name = "pin-project-lite"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6b063f57ec186e6140e2b8b6921e5f1bd89c7356dda5b33acc5401203ca6131c"
-
-[[package]]
-name = "pin-utils"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
-
-[[package]]
-name = "plotters"
-version = "0.2.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d1685fbe7beba33de0330629da9d955ac75bd54f33d7b79f9a895590124f6bb"
-dependencies = [
- "js-sys",
- "num-traits",
- "wasm-bindgen",
- "web-sys",
-]
-
-[[package]]
-name = "polling"
-version = "2.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2a7bc6b2a29e632e45451c941832803a18cce6781db04de8a04696cdca8bde4"
-dependencies = [
- "cfg-if 0.1.10",
- "libc",
- "log",
- "wepoll-sys",
- "winapi",
-]
-
-[[package]]
-name = "ppv-lite86"
-version = "0.2.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c36fa947111f5c62a733b652544dd0016a43ce89619538a8ef92724a6f501a20"
-
-[[package]]
-name = "predicates"
-version = "1.0.5"
+version = "1.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96bfead12e90dccead362d62bb2c90a5f6fc4584963645bc7f71a735e0b0735a"
+checksum = "48c950132583b500556b1efd71d45b319029f2b71518d979fcc208e16b42426f"
 dependencies = [
- "difference",
- "float-cmp",
- "normalize-line-endings",
- "predicates-core",
- "regex",
+ "proc-macro2",
+ "quote",
+ "syn",
 ]
 
 [[package]]
-name = "predicates-core"
-version = "1.0.0"
+name = "pin-project-lite"
+version = "0.2.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06075c3a3e92559ff8929e7a280684489ea27fe44805174c3ebd9328dcb37178"
+checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905"
 
 [[package]]
-name = "predicates-tree"
-version = "1.0.0"
+name = "pin-utils"
+version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e63c4859013b38a76eca2414c64911fba30def9e3202ac461a2d22831220124"
-dependencies = [
- "predicates-core",
- "treeline",
-]
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
 
 [[package]]
-name = "pretty_assertions"
-version = "0.7.1"
+name = "ppv-lite86"
+version = "0.2.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f297542c27a7df8d45de2b0e620308ab883ad232d06c14b76ac3e144bda50184"
-dependencies = [
- "ansi_term 0.12.1",
- "ctor",
- "diff",
- "output_vt100",
-]
+checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
 
 [[package]]
 name = "proc-macro-crate"
-version = "0.1.5"
+version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785"
+checksum = "41fdbd1df62156fbc5945f4762632564d7d038153091c3fcf1067f6aef7cff92"
 dependencies = [
+ "thiserror",
  "toml",
 ]
 
@@ -2955,15 +2212,15 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
 
 [[package]]
 name = "proc-macro-nested"
-version = "0.1.6"
+version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a"
+checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.24"
+version = "1.0.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
+checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec"
 dependencies = [
  "unicode-xid",
 ]
@@ -2976,39 +2233,20 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
 
 [[package]]
 name = "quote"
-version = "1.0.7"
+version = "1.0.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
+checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
 dependencies = [
  "proc-macro2",
 ]
 
-[[package]]
-name = "rand"
-version = "0.6.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
-dependencies = [
- "autocfg 0.1.7",
- "libc",
- "rand_chacha 0.1.1",
- "rand_core 0.4.2",
- "rand_hc 0.1.0",
- "rand_isaac",
- "rand_jitter",
- "rand_os",
- "rand_pcg",
- "rand_xorshift",
- "winapi",
-]
-
 [[package]]
 name = "rand"
 version = "0.7.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
 dependencies = [
- "getrandom 0.1.15",
+ "getrandom 0.1.16",
  "libc",
  "rand_chacha 0.2.2",
  "rand_core 0.5.1",
@@ -3027,16 +2265,6 @@ dependencies = [
  "rand_hc 0.3.0",
 ]
 
-[[package]]
-name = "rand_chacha"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
-dependencies = [
- "autocfg 0.1.7",
- "rand_core 0.3.1",
-]
-
 [[package]]
 name = "rand_chacha"
 version = "0.2.2"
@@ -3057,28 +2285,13 @@ dependencies = [
  "rand_core 0.6.2",
 ]
 
-[[package]]
-name = "rand_core"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
-dependencies = [
- "rand_core 0.4.2",
-]
-
-[[package]]
-name = "rand_core"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
-
 [[package]]
 name = "rand_core"
 version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
 dependencies = [
- "getrandom 0.1.15",
+ "getrandom 0.1.16",
 ]
 
 [[package]]
@@ -3090,15 +2303,6 @@ dependencies = [
  "getrandom 0.2.2",
 ]
 
-[[package]]
-name = "rand_hc"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
-dependencies = [
- "rand_core 0.3.1",
-]
-
 [[package]]
 name = "rand_hc"
 version = "0.2.0"
@@ -3117,66 +2321,13 @@ dependencies = [
  "rand_core 0.6.2",
 ]
 
-[[package]]
-name = "rand_isaac"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
-dependencies = [
- "rand_core 0.3.1",
-]
-
-[[package]]
-name = "rand_jitter"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
-dependencies = [
- "libc",
- "rand_core 0.4.2",
- "winapi",
-]
-
-[[package]]
-name = "rand_os"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
-dependencies = [
- "cloudabi 0.0.3",
- "fuchsia-cprng",
- "libc",
- "rand_core 0.4.2",
- "rdrand",
- "winapi",
-]
-
-[[package]]
-name = "rand_pcg"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
-dependencies = [
- "autocfg 0.1.7",
- "rand_core 0.4.2",
-]
-
-[[package]]
-name = "rand_xorshift"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
-dependencies = [
- "rand_core 0.3.1",
-]
-
 [[package]]
 name = "rayon"
 version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674"
 dependencies = [
- "autocfg 1.0.1",
+ "autocfg",
  "crossbeam-deque",
  "either",
  "rayon-core",
@@ -3190,20 +2341,11 @@ checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a"
 dependencies = [
  "crossbeam-channel",
  "crossbeam-deque",
- "crossbeam-utils 0.8.0",
+ "crossbeam-utils",
  "lazy_static",
  "num_cpus",
 ]
 
-[[package]]
-name = "rdrand"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
-dependencies = [
- "rand_core 0.3.1",
-]
-
 [[package]]
 name = "read_input"
 version = "0.8.4"
@@ -3218,11 +2360,11 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
 
 [[package]]
 name = "redox_syscall"
-version = "0.2.5"
+version = "0.2.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9"
+checksum = "8270314b5ccceb518e7e578952f0b72b88222d02e8f77f5ecf7abbb673539041"
 dependencies = [
- "bitflags 1.2.1",
+ "bitflags",
 ]
 
 [[package]]
@@ -3231,37 +2373,27 @@ version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d"
 dependencies = [
- "getrandom 0.1.15",
+ "getrandom 0.1.16",
  "redox_syscall 0.1.57",
  "rust-argon2",
 ]
 
 [[package]]
 name = "regex"
-version = "1.4.1"
+version = "1.4.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8963b85b8ce3074fecffde43b4b0dded83ce2f367dc8d363afc56679f3ee820b"
+checksum = "957056ecddbeba1b26965114e191d2e8589ce74db242b6ea25fc4062427a5c19"
 dependencies = [
  "aho-corasick",
  "memchr",
  "regex-syntax",
- "thread_local",
-]
-
-[[package]]
-name = "regex-automata"
-version = "0.1.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4"
-dependencies = [
- "byteorder",
 ]
 
 [[package]]
 name = "regex-syntax"
-version = "0.6.20"
+version = "0.6.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8cab7a364d15cde1e505267766a2d3c4e22a843e1a601f0fa7564c0f82ced11c"
+checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548"
 
 [[package]]
 name = "remove_dir_all"
@@ -3287,7 +2419,7 @@ dependencies = [
  "cc",
  "libc",
  "once_cell",
- "spin 0.5.2",
+ "spin",
  "untrusted",
  "web-sys",
  "winapi",
@@ -3295,23 +2427,23 @@ dependencies = [
 
 [[package]]
 name = "run_script"
-version = "0.6.3"
+version = "0.6.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a8e8fc35067815a04a35fe2144361e1257b0f1041f0d413664f38e44d1a73cb4"
+checksum = "70f5efb6762d8cafcab5b2a5545dad239d896989b15304e7d1a03cc6cf1aa626"
 dependencies = [
  "fsio",
 ]
 
 [[package]]
 name = "rust-argon2"
-version = "0.8.2"
+version = "0.8.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9dab61250775933275e84053ac235621dfb739556d5c54a2f2e9313b7cf43a19"
+checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb"
 dependencies = [
- "base64 0.12.3",
+ "base64",
  "blake2b_simd",
  "constant_time_eq",
- "crossbeam-utils 0.7.2",
+ "crossbeam-utils",
 ]
 
 [[package]]
@@ -3362,15 +2494,6 @@ version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
 
-[[package]]
-name = "same-file"
-version = "1.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
-dependencies = [
- "winapi-util",
-]
-
 [[package]]
 name = "scoped-tls"
 version = "1.0.0"
@@ -3418,28 +2541,18 @@ dependencies = [
 
 [[package]]
 name = "serde"
-version = "1.0.124"
+version = "1.0.125"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd761ff957cb2a45fbb9ab3da6512de9de55872866160b23c25f1a841e99d29f"
+checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171"
 dependencies = [
  "serde_derive",
 ]
 
-[[package]]
-name = "serde_cbor"
-version = "0.11.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e18acfa2f90e8b735b2836ab8d538de304cbb6729a7360729ea5a895d15a622"
-dependencies = [
- "half",
- "serde",
-]
-
 [[package]]
 name = "serde_derive"
-version = "1.0.124"
+version = "1.0.125"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1800f7693e94e186f5e25a28291ae1570da908aff7d97a095dec1e56ff99069b"
+checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -3448,11 +2561,10 @@ dependencies = [
 
 [[package]]
 name = "serde_json"
-version = "1.0.59"
+version = "1.0.64"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95"
+checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
 dependencies = [
- "indexmap",
  "itoa",
  "ryu",
  "serde",
@@ -3484,22 +2596,9 @@ dependencies = [
 
 [[package]]
 name = "sha-1"
-version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "170a36ea86c864a3f16dd2687712dd6646f7019f301e57537c7f4dc9f5916770"
-dependencies = [
- "block-buffer 0.9.0",
- "cfg-if 0.1.10",
- "cpuid-bool",
- "digest 0.9.0",
- "opaque-debug 0.3.0",
-]
-
-[[package]]
-name = "sha2"
-version = "0.9.2"
+version = "0.9.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e7aab86fe2149bad8c507606bdb3f4ef5e7b2380eb92350f56122cca72a42a8"
+checksum = "dfebf75d25bd900fd1e7d11501efab59bc846dbc76196839663e6637bba9f25f"
 dependencies = [
  "block-buffer 0.9.0",
  "cfg-if 1.0.0",
@@ -3510,9 +2609,9 @@ dependencies = [
 
 [[package]]
 name = "signal-hook"
-version = "0.1.16"
+version = "0.1.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "604508c1418b99dfe1925ca9224829bb2a8a9a04dda655cc01fcad46f4ab05ed"
+checksum = "7e31d442c16f047a671b5a71e2161d6e68814012b7f5379d269ebd915fac2729"
 dependencies = [
  "libc",
  "mio",
@@ -3521,19 +2620,18 @@ dependencies = [
 
 [[package]]
 name = "signal-hook-registry"
-version = "1.2.1"
+version = "1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a3e12110bc539e657a646068aaf5eb5b63af9d0c1f7b29c97113fad80e15f035"
+checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6"
 dependencies = [
- "arc-swap",
  "libc",
 ]
 
 [[package]]
 name = "slab"
-version = "0.4.2"
+version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
+checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527"
 
 [[package]]
 name = "sled"
@@ -3543,7 +2641,7 @@ checksum = "1d0132f3e393bcb7390c60bb45769498cf4550bcb7a21d7f95c02b69f6362cdc"
 dependencies = [
  "crc32fast",
  "crossbeam-epoch",
- "crossbeam-utils 0.8.0",
+ "crossbeam-utils",
  "fs2",
  "fxhash",
  "libc",
@@ -3563,9 +2661,9 @@ dependencies = [
 
 [[package]]
 name = "snafu"
-version = "0.6.9"
+version = "0.6.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c4e6046e4691afe918fd1b603fd6e515bcda5388a1092a9edbada307d159f09"
+checksum = "eab12d3c261b2308b0d80c26fffb58d17eba81a4be97890101f416b478c79ca7"
 dependencies = [
  "doc-comment",
  "snafu-derive",
@@ -3573,9 +2671,9 @@ dependencies = [
 
 [[package]]
 name = "snafu-derive"
-version = "0.6.9"
+version = "0.6.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7073448732a89f2f3e6581989106067f403d378faeafb4a50812eb814170d3e5"
+checksum = "1508efa03c362e23817f96cde18abed596a25219a8b2c66e8db33c03543d315b"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -3584,11 +2682,10 @@ dependencies = [
 
 [[package]]
 name = "socket2"
-version = "0.3.19"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e"
+checksum = "9e3dfc207c526015c632472a77be09cf1b6e46866581aecae5cc38fb4235dea2"
 dependencies = [
- "cfg-if 1.0.0",
  "libc",
  "winapi",
 ]
@@ -3599,17 +2696,11 @@ version = "0.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
 
-[[package]]
-name = "spin"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "652ac3743312871a5fb703f0337e68ffa3cdc28c863efad0b8dc858fa10c991b"
-
 [[package]]
 name = "spinning_top"
-version = "0.2.2"
+version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e529d73e80d64b5f2631f9035113347c578a1c9c7774b83a2b880788459ab36"
+checksum = "8bd0ab6b8c375d2d963503b90d3770010d95bc3b5f98036f948dee24bf4e8879"
 dependencies = [
  "lock_api",
 ]
@@ -3628,15 +2719,15 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
 
 [[package]]
 name = "strsim"
-version = "0.9.3"
+version = "0.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
+checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
 
 [[package]]
 name = "structopt"
-version = "0.3.20"
+version = "0.3.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "126d630294ec449fae0b16f964e35bf3c74f940da9dca17ee9b905f7b3112eb8"
+checksum = "5277acd7ee46e63e5168a80734c9f6ee81b1367a7d8772a2d765df2a3705d28c"
 dependencies = [
  "clap",
  "lazy_static",
@@ -3645,9 +2736,9 @@ dependencies = [
 
 [[package]]
 name = "structopt-derive"
-version = "0.4.13"
+version = "0.4.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "65e51c492f9e23a220534971ff5afc14037289de430e3c83f9daf6a1b6ae91e8"
+checksum = "5ba9cdfda491b814720b6b06e0cac513d922fc407582032e8706e9f137976f90"
 dependencies = [
  "heck",
  "proc-macro-error",
@@ -3680,17 +2771,11 @@ version = "2.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2"
 
-[[package]]
-name = "supercow"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "171758edb47aa306a78dfa4ab9aeb5167405bd4e3dc2b64e88f6a84bbe98bd63"
-
 [[package]]
 name = "syn"
-version = "1.0.62"
+version = "1.0.70"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "123a78a3596b24fee53a6464ce52d8ecbf62241e6294c7e7fe12086cd161f512"
+checksum = "b9505f307c872bab8eb46f77ae357c8eba1fdacead58ee5a850116b1d7f82883"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -3718,16 +2803,16 @@ dependencies = [
  "cfg-if 1.0.0",
  "libc",
  "rand 0.8.3",
- "redox_syscall 0.2.5",
+ "redox_syscall 0.2.6",
  "remove_dir_all",
  "winapi",
 ]
 
 [[package]]
 name = "terminal_size"
-version = "0.1.15"
+version = "0.1.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4bd2d183bd3fac5f5fe38ddbeb4dc9aec4a39a9d7d59e7491d900302da01cbe1"
+checksum = "86ca8ced750734db02076f44132d802af0b33b09942331f4459dde8636fd2406"
 dependencies = [
  "libc",
  "winapi",
@@ -3772,15 +2857,6 @@ dependencies = [
  "syn",
 ]
 
-[[package]]
-name = "thread_local"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
-dependencies = [
- "lazy_static",
-]
-
 [[package]]
 name = "time"
 version = "0.1.44"
@@ -3793,34 +2869,33 @@ dependencies = [
 ]
 
 [[package]]
-name = "tinytemplate"
-version = "1.1.0"
+name = "tinyvec"
+version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d3dc76004a03cec1c5932bca4cdc2e39aaa798e3f82363dd94f9adf6098c12f"
+checksum = "5b5220f05bb7de7f3f53c7c065e1199b3172696fe2db9f9c4d8ad9b4ee74c342"
 dependencies = [
- "serde",
- "serde_json",
+ "tinyvec_macros",
 ]
 
 [[package]]
-name = "tinyvec"
-version = "0.3.4"
+name = "tinyvec_macros"
+version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "238ce071d267c5710f9d31451efec16c5ee22de34df17cc05e56cbc92e967117"
+checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
 
 [[package]]
 name = "tokio"
-version = "1.2.0"
+version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8190d04c665ea9e6b6a0dc45523ade572c088d2e6566244c1122671dbf4ae3a"
+checksum = "83f0c8e7c0addab50b663055baf787d0af7f413a46e6e7fb9559a4e4db7137a5"
 dependencies = [
- "autocfg 1.0.1",
+ "autocfg",
  "bytes 1.0.1",
  "libc",
  "memchr",
  "mio",
  "num_cpus",
- "pin-project-lite 0.2.0",
+ "pin-project-lite",
  "tokio-macros",
 ]
 
@@ -3837,12 +2912,12 @@ dependencies = [
 
 [[package]]
 name = "tokio-stream"
-version = "0.1.3"
+version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1981ad97df782ab506a1f43bf82c967326960d278acf3bf8279809648c3ff3ea"
+checksum = "e177a5d8c3bf36de9ebe6d58537d8879e964332f93fb3339e43f618c81361af0"
 dependencies = [
  "futures-core",
- "pin-project-lite 0.2.0",
+ "pin-project-lite",
  "tokio",
 ]
 
@@ -3854,64 +2929,52 @@ checksum = "e1a5f475f1b9d077ea1017ecbc60890fda8e54942d680ca0b1d2b47cfa2d861b"
 dependencies = [
  "futures-util",
  "log",
- "pin-project 1.0.1",
+ "pin-project",
  "tokio",
  "tungstenite",
 ]
 
 [[package]]
 name = "tokio-util"
-version = "0.6.3"
+version = "0.6.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ebb7cb2f00c5ae8df755b252306272cd1790d39728363936e01827e11f0b017b"
+checksum = "940a12c99365c31ea8dd9ba04ec1be183ffe4920102bb7122c2f515437601e8e"
 dependencies = [
  "bytes 1.0.1",
  "futures-core",
  "futures-sink",
  "log",
- "pin-project-lite 0.2.0",
+ "pin-project-lite",
  "tokio",
 ]
 
 [[package]]
 name = "toml"
-version = "0.5.7"
+version = "0.5.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75cf45bb0bef80604d001caaec0d09da99611b3c0fd39d3080468875cdb65645"
+checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
 dependencies = [
  "serde",
 ]
 
 [[package]]
 name = "tower-service"
-version = "0.3.0"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860"
+checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
 
 [[package]]
 name = "tracing"
-version = "0.1.21"
+version = "0.1.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0987850db3733619253fe60e17cb59b82d37c7e6c0236bb81e4d6b87c879f27"
+checksum = "01ebdc2bb4498ab1ab5f5b73c5803825e60199229ccba0698170e3be0e7f959f"
 dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
  "log",
- "pin-project-lite 0.1.11",
- "tracing-attributes",
+ "pin-project-lite",
  "tracing-core",
 ]
 
-[[package]]
-name = "tracing-attributes"
-version = "0.1.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "80e0ccfc3378da0cce270c946b676a376943f5cd16aeba64568e7939806f4ada"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
 [[package]]
 name = "tracing-core"
 version = "0.1.17"
@@ -3921,22 +2984,6 @@ dependencies = [
  "lazy_static",
 ]
 
-[[package]]
-name = "tracing-futures"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab7bb6f14721aa00656086e9335d363c5c8747bae02ebe32ea2c7dece5689b4c"
-dependencies = [
- "pin-project 0.4.27",
- "tracing",
-]
-
-[[package]]
-name = "treeline"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41"
-
 [[package]]
 name = "try-lock"
 version = "0.2.3"
@@ -3949,7 +2996,7 @@ version = "0.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8ada8297e8d70872fa9a551d93250a9f407beb9f37ef86494eb20012a2ff7c24"
 dependencies = [
- "base64 0.13.0",
+ "base64",
  "byteorder",
  "bytes 1.0.1",
  "http",
@@ -3957,7 +3004,7 @@ dependencies = [
  "input_buffer",
  "log",
  "rand 0.8.3",
- "sha-1 0.9.1",
+ "sha-1 0.9.4",
  "url",
  "utf-8",
 ]
@@ -3983,9 +3030,9 @@ dependencies = [
 
 [[package]]
 name = "typenum"
-version = "1.12.0"
+version = "1.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
+checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06"
 
 [[package]]
 name = "ucd-trie"
@@ -4010,27 +3057,27 @@ dependencies = [
 
 [[package]]
 name = "unicode-bidi"
-version = "0.3.4"
+version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
+checksum = "eeb8be209bb1c96b7c177c7420d26e04eccacb0eeae6b980e35fcb74678107e0"
 dependencies = [
  "matches",
 ]
 
 [[package]]
 name = "unicode-normalization"
-version = "0.1.13"
+version = "0.1.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977"
+checksum = "07fbfce1c8a97d547e8b5334978438d9d6ec8c20e38f56d4a4374d181493eaef"
 dependencies = [
  "tinyvec",
 ]
 
 [[package]]
 name = "unicode-segmentation"
-version = "1.6.0"
+version = "1.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
+checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796"
 
 [[package]]
 name = "unicode-width"
@@ -4064,10 +3111,11 @@ checksum = "7e33648dd74328e622c7be51f3b40a303c63f93e6fa5f08778b6203a4c25c20f"
 
 [[package]]
 name = "url"
-version = "2.1.1"
+version = "2.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb"
+checksum = "9ccd964113622c8e9322cfac19eb1004a07e636c545f325da085d5cdde6f1f8b"
 dependencies = [
+ "form_urlencoded",
  "idna",
  "matches",
  "percent-encoding",
@@ -4085,25 +3133,9 @@ dependencies = [
 
 [[package]]
 name = "utf-8"
-version = "0.7.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05e42f7c18b8f902290b009cde6d651262f956c98bc51bca4cd1d511c9cd85c7"
-
-[[package]]
-name = "uuid"
-version = "0.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11"
-dependencies = [
- "rand 0.7.3",
- "serde",
-]
-
-[[package]]
-name = "vec-arena"
-version = "1.0.0"
+version = "0.7.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eafc1b9b2dfc6f5529177b62cf806484db55b32dc7c9658a118e11bbeb33061d"
+checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
 
 [[package]]
 name = "vec_map"
@@ -4113,9 +3145,9 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
 
 [[package]]
 name = "version_check"
-version = "0.9.2"
+version = "0.9.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
+checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
 
 [[package]]
 name = "void"
@@ -4123,23 +3155,6 @@ version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
 
-[[package]]
-name = "waker-fn"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca"
-
-[[package]]
-name = "walkdir"
-version = "2.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d"
-dependencies = [
- "same-file",
- "winapi",
- "winapi-util",
-]
-
 [[package]]
 name = "want"
 version = "0.3.0"
@@ -4152,9 +3167,9 @@ dependencies = [
 
 [[package]]
 name = "warp"
-version = "0.3.0"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3dafd0aac2818a94a34df0df1100a7356c493d8ede4393875fd0b5c51bb6bc80"
+checksum = "332d47745e9a0c38636dbd454729b147d16bd1ed08ae67b3ab281c4506771054"
 dependencies = [
  "bytes 1.0.1",
  "futures",
@@ -4166,7 +3181,7 @@ dependencies = [
  "mime_guess",
  "multipart",
  "percent-encoding",
- "pin-project 1.0.1",
+ "pin-project",
  "scoped-tls",
  "serde",
  "serde_json",
@@ -4177,7 +3192,6 @@ dependencies = [
  "tokio-util",
  "tower-service",
  "tracing",
- "tracing-futures",
 ]
 
 [[package]]
@@ -4194,19 +3208,19 @@ checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
 
 [[package]]
 name = "wasm-bindgen"
-version = "0.2.68"
+version = "0.2.73"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ac64ead5ea5f05873d7c12b545865ca2b8d28adfc50a49b84770a3a97265d42"
+checksum = "83240549659d187488f91f33c0f8547cbfef0b2088bc470c116d1d260ef623d9"
 dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
  "wasm-bindgen-macro",
 ]
 
 [[package]]
 name = "wasm-bindgen-backend"
-version = "0.2.68"
+version = "0.2.73"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f22b422e2a757c35a73774860af8e112bff612ce6cb604224e8e47641a9e4f68"
+checksum = "ae70622411ca953215ca6d06d3ebeb1e915f0f6613e3b495122878d7ebec7dae"
 dependencies = [
  "bumpalo",
  "lazy_static",
@@ -4217,23 +3231,11 @@ dependencies = [
  "wasm-bindgen-shared",
 ]
 
-[[package]]
-name = "wasm-bindgen-futures"
-version = "0.4.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7866cab0aa01de1edf8b5d7936938a7e397ee50ce24119aef3e1eaa3b6171da"
-dependencies = [
- "cfg-if 0.1.10",
- "js-sys",
- "wasm-bindgen",
- "web-sys",
-]
-
 [[package]]
 name = "wasm-bindgen-macro"
-version = "0.2.68"
+version = "0.2.73"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6b13312a745c08c469f0b292dd2fcd6411dba5f7160f593da6ef69b64e407038"
+checksum = "3e734d91443f177bfdb41969de821e15c516931c3c3db3d318fa1b68975d0f6f"
 dependencies = [
  "quote",
  "wasm-bindgen-macro-support",
@@ -4241,9 +3243,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-macro-support"
-version = "0.2.68"
+version = "0.2.73"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f249f06ef7ee334cc3b8ff031bfc11ec99d00f34d86da7498396dc1e3b1498fe"
+checksum = "d53739ff08c8a68b0fdbcd54c372b8ab800b1449ab3c9d706503bc7dd1621b2c"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -4254,29 +3256,20 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-shared"
-version = "0.2.68"
+version = "0.2.73"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d649a3145108d7d3fbcde896a468d1bd636791823c9921135218ad89be08307"
+checksum = "d9a543ae66aa233d14bb765ed9af4a33e81b8b58d1584cf1b47ff8cd0b9e4489"
 
 [[package]]
 name = "web-sys"
-version = "0.3.45"
+version = "0.3.50"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4bf6ef87ad7ae8008e15a355ce696bed26012b7caa21605188cfd8214ab51e2d"
+checksum = "a905d57e488fec8861446d3393670fb50d27a262344013181c2cdf9fff5481be"
 dependencies = [
  "js-sys",
  "wasm-bindgen",
 ]
 
-[[package]]
-name = "wepoll-sys"
-version = "3.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fcb14dea929042224824779fbc82d9fab8d2e6d3cbc0ac404de8edf489e77ff"
-dependencies = [
- "cc",
-]
-
 [[package]]
 name = "winapi"
 version = "0.3.9"
@@ -4293,15 +3286,6 @@ version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
 
-[[package]]
-name = "winapi-util"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
-dependencies = [
- "winapi",
-]
-
 [[package]]
 name = "winapi-x86_64-pc-windows-gnu"
 version = "0.4.0"
@@ -4330,9 +3314,9 @@ dependencies = [
 
 [[package]]
 name = "zerocopy-derive"
-version = "0.2.0"
+version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d498dbd1fd7beb83c86709ae1c33ca50942889473473d287d56ce4770a18edfb"
+checksum = "dc9c39e6d503229ffa00cc2954af4a751e6bbedf2a2c18e856eb3ece93d32495"
 dependencies = [
  "proc-macro2",
  "syn",
@@ -4341,18 +3325,18 @@ dependencies = [
 
 [[package]]
 name = "zeroize"
-version = "1.2.0"
+version = "1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81a974bcdd357f0dca4d41677db03436324d45a4c9ed2d0b873a5a360ce41c36"
+checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd"
 dependencies = [
  "zeroize_derive",
 ]
 
 [[package]]
 name = "zeroize_derive"
-version = "1.0.1"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3f369ddb18862aba61aa49bf31e74d29f0f162dec753063200e1dc084345d16"
+checksum = "a2c1e130bebaeab2f23886bf9acbaca14b092408c452543c857f66399cd6dab1"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -4362,18 +3346,18 @@ dependencies = [
 
 [[package]]
 name = "zstd"
-version = "0.5.3+zstd.1.4.5"
+version = "0.5.4+zstd.1.4.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "01b32eaf771efa709e8308605bbf9319bf485dc1503179ec0469b611937c0cd8"
+checksum = "69996ebdb1ba8b1517f61387a883857818a66c8a295f487b1ffd8fd9d2c82910"
 dependencies = [
  "zstd-safe",
 ]
 
 [[package]]
 name = "zstd-safe"
-version = "2.0.5+zstd.1.4.5"
+version = "2.0.6+zstd.1.4.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1cfb642e0d27f64729a639c52db457e0ae906e7bc6f5fe8f5c453230400f1055"
+checksum = "98aa931fb69ecee256d44589d19754e61851ae4769bf963b385119b1cc37a49e"
 dependencies = [
  "libc",
  "zstd-sys",
@@ -4381,9 +3365,9 @@ dependencies = [
 
 [[package]]
 name = "zstd-sys"
-version = "1.4.17+zstd.1.4.5"
+version = "1.4.18+zstd.1.4.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b89249644df056b522696b1bb9e7c18c87e8ffa3e2f0dc3b0155875d6498f01b"
+checksum = "a1e6e8778706838f43f771d80d37787cb2fe06dafe89dd3aebaf6721b9eaec81"
 dependencies = [
  "cc",
  "glob",
diff --git a/Cargo.toml b/Cargo.toml
index aa040bba0..775733725 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -33,23 +33,8 @@ members = [
     "neon/native",
     "rust-bins/duniter-dbex",
     "rust-bins/xtask",
-    "rust-libs/dubp-wot",
-    "rust-libs/duniter-conf",
-    "rust-libs/duniter-dbs",
-    "rust-libs/duniter-bc-reader",
-    "rust-libs/duniter-dbs-write-ops",
-    "rust-libs/duniter-mempools",
-    "rust-libs/duniter-module",
     "rust-libs/duniter-server",
-    "rust-libs/duniter-global",
-    "rust-libs/modules/gva",
-    "rust-libs/modules/gva/bca",
-    "rust-libs/modules/gva/bca/types",
-    "rust-libs/modules/gva/dbs-reader",
-    "rust-libs/modules/gva/gql",
-    "rust-libs/modules/gva/indexer",
     "rust-libs/tests/duniter-integration-tests",
-    "rust-libs/tools/kv_typed"
 ]
 
 [patch.crates-io]
diff --git a/deny.toml b/deny.toml
index 0ed91ca7b..655111165 100644
--- a/deny.toml
+++ b/deny.toml
@@ -61,4 +61,3 @@ version = "0.3.1"
 
 [sources]
 unknown-registry = "deny"
-unknown-git = "deny"
diff --git a/neon/native/Cargo.toml b/neon/native/Cargo.toml
index 060c52e94..c0de6dee9 100644
--- a/neon/native/Cargo.toml
+++ b/neon/native/Cargo.toml
@@ -18,7 +18,7 @@ neon-build = "0.4.0"
 bincode = "1.2.1"
 bs58 = "0.3.0"
 dubp = { version = "0.51.0", features = ["duniter"] }
-dubp-wot = { path = "../../rust-libs/dubp-wot" }
+dubp-wot = { git = "https://git.duniter.org/nodes/rust/duniter-core" }
 duniter-server = { path = "../../rust-libs/duniter-server" }
 flate2 = "1.0.16"
 flexi_logger = { version = "=0.16.0", default-features = false, features = ["compress"] }
diff --git a/rust-bins/duniter-dbex/Cargo.toml b/rust-bins/duniter-dbex/Cargo.toml
index 3b923fee4..b018a8747 100644
--- a/rust-bins/duniter-dbex/Cargo.toml
+++ b/rust-bins/duniter-dbex/Cargo.toml
@@ -23,10 +23,9 @@ arrayvec = "0.5.1"
 comfy-table = "2.1.0"
 dirs = "3.0.1"
 dubp = { version = "0.51.0", features = ["duniter"] }
-duniter-dbs = { path = "../../rust-libs/duniter-dbs", default-features = false, features = ["explorer", "leveldb_backend", "sled_backend"] }
-duniter-dbs-write-ops = { path = "../../rust-libs/duniter-dbs-write-ops", default-features = false, features = ["explorer", "leveldb_backend", "sled_backend"] }
-duniter-gva-db = { path = "../../rust-libs/modules/gva/db", default-features = false, features = ["explorer", "leveldb_backend"] }
-duniter-gva-indexer = { path = "../../rust-libs/modules/gva/indexer" }
+duniter-core = { git = "https://git.duniter.org/nodes/rust/duniter-core", features = ["bc-writer", "explorer", "leveldb_backend"] }
+duniter-gva-db = { git = "https://git.duniter.org/nodes/rust/modules/duniter-gva", default-features = false, features = ["explorer", "leveldb_backend"] }
+duniter-gva-indexer = { git = "https://git.duniter.org/nodes/rust/modules/duniter-gva" }
 fast-threadpool = "0.2.3"
 flume = "0.10.0"
 once_cell = "1.5.2"
diff --git a/rust-bins/duniter-dbex/src/export_bc.rs b/rust-bins/duniter-dbex/src/export_bc.rs
index 007880843..a07b46651 100644
--- a/rust-bins/duniter-dbex/src/export_bc.rs
+++ b/rust-bins/duniter-dbex/src/export_bc.rs
@@ -14,7 +14,7 @@
 // along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 use crate::*;
-use duniter_dbs::{
+use duniter_core::dbs::{
     databases::bc_v1::{BcV1Db, BcV1DbReadable},
     kv_typed::prelude::Backend,
 };
diff --git a/rust-bins/duniter-dbex/src/main.rs b/rust-bins/duniter-dbex/src/main.rs
index 90cf5770c..977d8df5c 100644
--- a/rust-bins/duniter-dbex/src/main.rs
+++ b/rust-bins/duniter-dbex/src/main.rs
@@ -32,17 +32,17 @@ use self::cli::{Database, Opt, OutputFormat, SubCommand};
 use self::stringify_json_value::stringify_json_value;
 use anyhow::anyhow;
 use comfy_table::Table;
-use duniter_dbs::databases::{
+use duniter_core::dbs::databases::{
     bc_v1::{BcV1Db, BcV1DbWritable},
     bc_v2::{BcV2Db, BcV2DbWritable},
     network_v1::{NetworkV1Db, NetworkV1DbWritable},
     txs_mp_v2::{TxsMpV2Db, TxsMpV2DbWritable},
 };
-use duniter_dbs::kv_typed::prelude::*;
-use duniter_dbs::prelude::*;
-use duniter_dbs::regex::Regex;
-use duniter_dbs::serde_json::{Map, Value};
-use duniter_dbs::smallvec::{smallvec, SmallVec};
+use duniter_core::dbs::kv_typed::prelude::*;
+use duniter_core::dbs::prelude::*;
+use duniter_core::dbs::regex::Regex;
+use duniter_core::dbs::serde_json::{Map, Value};
+use duniter_core::dbs::smallvec::{smallvec, SmallVec};
 use duniter_gva_db::{GvaV1Db, GvaV1DbWritable};
 use rayon::prelude::*;
 use std::{
diff --git a/rust-bins/duniter-dbex/src/migrate.rs b/rust-bins/duniter-dbex/src/migrate.rs
index a3312ae1a..483271fa3 100644
--- a/rust-bins/duniter-dbex/src/migrate.rs
+++ b/rust-bins/duniter-dbex/src/migrate.rs
@@ -18,7 +18,7 @@ use dubp::{
     block::parser::parse_json_block_from_serde_value, block::parser::ParseJsonBlockError,
     block::prelude::DubpBlockTrait, block::DubpBlock, common::prelude::BlockNumber,
 };
-use duniter_dbs::{databases::bc_v1::BcV1DbReadable, FileBackend};
+use duniter_core::dbs::{databases::bc_v1::BcV1DbReadable, FileBackend};
 use fast_threadpool::{ThreadPool, ThreadPoolConfig};
 use std::{ops::Deref, path::PathBuf};
 
@@ -26,7 +26,7 @@ const CHUNK_SIZE: usize = 250;
 
 pub(crate) fn migrate(profile_path: PathBuf) -> anyhow::Result<()> {
     let start_time = Instant::now();
-    let (bc_db, shared_dbs) = duniter_dbs::open_dbs(Some(profile_path.as_path()))?;
+    let (bc_db, shared_dbs) = duniter_core::dbs::open_dbs(Some(profile_path.as_path()))?;
     let gva_db = duniter_gva_indexer::get_gva_db_rw(Some(profile_path.as_path()));
 
     // Clear bc_db and gva_db
@@ -118,7 +118,7 @@ fn migrate_inner(
                         Ok::<_, KvError>(())
                     })
                     .expect("gva:apply_chunk: dbs pool disconnected");
-                current = Some(duniter_dbs_write_ops::apply_block::apply_chunk(
+                current = Some(duniter_core::dbs_write_ops::apply_block::apply_chunk(
                     bc_db, current, &dbs_pool, chunk, None,
                 )?);
                 gva_handle
diff --git a/rust-libs/dubp-wot/Cargo.toml b/rust-libs/dubp-wot/Cargo.toml
deleted file mode 100644
index 5a060429e..000000000
--- a/rust-libs/dubp-wot/Cargo.toml
+++ /dev/null
@@ -1,23 +0,0 @@
-[package]
-name = "dubp-wot"
-version = "0.11.0"
-authors = ["nanocryk <nanocryk@duniter.org>", "elois <elois@duniter.org>"]
-description = "Makes Web of Trust computations for the Duniter project."
-repository = "https://git.duniter.org/nodes/typescript/duniter"
-readme = "README.md"
-keywords = ["duniter", "wot", "trust"]
-license = "AGPL-3.0"
-edition = "2018"
-
-[lib]
-path = "src/lib.rs"
-
-[dependencies]
-log = "0.4.8"
-rayon = "1.3.0"
-serde = { version = "1.0.105", features = ["derive"] }
-
-[dev-dependencies]
-bincode = "1.2.0"
-
-[features]
diff --git a/rust-libs/dubp-wot/README.md b/rust-libs/dubp-wot/README.md
deleted file mode 100644
index 2d3dcdfc4..000000000
--- a/rust-libs/dubp-wot/README.md
+++ /dev/null
@@ -1,10 +0,0 @@
-# wot
-
-`dubp-wot` is a crate making "Web of Trust" computations for
-the [Duniter] project.
-
-[Duniter]: https://duniter.org/en/
-
-## How to use it
-
-You can add `dubp-wot` as a `cargo` dependency in your Rust project.
diff --git a/rust-libs/dubp-wot/src/data/mod.rs b/rust-libs/dubp-wot/src/data/mod.rs
deleted file mode 100644
index eddc11e19..000000000
--- a/rust-libs/dubp-wot/src/data/mod.rs
+++ /dev/null
@@ -1,196 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-//! Provide data structures to manage web of trusts.
-//! `LegacyWebOfTrust` is almost a translation of the legacy C++ coden while
-//! `RustyWebOfTrust` is a brand new implementation with a more "rusty" style.
-
-pub mod rusty;
-
-use serde::de::{self, Deserialize, DeserializeOwned, Deserializer, Visitor};
-use serde::{Serialize, Serializer};
-use std::{
-    fmt::{self, Debug},
-    io::Write,
-};
-
-/// Wrapper for a node id.
-#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
-pub struct WotId(pub usize);
-
-impl Serialize for WotId {
-    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-    where
-        S: Serializer,
-    {
-        serializer.serialize_u32(self.0 as u32)
-    }
-}
-
-struct WotIdVisitor;
-
-impl<'de> Visitor<'de> for WotIdVisitor {
-    type Value = WotId;
-
-    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
-        formatter.write_str("an integer between -2^31 and 2^31")
-    }
-
-    fn visit_u8<E>(self, value: u8) -> Result<WotId, E>
-    where
-        E: de::Error,
-    {
-        Ok(WotId(value as usize))
-    }
-
-    fn visit_u32<E>(self, value: u32) -> Result<WotId, E>
-    where
-        E: de::Error,
-    {
-        Ok(WotId(value as usize))
-    }
-
-    fn visit_u64<E>(self, value: u64) -> Result<WotId, E>
-    where
-        E: de::Error,
-    {
-        use std::usize;
-        if value >= usize::MIN as u64 && value <= usize::MAX as u64 {
-            Ok(WotId(value as usize))
-        } else {
-            Err(E::custom(format!("u32 out of range: {}", value)))
-        }
-    }
-}
-
-impl<'de> Deserialize<'de> for WotId {
-    fn deserialize<D>(deserializer: D) -> Result<WotId, D::Error>
-    where
-        D: Deserializer<'de>,
-    {
-        deserializer.deserialize_u32(WotIdVisitor)
-    }
-}
-
-/// Results of a certification, with the current certification count
-/// of the destination as parameter.
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
-pub enum NewLinkResult {
-    /// Certification worked.
-    Ok(usize),
-    /// All available certifications has been used.
-    AllCertificationsUsed(usize),
-    /// Unknown source.
-    UnknownSource(),
-    /// Unknown target.
-    UnknownTarget(),
-    /// Self linking is forbidden.
-    SelfLinkingForbidden(),
-}
-
-/// Results of a certification removal, with the current certification count
-/// of the destination as parameter.
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
-pub enum RemLinkResult {
-    /// Certification has been removed.
-    Removed(usize),
-    /// Requested certification doesn't exist.
-    UnknownCert(usize),
-    /// Unknown source.
-    UnknownSource(),
-    /// Unknown target.
-    UnknownTarget(),
-}
-
-/// Results of a certification test.
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
-pub enum HasLinkResult {
-    /// Both nodes are known, here is the result.
-    Link(bool),
-    /// Unknown source.
-    UnknownSource(),
-    /// Unknown target.
-    UnknownTarget(),
-}
-
-/// Trait for a Web Of Trust.
-/// Allow to provide other implementations of the `WoT` logic instead of the legacy C++
-/// translated one.
-pub trait WebOfTrust: Clone + Debug + Default + DeserializeOwned + Send + Serialize + Sync {
-    /// Create a new Web of Trust with the maximum of links a node can issue.
-    fn new(max_links: usize) -> Self;
-
-    /// Clear Web of Trust datas
-    fn clear(&mut self);
-
-    /// Get the maximum number of links per user.
-    fn get_max_link(&self) -> usize;
-
-    /// Set the maximum number of links per user.
-    fn set_max_link(&mut self, max_link: usize);
-
-    /// Add a new node.
-    fn add_node(&mut self) -> WotId;
-
-    /// Remove the last node.
-    /// Returns `None` if the WoT was empty, otherwise new top node id.
-    fn rem_node(&mut self) -> Option<WotId>;
-
-    /// Get the size of the WoT.
-    fn size(&self) -> usize;
-
-    /// Check if given node is enabled.
-    /// Returns `None` if this node doesn't exist.
-    fn is_enabled(&self, id: WotId) -> Option<bool>;
-
-    /// Set the enabled state of given node.
-    /// Returns `Null` if this node doesn't exist, `enabled` otherwise.
-    fn set_enabled(&mut self, id: WotId, enabled: bool) -> Option<bool>;
-
-    /// Get enabled node array.
-    fn get_enabled(&self) -> Vec<WotId>;
-
-    /// Get disabled node array.
-    fn get_disabled(&self) -> Vec<WotId>;
-
-    /// Try to add a link from the source to the target.
-    fn add_link(&mut self, source: WotId, target: WotId) -> NewLinkResult;
-
-    /// Try to remove a link from the source to the target.
-    fn rem_link(&mut self, source: WotId, target: WotId) -> RemLinkResult;
-
-    /// Test if there is a link from the source to the target.
-    fn has_link(&self, source: WotId, target: WotId) -> HasLinkResult;
-
-    /// Get the list of links source for this target.
-    /// Returns `None` if this node doesn't exist.
-    fn get_links_source(&self, target: WotId) -> Option<Vec<WotId>>;
-
-    /// Get the number of issued links by a node.
-    /// Returns `None` if this node doesn't exist.
-    fn issued_count(&self, id: WotId) -> Option<usize>;
-
-    /// Test if a node is a sentry.
-    fn is_sentry(&self, node: WotId, sentry_requirement: usize) -> Option<bool>;
-
-    /// Get sentries array.
-    fn get_sentries(&self, sentry_requirement: usize) -> Vec<WotId>;
-
-    /// Get non sentries array.
-    fn get_non_sentries(&self, sentry_requirement: usize) -> Vec<WotId>;
-
-    /// Dump wot
-    fn dump<W: Write>(&self, output: &mut W) -> std::io::Result<()>;
-}
diff --git a/rust-libs/dubp-wot/src/data/rusty.rs b/rust-libs/dubp-wot/src/data/rusty.rs
deleted file mode 100644
index 398027350..000000000
--- a/rust-libs/dubp-wot/src/data/rusty.rs
+++ /dev/null
@@ -1,258 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-//! Experimental implementation of the Web of Trust in a more "rusty" style.
-
-use super::{HasLinkResult, NewLinkResult, RemLinkResult};
-use crate::WebOfTrust;
-use crate::WotId;
-use rayon::prelude::*;
-use serde::{Deserialize, Serialize};
-use std::collections::HashSet;
-
-/// A node in the `WoT` graph.
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-struct Node {
-    /// Is this node enabled ?
-    enabled: bool,
-    /// Set of links this node is the target.
-    links_source: HashSet<WotId>,
-    /// Number of links the node issued.
-    issued_count: usize,
-}
-
-impl Node {
-    /// Create a new node.
-    pub fn new() -> Node {
-        Node {
-            enabled: true,
-            links_source: HashSet::new(),
-            issued_count: 0,
-        }
-    }
-}
-
-/// A more idiomatic implementation of a Web of Trust.
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-pub struct RustyWebOfTrust {
-    /// List of nodes in the WoT.
-    nodes: Vec<Node>,
-    /// Maximum number of links a node can issue.
-    max_links: usize,
-}
-
-impl Default for RustyWebOfTrust {
-    fn default() -> RustyWebOfTrust {
-        RustyWebOfTrust {
-            nodes: Vec::new(),
-            max_links: 4_000_000_000,
-        }
-    }
-}
-
-impl WebOfTrust for RustyWebOfTrust {
-    fn new(max_links: usize) -> RustyWebOfTrust {
-        RustyWebOfTrust {
-            nodes: vec![],
-            max_links,
-        }
-    }
-
-    fn clear(&mut self) {
-        self.nodes = Vec::new();
-    }
-
-    fn get_max_link(&self) -> usize {
-        self.max_links
-    }
-
-    fn set_max_link(&mut self, max_links: usize) {
-        self.max_links = max_links;
-    }
-
-    fn add_node(&mut self) -> WotId {
-        self.nodes.push(Node::new());
-        WotId(self.nodes.len() - 1)
-    }
-
-    fn rem_node(&mut self) -> Option<WotId> {
-        if !self.nodes.is_empty() {
-            self.nodes.pop();
-            Some(WotId(self.nodes.len()))
-        } else {
-            None
-        }
-    }
-
-    fn size(&self) -> usize {
-        self.nodes.len()
-    }
-
-    fn is_enabled(&self, id: WotId) -> Option<bool> {
-        self.nodes.get(id.0).map(|n| n.enabled)
-    }
-
-    fn set_enabled(&mut self, id: WotId, enabled: bool) -> Option<bool> {
-        self.nodes
-            .get_mut(id.0)
-            .map(|n| n.enabled = enabled)
-            .map(|_| enabled)
-    }
-
-    fn get_enabled(&self) -> Vec<WotId> {
-        self.nodes
-            .par_iter()
-            .enumerate()
-            .filter(|&(_, n)| n.enabled)
-            .map(|(i, _)| WotId(i))
-            .collect()
-    }
-
-    fn get_disabled(&self) -> Vec<WotId> {
-        self.nodes
-            .par_iter()
-            .enumerate()
-            .filter(|&(_, n)| !n.enabled)
-            .map(|(i, _)| WotId(i))
-            .collect()
-    }
-
-    fn add_link(&mut self, source: WotId, target: WotId) -> NewLinkResult {
-        if source == target {
-            NewLinkResult::SelfLinkingForbidden()
-        } else if source.0 >= self.size() {
-            NewLinkResult::UnknownSource()
-        } else if target.0 >= self.size() {
-            NewLinkResult::UnknownTarget()
-        } else if self.nodes[source.0].issued_count >= self.max_links {
-            NewLinkResult::AllCertificationsUsed(self.nodes[target.0].links_source.len())
-        } else {
-            self.nodes[source.0].issued_count += 1;
-            self.nodes[target.0].links_source.insert(source);
-            NewLinkResult::Ok(self.nodes[target.0].links_source.len())
-        }
-    }
-
-    fn rem_link(&mut self, source: WotId, target: WotId) -> RemLinkResult {
-        if source.0 >= self.size() {
-            RemLinkResult::UnknownSource()
-        } else if target.0 >= self.size() {
-            RemLinkResult::UnknownTarget()
-        } else if !self.nodes[target.0].links_source.contains(&source) {
-            RemLinkResult::UnknownCert(self.nodes[target.0].links_source.len())
-        } else {
-            self.nodes[source.0].issued_count -= 1;
-            self.nodes[target.0].links_source.remove(&source);
-            RemLinkResult::Removed(self.nodes[target.0].links_source.len())
-        }
-    }
-
-    fn has_link(&self, source: WotId, target: WotId) -> HasLinkResult {
-        if source.0 >= self.size() {
-            HasLinkResult::UnknownSource()
-        } else if target.0 >= self.size() {
-            HasLinkResult::UnknownTarget()
-        } else {
-            HasLinkResult::Link(self.nodes[target.0].links_source.contains(&source))
-        }
-    }
-
-    fn get_links_source(&self, target: WotId) -> Option<Vec<WotId>> {
-        self.nodes
-            .get(target.0)
-            .map(|n| n.links_source.iter().cloned().collect())
-    }
-
-    fn issued_count(&self, id: WotId) -> Option<usize> {
-        self.nodes.get(id.0).map(|n| n.issued_count)
-    }
-
-    fn is_sentry(&self, node: WotId, sentry_requirement: usize) -> Option<bool> {
-        if node.0 >= self.size() {
-            return None;
-        }
-
-        let node = &self.nodes[node.0];
-
-        Some(
-            node.enabled
-                && node.issued_count >= sentry_requirement
-                && node.links_source.len() >= sentry_requirement,
-        )
-    }
-
-    fn get_sentries(&self, sentry_requirement: usize) -> Vec<WotId> {
-        self.nodes
-            .par_iter()
-            .enumerate()
-            .filter(|&(_, n)| {
-                n.enabled
-                    && n.issued_count >= sentry_requirement
-                    && n.links_source.len() >= sentry_requirement
-            })
-            .map(|(i, _)| WotId(i))
-            .collect()
-    }
-
-    fn get_non_sentries(&self, sentry_requirement: usize) -> Vec<WotId> {
-        self.nodes
-            .par_iter()
-            .enumerate()
-            .filter(|&(_, n)| {
-                n.enabled
-                    && (n.issued_count < sentry_requirement
-                        || n.links_source.len() < sentry_requirement)
-            })
-            .map(|(i, _)| WotId(i))
-            .collect()
-    }
-
-    fn dump<W: std::io::Write>(&self, output: &mut W) -> std::io::Result<()> {
-        writeln!(output, "max_links={}", self.max_links)?;
-        writeln!(output, "nodes_count={}", self.nodes.len())?;
-        for (node_id, node) in self.nodes.iter().enumerate() {
-            write!(output, "{:03}: ", node_id)?;
-            if !node.enabled {
-                write!(output, "disabled ")?;
-            }
-            // dump sources
-            write!(output, "[")?;
-            let mut sorted_sources = node.links_source.iter().copied().collect::<Vec<WotId>>();
-            sorted_sources.sort_unstable();
-            let mut remaining_sources = sorted_sources.len();
-            for source in &sorted_sources {
-                if remaining_sources == 1 {
-                    write!(output, "{}", source.0)?;
-                } else {
-                    write!(output, "{}, ", source.0)?;
-                    remaining_sources -= 1;
-                }
-            }
-            writeln!(output, "]")?;
-        }
-        Ok(())
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use crate::tests::generic_wot_test;
-
-    #[test]
-    fn wot_tests() {
-        generic_wot_test::<RustyWebOfTrust>();
-    }
-}
diff --git a/rust-libs/dubp-wot/src/lib.rs b/rust-libs/dubp-wot/src/lib.rs
deleted file mode 100644
index dbfc71b4b..000000000
--- a/rust-libs/dubp-wot/src/lib.rs
+++ /dev/null
@@ -1,561 +0,0 @@
-//  Copyright (C) 2017-2020  The AXIOM TEAM Association.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-//! `wot` is a crate making "Web of Trust" computations for
-//! the [Duniter] project.
-//!
-//! [Duniter]: https://duniter.org/
-//!
-//! It defines a trait representing a Web of Trust and allow to do calculations on it.
-//!
-//! It also contains an "legacy" implementation translated from the original C++ code.
-//!
-//! Web of Trust tests are translated from [duniter/wot Javascript test][js-tests].
-//!
-//! [js-tests]: https://github.com/duniter/wot/blob/master/wotcpp/webOfTrust.cpp
-
-#![deny(
-    clippy::unwrap_used,
-    missing_docs,
-    missing_debug_implementations,
-    missing_copy_implementations,
-    trivial_casts,
-    trivial_numeric_casts,
-    unsafe_code,
-    unstable_features,
-    unused_import_braces,
-    unused_qualifications
-)]
-
-pub mod data;
-pub mod operations;
-
-pub use crate::data::{WebOfTrust, WotId};
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use crate::data::*;
-    use crate::operations::centrality::*;
-    use crate::operations::distance::*;
-    use crate::operations::path::*;
-    use std::{io::Read, io::Write, path::Path};
-
-    fn read_bin_file(file_path: &Path) -> Result<Vec<u8>, std::io::Error> {
-        let mut file = std::fs::File::open(file_path)?;
-        if file.metadata()?.len() == 0 {
-            Ok(vec![])
-        } else {
-            let mut bin_datas = Vec::new();
-            file.read_to_end(&mut bin_datas)?;
-
-            Ok(bin_datas)
-        }
-    }
-
-    fn write_bin_file(file_path: &Path, datas: &[u8]) -> Result<(), std::io::Error> {
-        let mut file = std::fs::File::create(file_path)?;
-        file.write_all(datas)?;
-
-        Ok(())
-    }
-
-    /// Test translated from https://github.com/duniter/wot/blob/master/tests/test.js
-    ///
-    /// Clone and file tests are not included in this generic test and should be done in
-    /// the implementation test.
-    #[allow(clippy::cognitive_complexity)]
-    pub fn generic_wot_test<W>()
-    where
-        W: WebOfTrust + Sync,
-    {
-        let centralities_calculator = UlrikBrandesCentralityCalculator {};
-        let distance_calculator = RustyDistanceCalculator {};
-        let path_finder = RustyPathFinder {};
-        let mut wot = W::new(3);
-
-        // should have an initial size of 0
-        assert_eq!(wot.size(), 0);
-
-        // should return `None()` if testing `is_enabled()` with out-of-bounds node
-        assert_eq!(wot.is_enabled(WotId(0)), None);
-        assert_eq!(wot.is_enabled(WotId(23)), None);
-
-        // should give nomber 0 if we add a node
-        // - add a node
-        assert_eq!(wot.add_node(), WotId(0));
-        assert_eq!(wot.size(), 1);
-        assert_eq!(wot.get_disabled().len(), 0);
-
-        // delete top node (return new top node id)
-        assert_eq!(wot.rem_node(), Some(WotId(0)));
-        assert_eq!(wot.size(), 0);
-
-        // readd node
-        assert_eq!(wot.add_node(), WotId(0));
-
-        // - add another
-        assert_eq!(wot.add_node(), WotId(1));
-        assert_eq!(wot.size(), 2);
-        assert_eq!(wot.get_disabled().len(), 0);
-
-        // - add 10 nodes
-        for i in 0..10 {
-            assert_eq!(wot.add_node(), WotId(i + 2));
-        }
-
-        assert_eq!(wot.size(), 12);
-
-        // shouldn't be able to self cert
-        assert_eq!(
-            wot.add_link(WotId(0), WotId(0)),
-            NewLinkResult::SelfLinkingForbidden()
-        );
-
-        // should add certs only in the boundaries of max_cert
-        assert_eq!(wot.add_link(WotId(0), WotId(1)), NewLinkResult::Ok(1));
-        assert_eq!(wot.add_link(WotId(0), WotId(2)), NewLinkResult::Ok(1));
-        assert_eq!(wot.add_link(WotId(0), WotId(3)), NewLinkResult::Ok(1));
-        assert_eq!(
-            wot.add_link(WotId(0), WotId(4)),
-            NewLinkResult::AllCertificationsUsed(0)
-        );
-
-        assert_eq!(wot.get_max_link(), 3);
-        assert_eq!(wot.has_link(WotId(0), WotId(1)), HasLinkResult::Link(true));
-        assert_eq!(wot.has_link(WotId(0), WotId(2)), HasLinkResult::Link(true));
-        assert_eq!(wot.has_link(WotId(0), WotId(3)), HasLinkResult::Link(true));
-        assert_eq!(wot.has_link(WotId(0), WotId(4)), HasLinkResult::Link(false));
-
-        wot.set_max_link(4);
-        assert_eq!(wot.get_max_link(), 4);
-        assert_eq!(wot.has_link(WotId(0), WotId(4)), HasLinkResult::Link(false));
-        wot.add_link(WotId(0), WotId(4));
-        assert_eq!(wot.has_link(WotId(0), WotId(4)), HasLinkResult::Link(true));
-        wot.rem_link(WotId(0), WotId(1));
-        wot.rem_link(WotId(0), WotId(2));
-        wot.rem_link(WotId(0), WotId(3));
-        wot.rem_link(WotId(0), WotId(4));
-
-        // false when not linked + test out of bounds
-        assert_eq!(wot.has_link(WotId(0), WotId(6)), HasLinkResult::Link(false));
-        assert_eq!(
-            wot.has_link(WotId(23), WotId(0)),
-            HasLinkResult::UnknownSource()
-        );
-        assert_eq!(
-            wot.has_link(WotId(2), WotId(53)),
-            HasLinkResult::UnknownTarget()
-        );
-
-        // created nodes should be enabled
-        assert_eq!(wot.is_enabled(WotId(0)), Some(true));
-        assert_eq!(wot.is_enabled(WotId(1)), Some(true));
-        assert_eq!(wot.is_enabled(WotId(2)), Some(true));
-        assert_eq!(wot.is_enabled(WotId(3)), Some(true));
-        assert_eq!(wot.is_enabled(WotId(11)), Some(true));
-
-        // should be able to disable some nodes
-        assert_eq!(wot.set_enabled(WotId(0), false), Some(false));
-        assert_eq!(wot.set_enabled(WotId(1), false), Some(false));
-        assert_eq!(wot.set_enabled(WotId(2), false), Some(false));
-        assert_eq!(wot.get_disabled().len(), 3);
-        assert_eq!(wot.set_enabled(WotId(1), true), Some(true));
-
-        // node 0 and 2 should be disabled
-        assert_eq!(wot.is_enabled(WotId(0)), Some(false));
-        assert_eq!(wot.is_enabled(WotId(1)), Some(true));
-        assert_eq!(wot.is_enabled(WotId(2)), Some(false));
-        assert_eq!(wot.is_enabled(WotId(3)), Some(true));
-        // - set enabled again
-        assert_eq!(wot.set_enabled(WotId(0), true), Some(true));
-        assert_eq!(wot.set_enabled(WotId(1), true), Some(true));
-        assert_eq!(wot.set_enabled(WotId(2), true), Some(true));
-        assert_eq!(wot.set_enabled(WotId(1), true), Some(true));
-        assert_eq!(wot.get_disabled().len(), 0);
-
-        // should not exist a link from 2 to 0
-        assert_eq!(wot.has_link(WotId(2), WotId(0)), HasLinkResult::Link(false));
-
-        // should be able to add some links, cert count is returned
-        assert_eq!(wot.add_link(WotId(2), WotId(0)), NewLinkResult::Ok(1));
-        assert_eq!(wot.add_link(WotId(4), WotId(0)), NewLinkResult::Ok(2));
-        assert_eq!(wot.add_link(WotId(5), WotId(0)), NewLinkResult::Ok(3));
-
-        // should exist new links
-        /* WoT is:
-         *
-         * 2 --> 0
-         * 4 --> 0
-         * 5 --> 0
-         */
-
-        assert_eq!(wot.has_link(WotId(2), WotId(0)), HasLinkResult::Link(true));
-        assert_eq!(wot.has_link(WotId(4), WotId(0)), HasLinkResult::Link(true));
-        assert_eq!(wot.has_link(WotId(5), WotId(0)), HasLinkResult::Link(true));
-        assert_eq!(wot.has_link(WotId(2), WotId(1)), HasLinkResult::Link(false));
-
-        // should be able to remove some links
-        assert_eq!(wot.rem_link(WotId(4), WotId(0)), RemLinkResult::Removed(2));
-        /*
-         * WoT is now:
-         *
-         * 2 --> 0
-         * 5 --> 0
-         */
-
-        // should exist less links
-        assert_eq!(wot.has_link(WotId(2), WotId(0)), HasLinkResult::Link(true));
-        assert_eq!(wot.has_link(WotId(4), WotId(0)), HasLinkResult::Link(false));
-        assert_eq!(wot.has_link(WotId(5), WotId(0)), HasLinkResult::Link(true));
-        assert_eq!(wot.has_link(WotId(2), WotId(1)), HasLinkResult::Link(false));
-
-        // should successfully use distance rule
-        assert_eq!(
-            distance_calculator.is_outdistanced(
-                &wot,
-                WotDistanceParameters {
-                    node: WotId(0),
-                    sentry_requirement: 1,
-                    step_max: 1,
-                    x_percent: 1.0,
-                },
-            ),
-            Ok(false)
-        );
-        // => no because 2,4,5 have certified him
-        assert_eq!(
-            distance_calculator.is_outdistanced(
-                &wot,
-                WotDistanceParameters {
-                    node: WotId(0),
-                    sentry_requirement: 2,
-                    step_max: 1,
-                    x_percent: 1.0,
-                },
-            ),
-            Ok(false)
-        );
-        // => no because only member 2 has 2 certs, and has certified him
-        assert_eq!(
-            distance_calculator.is_outdistanced(
-                &wot,
-                WotDistanceParameters {
-                    node: WotId(0),
-                    sentry_requirement: 3,
-                    step_max: 1,
-                    x_percent: 1.0,
-                },
-            ),
-            Ok(false)
-        );
-        // => no because no member has issued 3 certifications
-
-        // - we add links from member 3
-        assert_eq!(wot.add_link(WotId(3), WotId(1)), NewLinkResult::Ok(1));
-        assert_eq!(wot.add_link(WotId(3), WotId(2)), NewLinkResult::Ok(1));
-        /*
-         * WoT is now:
-         *
-         * 2 --> 0
-         * 5 --> 0
-         * 3 --> 1
-         * 3 --> 2
-         */
-        assert_eq!(wot.size(), 12);
-        assert_eq!(wot.get_sentries(1).len(), 1);
-        assert_eq!(wot.get_sentries(1)[0], WotId(2));
-        assert_eq!(wot.get_sentries(2).len(), 0);
-        assert_eq!(wot.get_sentries(3).len(), 0);
-        assert_eq!(wot.get_non_sentries(1).len(), 11); // 12 - 1
-        assert_eq!(wot.get_non_sentries(2).len(), 12); // 12 - 0
-        assert_eq!(wot.get_non_sentries(3).len(), 12); // 12 - 0
-        assert_eq!(path_finder.find_paths(&wot, WotId(3), WotId(0), 1).len(), 0); // KO
-        assert_eq!(path_finder.find_paths(&wot, WotId(3), WotId(0), 2).len(), 1); // It exists 3 -> 2 -> 0
-        assert!(path_finder
-            .find_paths(&wot, WotId(3), WotId(0), 2)
-            .contains(&vec![WotId(3), WotId(2), WotId(0)]));
-
-        assert_eq!(
-            distance_calculator.is_outdistanced(
-                &wot,
-                WotDistanceParameters {
-                    node: WotId(0),
-                    sentry_requirement: 1,
-                    step_max: 1,
-                    x_percent: 1.0,
-                },
-            ),
-            Ok(false)
-        ); // OK : 2 -> 0
-        assert_eq!(
-            distance_calculator.is_outdistanced(
-                &wot,
-                WotDistanceParameters {
-                    node: WotId(0),
-                    sentry_requirement: 2,
-                    step_max: 1,
-                    x_percent: 1.0,
-                },
-            ),
-            Ok(false)
-        ); // OK : 2 -> 0
-        assert_eq!(
-            distance_calculator.is_outdistanced(
-                &wot,
-                WotDistanceParameters {
-                    node: WotId(0),
-                    sentry_requirement: 3,
-                    step_max: 1,
-                    x_percent: 1.0,
-                },
-            ),
-            Ok(false)
-        ); // OK : no stry \w 3 lnk
-        assert_eq!(
-            distance_calculator.is_outdistanced(
-                &wot,
-                WotDistanceParameters {
-                    node: WotId(0),
-                    sentry_requirement: 2,
-                    step_max: 2,
-                    x_percent: 1.0,
-                },
-            ),
-            Ok(false)
-        ); // OK : 2 -> 0
-
-        wot.add_link(WotId(1), WotId(3));
-        wot.add_link(WotId(2), WotId(3));
-
-        assert_eq!(wot.size(), 12);
-        assert_eq!(wot.get_sentries(1).len(), 3);
-        assert_eq!(wot.get_sentries(1)[0], WotId(1));
-        assert_eq!(wot.get_sentries(1)[1], WotId(2));
-        assert_eq!(wot.get_sentries(1)[2], WotId(3));
-
-        assert_eq!(wot.get_sentries(2).len(), 1);
-        assert_eq!(wot.get_sentries(2)[0], WotId(3));
-        assert_eq!(wot.get_sentries(3).len(), 0);
-        assert_eq!(wot.get_non_sentries(1).len(), 9); // 12 - 3
-        assert_eq!(wot.get_non_sentries(2).len(), 11); // 12 - 1
-        assert_eq!(wot.get_non_sentries(3).len(), 12); // 12 - 0
-        assert_eq!(path_finder.find_paths(&wot, WotId(3), WotId(0), 1).len(), 0); // KO
-        assert_eq!(path_finder.find_paths(&wot, WotId(3), WotId(0), 2).len(), 1); // It exists 3 -> 2 -> 0
-        assert!(path_finder
-            .find_paths(&wot, WotId(3), WotId(0), 2)
-            .contains(&vec![WotId(3), WotId(2), WotId(0)]));
-
-        assert_eq!(
-            distance_calculator.is_outdistanced(
-                &wot,
-                WotDistanceParameters {
-                    node: WotId(0),
-                    sentry_requirement: 1,
-                    step_max: 1,
-                    x_percent: 1.0,
-                },
-            ),
-            Ok(true)
-        ); // KO : No path 3 -> 0
-           /*assert_eq!(
-               distance_calculator.is_outdistanced(
-                   &wot,
-                   WotDistanceParameters {
-                       node: WotId(0),
-                       sentry_requirement: 2,
-                       step_max: 1,
-                       x_percent: 1.0,
-                   },
-               ),
-               Some(true)
-           );*/ // KO : No path 3 -> 0
-        assert_eq!(
-            distance_calculator.is_outdistanced(
-                &wot,
-                WotDistanceParameters {
-                    node: WotId(0),
-                    sentry_requirement: 3,
-                    step_max: 1,
-                    x_percent: 1.0,
-                },
-            ),
-            Ok(false)
-        ); // OK : no stry \w 3 lnk
-        assert_eq!(
-            distance_calculator.is_outdistanced(
-                &wot,
-                WotDistanceParameters {
-                    node: WotId(0),
-                    sentry_requirement: 2,
-                    step_max: 2,
-                    x_percent: 1.0,
-                },
-            ),
-            Ok(false)
-        ); // OK : 3 -> 2 -> 0
-
-        // should have 12 nodes
-        assert_eq!(wot.size(), 12);
-
-        // delete top node (return new top node id)
-        assert_eq!(wot.rem_node(), Some(WotId(11)));
-
-        // should have 11 nodes
-        assert_eq!(wot.size(), 11);
-
-        // should work with member 3 disabled
-        // - with member 3 disabled (non-member)
-        assert_eq!(wot.set_enabled(WotId(3), false), Some(false));
-        assert_eq!(wot.get_disabled().len(), 1);
-        assert_eq!(
-            distance_calculator.is_outdistanced(
-                &wot,
-                WotDistanceParameters {
-                    node: WotId(0),
-                    sentry_requirement: 2,
-                    step_max: 1,
-                    x_percent: 1.0,
-                },
-            ),
-            Ok(false)
-        ); // OK : Disabled
-
-        // Write wot in file
-        write_bin_file(
-            Path::new("test.wot"),
-            &bincode::serialize(&wot).expect("fail to serialize wot"),
-        )
-        .expect("fail to write wot file");
-
-        let wot2_bin = read_bin_file(Path::new("test.wot")).expect("fail to read wot file");
-        let wot2: W = bincode::deserialize(&wot2_bin).expect("fail to deserialize wot");
-
-        // Read wot from file
-        {
-            assert_eq!(wot.size(), wot2.size());
-            assert_eq!(
-                wot.get_non_sentries(1).len(),
-                wot2.get_non_sentries(1).len()
-            );
-            assert_eq!(wot.get_disabled().len(), wot2.get_disabled().len());
-            assert_eq!(wot2.get_disabled().len(), 1);
-            assert_eq!(wot2.is_enabled(WotId(3)), Some(false));
-            assert_eq!(
-                distance_calculator.is_outdistanced(
-                    &wot2,
-                    WotDistanceParameters {
-                        node: WotId(0),
-                        sentry_requirement: 2,
-                        step_max: 1,
-                        x_percent: 1.0,
-                    },
-                ),
-                Ok(false)
-            );
-        }
-
-        // Dump wot
-        let mut dump_wot2_chars = Vec::new();
-        wot2.dump(&mut dump_wot2_chars).expect("fail to dump wot2");
-        let dump_wot2_str = String::from_utf8(dump_wot2_chars).expect("invalid utf8 chars");
-        assert_eq!(
-            dump_wot2_str,
-            "max_links=4
-nodes_count=11
-000: [2, 5]
-001: [3]
-002: [3]
-003: disabled [1, 2]
-004: []
-005: []
-006: []
-007: []
-008: []
-009: []
-010: []
-"
-        );
-
-        // Read g1_genesis wot
-        let wot3_bin = read_bin_file(Path::new("tests/g1_genesis.bin"))
-            .expect("fail to read g1_genesis wot file");
-        let wot3: W = bincode::deserialize(&wot3_bin).expect("fail to deserialize g1_genesis wot");
-
-        // Check g1_genesis wot members_count
-        let members_count = wot3.get_enabled().len() as u64;
-        assert_eq!(members_count, 59);
-
-        // Test compute_distance in g1_genesis wot
-        assert_eq!(
-            distance_calculator.compute_distance(
-                &wot3,
-                WotDistanceParameters {
-                    node: WotId(37),
-                    sentry_requirement: 3,
-                    step_max: 5,
-                    x_percent: 0.8,
-                },
-            ),
-            Ok(WotDistance {
-                sentries: 48,
-                success: 48,
-                success_at_border: 3,
-                reached: 51,
-                reached_at_border: 3,
-                outdistanced: false,
-            },)
-        );
-
-        // Test betweenness centralities computation in g1_genesis wot
-        let centralities = centralities_calculator.betweenness_centralities(&wot3);
-        assert_eq!(centralities.len(), 59);
-        assert_eq!(
-            centralities,
-            vec![
-                148, 30, 184, 11, 60, 51, 40, 115, 24, 140, 47, 69, 16, 34, 94, 126, 151, 0, 34,
-                133, 20, 103, 38, 144, 73, 523, 124, 23, 47, 17, 9, 64, 77, 281, 6, 105, 54, 0,
-                111, 21, 6, 2, 0, 1, 47, 59, 28, 236, 0, 0, 0, 0, 60, 6, 0, 1, 8, 33, 169,
-            ]
-        );
-
-        // Test stress centralities computation in g1_genesis wot
-        let stress_centralities = centralities_calculator.stress_centralities(&wot3);
-        assert_eq!(stress_centralities.len(), 59);
-        assert_eq!(
-            stress_centralities,
-            vec![
-                848, 240, 955, 80, 416, 203, 290, 645, 166, 908, 313, 231, 101, 202, 487, 769, 984,
-                0, 154, 534, 105, 697, 260, 700, 496, 1726, 711, 160, 217, 192, 89, 430, 636, 1276,
-                41, 420, 310, 0, 357, 125, 50, 15, 0, 12, 275, 170, 215, 1199, 0, 0, 0, 0, 201, 31,
-                0, 9, 55, 216, 865,
-            ]
-        );
-
-        // Test distance stress centralities computation in g1_genesis wot
-        let distance_stress_centralities =
-            centralities_calculator.distance_stress_centralities(&wot3, 5);
-        assert_eq!(distance_stress_centralities.len(), 59);
-        assert_eq!(
-            distance_stress_centralities,
-            vec![
-                848, 240, 955, 80, 416, 203, 290, 645, 166, 908, 313, 231, 101, 202, 487, 769, 984,
-                0, 154, 534, 105, 697, 260, 700, 496, 1726, 711, 160, 217, 192, 89, 430, 636, 1276,
-                41, 420, 310, 0, 357, 125, 50, 15, 0, 12, 275, 170, 215, 1199, 0, 0, 0, 0, 201, 31,
-                0, 9, 55, 216, 865,
-            ]
-        );
-    }
-}
diff --git a/rust-libs/dubp-wot/src/operations/centrality.rs b/rust-libs/dubp-wot/src/operations/centrality.rs
deleted file mode 100644
index 933e43621..000000000
--- a/rust-libs/dubp-wot/src/operations/centrality.rs
+++ /dev/null
@@ -1,192 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-//! Provide a trait and implementations to find paths between nodes.
-
-use crate::data::WebOfTrust;
-use crate::data::WotId;
-use std::collections::{HashMap, VecDeque};
-
-/// Find paths between 2 nodes of a `WebOfTrust`.
-pub trait CentralitiesCalculator<T: WebOfTrust> {
-    /// Compute betweenness centrality of all members.
-    fn betweenness_centralities(&self, wot: &T) -> Vec<u64>;
-    /// Compute stress centrality of all members.
-    fn stress_centralities(&self, wot: &T) -> Vec<u64>;
-    /// Compute distance stress centrality of all members.
-    fn distance_stress_centralities(&self, wot: &T, step_max: usize) -> Vec<u64>;
-}
-
-/// An implementation based on "Ulrik brandes" algo.
-#[derive(Debug, Clone, Copy)]
-pub struct UlrikBrandesCentralityCalculator;
-
-impl<T: WebOfTrust> CentralitiesCalculator<T> for UlrikBrandesCentralityCalculator {
-    fn betweenness_centralities(&self, wot: &T) -> Vec<u64> {
-        let wot_size = wot.size();
-        let mut centralities = vec![0.0; wot_size];
-        let enabled_nodes = wot.get_enabled();
-
-        // The source of any path belongs to enabled_nodes
-        for s in enabled_nodes.clone() {
-            let mut stack: Vec<WotId> = Vec::with_capacity(wot_size);
-            let mut paths: HashMap<WotId, Vec<WotId>> = HashMap::with_capacity(wot_size);
-            let mut sigma = vec![0.0; wot_size];
-            let mut d: Vec<isize> = vec![-1; wot_size];
-            let mut q: VecDeque<WotId> = VecDeque::with_capacity(wot_size);
-
-            sigma[s.0] = 1.0;
-            d[s.0] = 0;
-            q.push_back(s);
-            while let Some(v) = q.pop_front() {
-                stack.push(v);
-                for w in wot.get_links_source(v).expect("v don't have any source !") {
-                    // w found for the first time ?
-                    if d[w.0] < 0 {
-                        q.push_back(w);
-                        d[w.0] = d[v.0] + 1;
-                    }
-                    // Shortest path to w via v
-                    if d[w.0] == d[v.0] + 1 {
-                        sigma[w.0] += sigma[v.0];
-                        paths.entry(w).or_insert_with(Vec::new).push(v);
-                    }
-                }
-            }
-            let mut delta = vec![0.0; wot_size];
-            // stack returns vertices in order of non-increasing distance from s
-            while let Some(w) = stack.pop() {
-                if paths.contains_key(&w) {
-                    for v in paths.get(&w).expect("Not found w in p !") {
-                        if enabled_nodes.contains(&w) {
-                            delta[v.0] += (sigma[v.0] / sigma[w.0]) * (1.0 + delta[w.0]);
-                        } else {
-                            // If w not in enabled_nodes, no path can end at w
-                            delta[v.0] += (sigma[v.0] / sigma[w.0]) * delta[w.0];
-                        }
-                    }
-                }
-                if w != s {
-                    centralities[w.0] += delta[w.0];
-                }
-            }
-        }
-        centralities.into_iter().map(|c| c as u64).collect()
-    }
-    fn stress_centralities(&self, wot: &T) -> Vec<u64> {
-        let wot_size = wot.size();
-        let mut centralities = vec![0.0; wot_size];
-        let enabled_nodes = wot.get_enabled();
-
-        // The source of any path belongs to enabled_nodes
-        for s in enabled_nodes.clone() {
-            let mut stack: Vec<WotId> = Vec::with_capacity(wot_size);
-            let mut paths: HashMap<WotId, Vec<WotId>> = HashMap::with_capacity(wot_size);
-            let mut sigma = vec![0.0; wot_size];
-            let mut d: Vec<isize> = vec![-1; wot_size];
-            let mut q: VecDeque<WotId> = VecDeque::with_capacity(wot_size);
-
-            sigma[s.0] = 1.0;
-            d[s.0] = 0;
-            q.push_back(s);
-            while let Some(v) = q.pop_front() {
-                stack.push(v);
-                for w in wot.get_links_source(v).expect("v don't have any source !") {
-                    // w found for the first time ?
-                    if d[w.0] < 0 {
-                        q.push_back(w);
-                        d[w.0] = d[v.0] + 1;
-                    }
-                    // Shortest path to w via v
-                    if d[w.0] == d[v.0] + 1 {
-                        sigma[w.0] += sigma[v.0];
-                        paths.entry(w).or_insert_with(Vec::new).push(v);
-                    }
-                }
-            }
-            let mut delta = vec![0.0; wot_size];
-            // stack returns vertices in order of non-increasing distance from s
-            while let Some(w) = stack.pop() {
-                if paths.contains_key(&w) {
-                    for v in paths.get(&w).expect("Not found w in p !") {
-                        if enabled_nodes.contains(&w) {
-                            delta[v.0] += sigma[v.0] * (1.0 + (delta[w.0] / sigma[w.0]));
-                        } else {
-                            // If w not in enabled_nodes, no path can end at w
-                            delta[v.0] += sigma[v.0] * (delta[w.0] / sigma[w.0]);
-                        }
-                    }
-                }
-                if w != s {
-                    centralities[w.0] += delta[w.0];
-                }
-            }
-        }
-        centralities.into_iter().map(|c| c as u64).collect()
-    }
-    fn distance_stress_centralities(&self, wot: &T, step_max: usize) -> Vec<u64> {
-        let wot_size = wot.size();
-        let mut centralities = vec![0.0; wot_size];
-        let enabled_nodes = wot.get_enabled();
-
-        // The source of any path belongs to enabled_nodes
-        for s in enabled_nodes.clone() {
-            let mut stack: Vec<WotId> = Vec::with_capacity(wot_size);
-            let mut paths: HashMap<WotId, Vec<WotId>> = HashMap::with_capacity(wot_size);
-            let mut sigma = vec![0.0; wot_size];
-            let mut d: Vec<isize> = vec![-1; wot_size];
-            let mut q: VecDeque<WotId> = VecDeque::with_capacity(wot_size);
-
-            sigma[s.0] = 1.0;
-            d[s.0] = 0;
-            q.push_back(s);
-            while let Some(v) = q.pop_front() {
-                stack.push(v);
-                if d[v.0] < step_max as isize {
-                    for w in wot.get_links_source(v).expect("v don't have any source !") {
-                        // w found for the first time ?
-                        if d[w.0] < 0 {
-                            q.push_back(w);
-                            d[w.0] = d[v.0] + 1;
-                        }
-                        // Shortest path to w via v
-                        if d[w.0] == d[v.0] + 1 {
-                            sigma[w.0] += sigma[v.0];
-                            paths.entry(w).or_insert_with(Vec::new).push(v);
-                        }
-                    }
-                }
-            }
-            let mut delta = vec![0.0; wot_size];
-            // stack returns vertices in order of non-increasing distance from s
-            while let Some(w) = stack.pop() {
-                if paths.contains_key(&w) {
-                    for v in paths.get(&w).expect("Not found w in p !") {
-                        if enabled_nodes.contains(&w) {
-                            delta[v.0] += sigma[v.0] * (1.0 + (delta[w.0] / sigma[w.0]));
-                        } else {
-                            // If w not in enabled_nodes, no path can end at w
-                            delta[v.0] += sigma[v.0] * (delta[w.0] / sigma[w.0]);
-                        }
-                    }
-                }
-                if w != s {
-                    centralities[w.0] += delta[w.0];
-                }
-            }
-        }
-        centralities.into_iter().map(|c| c as u64).collect()
-    }
-}
diff --git a/rust-libs/dubp-wot/src/operations/density.rs b/rust-libs/dubp-wot/src/operations/density.rs
deleted file mode 100644
index 76ae9a0f2..000000000
--- a/rust-libs/dubp-wot/src/operations/density.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-//! Provide function to compute average density.
-
-use crate::data::WebOfTrust;
-
-/// Compute average density
-pub fn calculate_average_density<T: WebOfTrust>(wot: &T) -> usize {
-    let enabled_members = wot.get_enabled();
-    let enabled_members_count = enabled_members.len();
-    let mut count_actives_links: usize = 0;
-    for member in &enabled_members {
-        count_actives_links += wot
-            .issued_count(*member)
-            .unwrap_or_else(|| panic!("Fail to get issued_count of wot_id {}", (*member).0));
-    }
-    ((count_actives_links as f32 / enabled_members_count as f32) * 1_000.0) as usize
-}
diff --git a/rust-libs/dubp-wot/src/operations/distance.rs b/rust-libs/dubp-wot/src/operations/distance.rs
deleted file mode 100644
index da6362e77..000000000
--- a/rust-libs/dubp-wot/src/operations/distance.rs
+++ /dev/null
@@ -1,211 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-//! Provide a trait and implementations to compute distances.
-
-use crate::data::WebOfTrust;
-use crate::data::WotId;
-use rayon::prelude::*;
-use std::collections::HashSet;
-
-/// Paramters for `WoT` distance calculations
-#[derive(Debug, Copy, Clone, PartialEq)]
-pub struct WotDistanceParameters {
-    /// Node from where distances are calculated.
-    pub node: WotId,
-    /// Links count received AND issued to be a sentry.
-    pub sentry_requirement: u32,
-    /// Currency parameter.
-    pub step_max: u32,
-    /// Currency parameter.
-    pub x_percent: f64,
-}
-
-/// Results of `WebOfTrust::compute_distance`.
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
-pub struct WotDistance {
-    /// Sentries count
-    pub sentries: u32,
-    /// Success count
-    pub success: u32,
-    /// Succes at border count
-    pub success_at_border: u32,
-    /// Reached count
-    pub reached: u32,
-    /// Reached at border count
-    pub reached_at_border: u32,
-    /// Is the node outdistanced ?
-    pub outdistanced: bool,
-}
-
-#[derive(Clone, Copy, Debug, Eq, PartialEq)]
-/// Error occured when computing distance
-pub enum DistanceError {
-    /// Node don't exist
-    NodeDontExist(WotId),
-}
-
-/// Compute distance between nodes of a `WebOfTrust`.
-pub trait DistanceCalculator<T: WebOfTrust> {
-    /// Compute distance between a node and the network.
-    /// Returns `None` if this node doesn't exist.
-    fn compute_distance(
-        &self,
-        wot: &T,
-        params: WotDistanceParameters,
-    ) -> Result<WotDistance, DistanceError>;
-
-    /// Compute distances of all members
-    fn compute_distances(
-        &self,
-        wot: &T,
-        sentry_requirement: u32,
-        step_max: u32,
-        x_percent: f64,
-    ) -> Result<(usize, Vec<usize>, usize, Vec<usize>), DistanceError>;
-
-    /// Test if a node is outdistanced in the network.
-    /// Returns `Node` if this node doesn't exist.
-    fn is_outdistanced(
-        &self,
-        wot: &T,
-        params: WotDistanceParameters,
-    ) -> Result<bool, DistanceError>;
-}
-
-/// Calculate distances between 2 members in a `WebOfTrust`.
-#[derive(Debug, Clone, Copy)]
-pub struct RustyDistanceCalculator;
-
-impl<T: WebOfTrust + Sync> DistanceCalculator<T> for RustyDistanceCalculator {
-    fn compute_distance(
-        &self,
-        wot: &T,
-        params: WotDistanceParameters,
-    ) -> Result<WotDistance, DistanceError> {
-        let WotDistanceParameters {
-            node,
-            sentry_requirement,
-            step_max,
-            x_percent,
-        } = params;
-
-        if node.0 >= wot.size() {
-            return Err(DistanceError::NodeDontExist(node));
-        }
-
-        let mut area = HashSet::new();
-        area.insert(node);
-        let mut border = HashSet::new();
-        border.insert(node);
-
-        for _ in 0..step_max {
-            border = border
-                .par_iter()
-                .map(|&id| {
-                    if let Some(links_source) = wot.get_links_source(id) {
-                        Ok(links_source
-                            .iter()
-                            .filter(|source| !area.contains(source))
-                            .cloned()
-                            .collect::<HashSet<_>>())
-                    } else {
-                        Err(DistanceError::NodeDontExist(id))
-                    }
-                })
-                .try_reduce(HashSet::new, |mut acc, sources| {
-                    for source in sources {
-                        acc.insert(source);
-                    }
-                    Ok(acc)
-                })?;
-            area.extend(border.iter());
-        }
-
-        let sentries: Vec<_> = wot.get_sentries(sentry_requirement as usize);
-        let mut success = area.iter().filter(|n| sentries.contains(n)).count() as u32;
-        let success_at_border = border.iter().filter(|n| sentries.contains(n)).count() as u32;
-        let mut sentries = sentries.len() as u32;
-        if wot
-            .is_sentry(node, sentry_requirement as usize)
-            .ok_or(DistanceError::NodeDontExist(node))?
-        {
-            sentries -= 1;
-            success -= 1;
-        }
-
-        Ok(WotDistance {
-            sentries,
-            reached: area.len() as u32 - 1,
-            reached_at_border: border.len() as u32,
-            success,
-            success_at_border,
-            outdistanced: f64::from(success) < ((x_percent * f64::from(sentries)).trunc() - 1.0),
-        })
-    }
-
-    fn is_outdistanced(
-        &self,
-        wot: &T,
-        params: WotDistanceParameters,
-    ) -> Result<bool, DistanceError> {
-        Self::compute_distance(&self, wot, params).map(|result| result.outdistanced)
-    }
-
-    fn compute_distances(
-        &self,
-        wot: &T,
-        sentry_requirement: u32,
-        step_max: u32,
-        x_percent: f64,
-    ) -> Result<(usize, Vec<usize>, usize, Vec<usize>), DistanceError> {
-        let members_count = wot.get_enabled().len();
-        let mut distances = Vec::new();
-        let mut average_distance: usize = 0;
-        let mut connectivities = Vec::new();
-        let mut average_connectivity: usize = 0;
-        for i in 0..wot.size() {
-            let distance_datas: WotDistance = Self::compute_distance(
-                &self,
-                wot,
-                WotDistanceParameters {
-                    node: WotId(i),
-                    sentry_requirement,
-                    step_max,
-                    x_percent,
-                },
-            )?;
-            let distance = ((f64::from(distance_datas.success)
-                / (x_percent * f64::from(distance_datas.sentries)))
-                * 100.0) as usize;
-            distances.push(distance);
-            average_distance += distance;
-            let connectivity =
-                ((f64::from(distance_datas.success - distance_datas.success_at_border)
-                    / (x_percent * f64::from(distance_datas.sentries)))
-                    * 100.0) as usize;
-            connectivities.push(connectivity);
-            average_connectivity += connectivity;
-        }
-        average_distance /= members_count;
-        average_connectivity /= members_count;
-        Ok((
-            average_distance,
-            distances,
-            average_connectivity,
-            connectivities,
-        ))
-    }
-}
diff --git a/rust-libs/dubp-wot/src/operations/mod.rs b/rust-libs/dubp-wot/src/operations/mod.rs
deleted file mode 100644
index e3fb53ca1..000000000
--- a/rust-libs/dubp-wot/src/operations/mod.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-//! Provide operation traits and implementations on `WebOfTrust` objects.
-
-pub mod centrality;
-pub mod density;
-pub mod distance;
-pub mod path;
diff --git a/rust-libs/dubp-wot/src/operations/path.rs b/rust-libs/dubp-wot/src/operations/path.rs
deleted file mode 100644
index 5aef5149c..000000000
--- a/rust-libs/dubp-wot/src/operations/path.rs
+++ /dev/null
@@ -1,107 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-//! Provide a trait and implementations to find paths between nodes.
-
-use crate::data::WebOfTrust;
-use crate::data::WotId;
-use std::collections::HashSet;
-
-/// Find paths between 2 nodes of a `WebOfTrust`.
-pub trait PathFinder<T: WebOfTrust> {
-    /// Get paths from one node to the other.
-    fn find_paths(&self, wot: &T, from: WotId, to: WotId, k_max: u32) -> Vec<Vec<WotId>>;
-}
-
-/// A new "rusty-er" implementation of `WoT` path finding.
-#[derive(Debug, Clone, Copy)]
-pub struct RustyPathFinder;
-
-impl<T: WebOfTrust> PathFinder<T> for RustyPathFinder {
-    fn find_paths(&self, wot: &T, from: WotId, to: WotId, k_max: u32) -> Vec<Vec<WotId>> {
-        if from.0 >= wot.size() || to.0 >= wot.size() {
-            return vec![];
-        }
-
-        // 1. We explore the k_max area around `to`, and only remember backward
-        //    links of the smallest distance.
-
-        // Stores for each node its distance to `to` node and its backward links.
-        // By default all nodes are out of range (`k_max + 1`) and links are known.
-        let mut graph: Vec<(u32, Vec<WotId>)> =
-            (0..wot.size()).map(|_| (k_max + 1, vec![])).collect();
-        // `to` node is at distance 0, and have no backward links.
-        graph[to.0] = (0, vec![]);
-        // Explored zone border.
-        let mut border = HashSet::new();
-        border.insert(to);
-
-        for distance in 1..=k_max {
-            let mut next_border = HashSet::new();
-
-            for node in border {
-                for source in &wot
-                    .get_links_source(node)
-                    .expect("links source must not be None")
-                {
-                    match graph[source.0].0 {
-                        path_distance if path_distance > distance => {
-                            // shorter path, we replace
-                            graph[source.0] = (distance, vec![node]);
-                            next_border.insert(*source);
-                        }
-                        path_distance if path_distance == distance => {
-                            // same length, we combine
-                            graph[source.0].1.push(node);
-                            next_border.insert(*source);
-                        }
-                        _ => unreachable!(),
-                    }
-                }
-            }
-
-            border = next_border;
-        }
-
-        // 2. If `from` is found, we follow the backward links and build paths.
-        //    For each path, we look at the last element sources and build new paths with them.
-        let mut paths = vec![vec![from]];
-
-        for _ in 1..=k_max {
-            let mut new_paths = vec![];
-
-            for path in &paths {
-                let node = path.last().expect("path should not be empty");
-
-                if node == &to {
-                    // If path is complete, we keep it.
-                    new_paths.push(path.clone())
-                } else {
-                    // If not complete we comlete paths
-                    let sources = &graph[node.0];
-                    for source in &sources.1 {
-                        let mut new_path = path.clone();
-                        new_path.push(*source);
-                        new_paths.push(new_path);
-                    }
-                }
-            }
-
-            paths = new_paths;
-        }
-
-        paths
-    }
-}
diff --git a/rust-libs/dubp-wot/tests/g1_genesis.bin b/rust-libs/dubp-wot/tests/g1_genesis.bin
deleted file mode 100644
index d684f6197a5442ff4860dec581a65b19456a51d4..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 3223
zcmcC!fB;5O2+hFDz`y`vGcqtRure?(urM$%urn|)XfQA^$TKi7STQg#C^9fGSTZm$
z@G~$la4|42FflMNa56A3h%+!Sm@qIf@Gvki@G&qj=rS-c$S^Q4h(OJTTLO{<87cv_
z0HhgYILH8yT96}@pca5E(t$e40%{@10+2&M7K=eG0hs~P%P0gQp%|nYWGKi$kgGwi
z18D?l0{IN&1CU0LFF-y9ISk}`ki$R@0$Bvo4>FDs<YEv*nSp^p80syMVIT`Z8o3!5
z7}!7x7#JAft^nBpG6iHa$W)M%K?Z>|fD8et2Zb%jr63zYwt-v(G8p7ykZS~>;R{mB
z2#ORC17tABFc2GLGsp`tIYvQ{C^Y6kwu4Lu`57b(G99ED6qp>)fCU9M$S{!YAe%w4
z1`2dgn1IxS^fAH=00kz<Ss*Wf6oWK_q8el%$Q2+>FbhEjg1iMX1Y{Y=Vvx5$;RLb-
zWGN_EKo)?^1JUq+25ABbfD8ax2(nBP8u%bzf#euLfdgWIOacWcEHFWeK_-JVgIoo2
z3CMPkD?o;U^nfA)<QkC8(jWm)%z*+E#0D7%(gZRD#0P~3NF&H#kU=09fLsXjDu@qK
z!w51R!~i9EP&xrAW@cbu0HqOCXqE!G66Al7Iz|`+<U~*!0oe-D1TqNZG?;4`LDqqE
zfUE>*0)-yPT987Rvp{|Yg}ydOAv8mR<Uw3UkVX&#<{yw^kQm4|kgXtRf}9L83}i4!
zEj)BVagXc*kaIzS12P>H|Dad^83GCnkOiR31u_T}vY_+=OOWsY0vRX;ElWTeK=G;o
zO^qPiL0$yA0LB1GsxvS!$T2W5s4y@vfZ_|J38V;w;U<Ip0P+*aKcLV9MFl9xLCys^
z8)hIpL_uj6<Zh5#L7G9i2;_E<-#`HbOC_KH10@2Gp(r+j1V9lCvJqqe%r;PffLsDH
z0IUHP3Luj}o(7o?%QYayApgJ=gIoj(MUX2%2?69fPy&G&4ss#bP>>;D2DBsw`440$
z$S_byf}#iHY*2!MMIj?7PC%MKnn5Ok6oJG*wu2OcoDK34C^dmx3o;bsB9I<X)PZPt
zJ_RWTITa)bG7x4nC{ci101{^eMFWTd@(V}<C@MgTLH+`n4Du%^3_z{{*#Pn@$R(is
z42n9C(_w~zVhH3SP|Sf65y)J)Yd{GDlu$sngIof#Kn+@%fMN<oF(_4mOps+@U;rrw
zX#}M%P$~nt5Ud#FG!O&i43M=TCxR4%vKc7gK+XjP9LR|vb?{6LG9Bg|kf|U|AlpFx
z1}g;V0x>`mASa+}04WC92vWlc@(73l3PBJXWGyI!K&F906qKSsP6LG|D1<<v334)W
zVgTufI}c<!$ax@zAkTta0SW+kD8Z}-DFAs66v?2#0NJR|z`y`k2=fO>1IS4rD?y4t
z;vgr0oC>l5#d=Ws0=XNMqCpV^G7XeU;0i$|fOLS|1d0%l2SEx!ZU%)E$o(KUgF+5u
zGe|Amb0CvJ84_e7$Ocfx1lb5m(O`ujw}BWSYe60~XJB9eDFSH#X#^Pn@-RpZ+*FWN
zAS*%E!<+<iCMZ-;6oQf_NCFg5AX7k^KoNuCPLLv)Bq)7@oCVShcPA(+K}LflK&cIs
zO+jG_N_`-45QZmykOGj2phy5I0$B&r0MZQd6j(9Lv7lH1`5fd^P>g|m4zd;$3ZNhZ
zX##72IYATJ5Cqu(@(jq`a77@iK&nBp0}2{YP=R6y6jUIEFhk&B3Ca;5MIcE%1_lO@
zLXZYfaDfbhdkUrqWHLx0C_RAu08$K62*U7o5l8_@AxILGMnR^76o4??M37Y=NpvTG
zG=UU?FkCUn1W?j5g%+?N--8MlkP|=(K^Sg5ND;^bpl}6AfU*rn5P{+uWCBP5C>%iw
zK(@d%!Gj3obC5eh9s;=;6s{l-f;56K+*(k!0OcD{Sq-uhWD+PU!HPf*1~EX10+c{N
zg#<_;DE>i-1XMeKVh^MN<|%k{0i*zwKtSa%C|!aK0vQOh4P+3=-Jrw*5{Fl*pu!s@
j3DOMmASf4rf)JFlK(@gQ0BHib1Y`(^&7hI}4nzY0n4me&

diff --git a/rust-libs/dubp-wot/tests/g1_genesis.bin.gz b/rust-libs/dubp-wot/tests/g1_genesis.bin.gz
deleted file mode 100644
index 29617bd5ccb38685e0b06479fabfae0bb8394060..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 917
zcmb=JlRNEokdh-$tMTF(wgLwcw*z09*6mU~A-|^dhWoAZ`{_6MYG$6}37ER+wBPeN
zb5!nrcJJGta_EuPjCGR})+S6pXm#*jvn|_g_G-Q`HfgrktlrJ32fGq>Cp0HiZt&gk
zJ7K%;ggFb!8B$pEWja+ExVE%iF>he*(D)!S;f%vEp?X!v^$B|)KM;AK$X=Z?hq;7(
zVWaZYl87};cPC6^lP=yMzvga=p~|Vg6`Cubvj}d{oy#)wa^%gPnkrp!i`2X7thc?_
zMV2_|pN#A<aXF*M;oT&vuzEqZ$;t`34O>0>Hp|`fSmXDIf&0=a2I)y*(i21?TPoNW
z^d)Pt%wRBc-ri{0AF(87#*FID)HerHUIdv{&U1{5IIxd9!lEks_@Py^Jm<6=eyGR&
zwpa9=c+s1Q^NZG8=-pwru{G#U<F58)LB?h$4|FEI`dRbs$*NcN5282Jb0lO%*@cNo
zFX7hkud!S9E@aUYGXt^M*Y-*tnuV*@x^IbJH=8N*fTiUt#<i~}JKGC-nBQ-*WvQN+
zyf;m#J~Tyt_p0SfcQodmci&cH_Til6ohG;GF>Ad;Hf-H7Nn+8z<ToNFCaafzEjFFj
zud?=HZdTAI!{<VxYXzs=J;%CTZr!U{0!w@^NP6ilT+18mdsejD=MifG>#w~>s&yN4
zrQLpQu3j+fvTca&0>%C#rIT!#&da=bI7fIV_g_v9>lu3{zdyj5eb7VOJb%;0V-?J`
zYzMU4fBQaHSNd}xl0U25_P~b+Ii-3Hb07R^EC}v2fBUfE{ms^HD`ws7OEVl7Rwn4J
zi!WZDp!aq9`MlknS=&_N681@EeR;NEsY*7}m)U)qCnN2(9)+Ddktu$8`;m*93vOk*
z$sUfj{uTOYLs*~M<leusecYX`#!vm;aqniz`4cW=z3bRc|EB$gyPht1|4M7s*OQYM
zr{qVUEmYpPSKl&Z-s71&&niyJwehdMQhNAUi0M}EebdfN>i8~n`|7h_hvxj1%_+ZP
zK2u%j{RY3uhx9GaEw-)xw{MkDltQnUsk>Hbj;U<C%B!E68<$K!yW~t}<Kl15;g4Qi
zx2SuxVs>=q9>Kad+tW49oVR?v?AlN7N6X)NB%RIv5U-LjKh4TaUFhc175jzSXIh73
zZ(n<)ufE|q=bFCObG@}&vX-oB&gt8txy4b<;uia?eSEomb87T%s4u)$d-(qw?gM&G
lzbCAncSUw~>yhQ5sxggej4W!Q6Yu^1ciH|w<BSEC=K+cvz#9Mn

diff --git a/rust-libs/duniter-bc-reader/Cargo.toml b/rust-libs/duniter-bc-reader/Cargo.toml
deleted file mode 100644
index e89f4d627..000000000
--- a/rust-libs/duniter-bc-reader/Cargo.toml
+++ /dev/null
@@ -1,21 +0,0 @@
-[package]
-name = "duniter-bc-reader"
-version = "0.1.0"
-authors = ["elois <elois@duniter.org>"]
-description = "Duniter DBs read operations"
-repository = "https://git.duniter.org/nodes/typescript/duniter"
-keywords = ["dubp", "duniter", "blockchain", "database"]
-license = "AGPL-3.0"
-edition = "2018"
-
-[lib]
-path = "src/lib.rs"
-
-[dependencies]
-anyhow = "1.0.34"
-duniter-dbs = { path = "../duniter-dbs" }
-dubp = { version = "0.51.0", features = ["duniter"] }
-resiter = "0.4.0"
-
-[dev-dependencies]
-smallvec = { version = "1.4.0", features = ["serde", "write"] }
diff --git a/rust-libs/duniter-bc-reader/src/lib.rs b/rust-libs/duniter-bc-reader/src/lib.rs
deleted file mode 100644
index 222795751..000000000
--- a/rust-libs/duniter-bc-reader/src/lib.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-#![deny(
-    clippy::unwrap_used,
-    missing_copy_implementations,
-    trivial_casts,
-    trivial_numeric_casts,
-    unstable_features,
-    unused_import_braces
-)]
-
-use dubp::crypto::hashs::Hash;
-use duniter_dbs::{databases::bc_v2::BcV2DbReadable, kv_typed::prelude::*, HashKeyV2};
-
-pub fn tx_exist<BcDb: BcV2DbReadable>(bc_db_ro: &BcDb, hash: Hash) -> KvResult<bool> {
-    bc_db_ro.txs_hashs().contains_key(&HashKeyV2(hash))
-}
diff --git a/rust-libs/duniter-conf/Cargo.toml b/rust-libs/duniter-conf/Cargo.toml
deleted file mode 100644
index f2b134f81..000000000
--- a/rust-libs/duniter-conf/Cargo.toml
+++ /dev/null
@@ -1,10 +0,0 @@
-[package]
-name = "duniter-conf"
-version = "0.1.0"
-authors = ["librelois <elois@duniter.org>"]
-license = "AGPL-3.0"
-edition = "2018"
-
-[dependencies]
-dubp = { version = "0.51.0", features = ["duniter"] }
-serde = { version = "1.0.105", features = ["derive"] }
diff --git a/rust-libs/duniter-conf/src/gva_conf.rs b/rust-libs/duniter-conf/src/gva_conf.rs
deleted file mode 100644
index 38825c561..000000000
--- a/rust-libs/duniter-conf/src/gva_conf.rs
+++ /dev/null
@@ -1,113 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
-
-use crate::*;
-
-#[derive(Clone, Debug, Default, Deserialize, Serialize)]
-#[serde(rename_all = "camelCase")]
-pub struct GvaConf {
-    ip4: Option<Ipv4Addr>,
-    ip6: Option<Ipv6Addr>,
-    port: Option<u16>,
-    path: Option<String>,
-    subscriptions_path: Option<String>,
-    remote_host: Option<String>,
-    remote_port: Option<u16>,
-    remote_path: Option<String>,
-    remote_subscriptions_path: Option<String>,
-    remote_tls: Option<bool>,
-    whitelist: Option<Vec<IpAddr>>,
-}
-
-impl GvaConf {
-    pub fn get_ip4(&self) -> Ipv4Addr {
-        self.ip4.unwrap_or(Ipv4Addr::LOCALHOST)
-    }
-    pub fn get_ip6(&self) -> Option<Ipv6Addr> {
-        self.ip6
-    }
-    pub fn get_port(&self) -> u16 {
-        self.port.unwrap_or(30901)
-    }
-    pub fn get_path(&self) -> String {
-        if let Some(mut path) = self.path.clone() {
-            if path.starts_with('/') {
-                path.remove(0);
-                path
-            } else {
-                path
-            }
-        } else {
-            "localhost".to_owned()
-        }
-    }
-    pub fn get_subscriptions_path(&self) -> String {
-        if let Some(mut subscriptions_path) = self.subscriptions_path.clone() {
-            if subscriptions_path.starts_with('/') {
-                subscriptions_path.remove(0);
-                subscriptions_path
-            } else {
-                subscriptions_path
-            }
-        } else {
-            "localhost".to_owned()
-        }
-    }
-    pub fn get_remote_host(&self) -> String {
-        if let Some(ref remote_host) = self.remote_host {
-            remote_host.to_owned()
-        } else if let Some(ip6) = self.ip6 {
-            format!("{} [{}]", self.get_ip4(), ip6)
-        } else {
-            self.get_ip4().to_string()
-        }
-    }
-    pub fn get_remote_port(&self) -> u16 {
-        if let Some(remote_port) = self.remote_port {
-            remote_port
-        } else {
-            self.get_port()
-        }
-    }
-    pub fn get_remote_path(&self) -> String {
-        if let Some(ref remote_path) = self.remote_path {
-            remote_path.to_owned()
-        } else {
-            self.get_path()
-        }
-    }
-    pub fn get_remote_subscriptions_path(&self) -> String {
-        if let Some(ref remote_subscriptions_path) = self.remote_subscriptions_path {
-            remote_subscriptions_path.to_owned()
-        } else {
-            self.get_subscriptions_path()
-        }
-    }
-    pub fn get_remote_tls(&self) -> bool {
-        self.remote_tls.unwrap_or(false)
-    }
-    pub fn get_whitelist(&self) -> &[IpAddr] {
-        if let Some(ref whitelist) = self.whitelist {
-            whitelist
-        } else {
-            &[
-                IpAddr::V4(Ipv4Addr::LOCALHOST),
-                IpAddr::V6(Ipv6Addr::LOCALHOST),
-            ]
-        }
-    }
-}
diff --git a/rust-libs/duniter-conf/src/lib.rs b/rust-libs/duniter-conf/src/lib.rs
deleted file mode 100644
index 5038209c6..000000000
--- a/rust-libs/duniter-conf/src/lib.rs
+++ /dev/null
@@ -1,54 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-#![deny(
-    clippy::unwrap_used,
-    missing_copy_implementations,
-    trivial_casts,
-    trivial_numeric_casts,
-    unstable_features,
-    unused_import_braces
-)]
-
-pub mod gva_conf;
-
-use crate::gva_conf::GvaConf;
-use dubp::crypto::keys::ed25519::Ed25519KeyPair;
-use serde::{Deserialize, Serialize};
-
-#[derive(Clone, Debug)]
-pub struct DuniterConf {
-    pub gva: Option<GvaConf>,
-    pub self_key_pair: Ed25519KeyPair,
-    pub txs_mempool_size: usize,
-}
-
-impl Default for DuniterConf {
-    fn default() -> Self {
-        DuniterConf {
-            gva: None,
-            self_key_pair: Ed25519KeyPair::generate_random().expect("fail to gen random keypair"),
-            txs_mempool_size: 0,
-        }
-    }
-}
-
-/// Duniter mode
-#[derive(Clone, Copy, Debug)]
-#[non_exhaustive]
-pub enum DuniterMode {
-    Start,
-    Sync,
-}
diff --git a/rust-libs/duniter-dbs-write-ops/Cargo.toml b/rust-libs/duniter-dbs-write-ops/Cargo.toml
deleted file mode 100644
index 4b49787fd..000000000
--- a/rust-libs/duniter-dbs-write-ops/Cargo.toml
+++ /dev/null
@@ -1,35 +0,0 @@
-[package]
-name = "duniter-dbs-write-ops"
-version = "0.1.0"
-authors = ["elois <elois@duniter.org>"]
-description = "Duniter DBs write operations"
-repository = "https://git.duniter.org/nodes/typescript/duniter"
-keywords = ["dubp", "duniter", "blockchain", "database"]
-license = "AGPL-3.0"
-edition = "2018"
-
-[lib]
-path = "src/lib.rs"
-
-[dependencies]
-chrono = "0.4.19"
-dubp = { version = "0.51.0", features = ["duniter"] }
-duniter-dbs = { path = "../duniter-dbs" }
-duniter-global = { path = "../duniter-global" }
-fast-threadpool = "0.2.3"
-flume = "0.10"
-log = "0.4.11"
-resiter = "0.4.0"
-
-[dev-dependencies]
-anyhow = "1.0.34"
-duniter-dbs = { path = "../duniter-dbs", features = ["mem"] }
-maplit = "1.0.2"
-serde_json = "1.0.53"
-
-[features]
-default = ["sled_backend"]
-
-explorer = ["duniter-dbs/explorer"]
-leveldb_backend = ["duniter-dbs/leveldb_backend"]
-sled_backend = ["duniter-dbs/sled_backend"]
diff --git a/rust-libs/duniter-dbs-write-ops/src/apply_block.rs b/rust-libs/duniter-dbs-write-ops/src/apply_block.rs
deleted file mode 100644
index 7d7e4511c..000000000
--- a/rust-libs/duniter-dbs-write-ops/src/apply_block.rs
+++ /dev/null
@@ -1,173 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-pub fn apply_block(
-    bc_db: &BcV2Db<FileBackend>,
-    block: Arc<DubpBlockV10>,
-    current_opt: Option<BlockMetaV2>,
-    dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
-    global_sender: &flume::Sender<GlobalBackGroundTaskMsg>,
-    throw_chainability: bool,
-) -> KvResult<BlockMetaV2> {
-    if let Some(current) = current_opt {
-        if block.number().0 == current.number + 1 {
-            apply_block_inner(bc_db, dbs_pool, block, global_sender)
-        } else if throw_chainability {
-            Err(KvError::Custom(
-                format!(
-                    "block #{} not chainable on current #{}",
-                    block.number().0,
-                    current.number
-                )
-                .into(),
-            ))
-        } else {
-            Ok(current)
-        }
-    } else if block.number() == BlockNumber(0) {
-        apply_block_inner(bc_db, dbs_pool, block, global_sender)
-    } else {
-        Err(KvError::Custom(
-            "Try to apply non genesis block on empty blockchain".into(),
-        ))
-    }
-}
-
-#[inline(always)]
-pub fn apply_chunk(
-    bc_db: &BcV2Db<FileBackend>,
-    current_opt: Option<BlockMetaV2>,
-    dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
-    blocks: Arc<[DubpBlockV10]>,
-    global_sender: Option<&flume::Sender<GlobalBackGroundTaskMsg>>,
-) -> KvResult<BlockMetaV2> {
-    verify_chunk_chainability(current_opt, &blocks)?;
-    apply_chunk_inner(bc_db, dbs_pool, blocks, global_sender)
-}
-
-fn verify_chunk_chainability(
-    current_opt: Option<BlockMetaV2>,
-    blocks: &[DubpBlockV10],
-) -> KvResult<()> {
-    if let Some(mut current) = current_opt {
-        for block in blocks {
-            if block.number().0 == current.number + 1 {
-                current.number += 1;
-            } else {
-                return Err(KvError::Custom(
-                    format!(
-                        "block #{} not chainable on current #{}",
-                        blocks[0].number().0,
-                        current.number
-                    )
-                    .into(),
-                ));
-            }
-        }
-        Ok(())
-    } else if blocks[0].number() == BlockNumber(0) {
-        let mut current_number = 0;
-        for block in &blocks[1..] {
-            if block.number().0 == current_number + 1 {
-                current_number += 1;
-            } else {
-                return Err(KvError::Custom(
-                    format!(
-                        "block #{} not chainable on current #{}",
-                        block.number().0,
-                        current_number
-                    )
-                    .into(),
-                ));
-            }
-        }
-        Ok(())
-    } else {
-        Err(KvError::Custom(
-            "Try to apply non genesis block on empty blockchain".into(),
-        ))
-    }
-}
-
-fn apply_block_inner(
-    bc_db: &BcV2Db<FileBackend>,
-    dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
-    block: Arc<DubpBlockV10>,
-    global_sender: &flume::Sender<GlobalBackGroundTaskMsg>,
-) -> KvResult<BlockMetaV2> {
-    let block_for_cm = Arc::clone(&block);
-    let block_for_txs_mp = Arc::clone(&block);
-
-    // Cm
-    crate::cm::update_current_meta(&block_for_cm, &global_sender);
-
-    //TxsMp
-    let txs_mp_handle = dbs_pool
-        .launch(move |dbs| {
-            crate::txs_mp::apply_block(block_for_txs_mp.transactions(), &dbs.txs_mp_db)?;
-            Ok::<_, KvError>(())
-        })
-        .expect("dbs pool disconnected");
-
-    // Bc
-    let new_current = crate::bc::apply_block(bc_db, &block)?;
-
-    txs_mp_handle.join().expect("dbs pool disconnected")?;
-
-    Ok(new_current)
-}
-
-fn apply_chunk_inner(
-    bc_db: &BcV2Db<FileBackend>,
-    dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
-    blocks: Arc<[DubpBlockV10]>,
-    global_sender: Option<&flume::Sender<GlobalBackGroundTaskMsg>>,
-) -> KvResult<BlockMetaV2> {
-    let blocks_len = blocks.len();
-    let blocks_for_txs_mp = Arc::clone(&blocks);
-
-    // Cm
-    if let Some(global_sender) = global_sender {
-        let chunk_len = blocks.len();
-        crate::cm::update_current_meta(&&blocks.deref()[chunk_len - 1], &global_sender);
-    }
-
-    //TxsMp
-    //log::info!("apply_chunk: launch txs_mp job...");
-    let txs_mp_handle = dbs_pool
-        .launch(move |dbs| {
-            for block in blocks_for_txs_mp.deref() {
-                crate::txs_mp::apply_block(block.transactions(), &dbs.txs_mp_db)?;
-            }
-            Ok::<_, KvError>(())
-        })
-        .expect("apply_chunk_inner:txs_mp: dbs pool disconnected");
-
-    // Bc
-    //log::info!("apply_chunk: launch bc job...");
-    for block in &blocks[..(blocks_len - 1)] {
-        crate::bc::apply_block(bc_db, block)?;
-    }
-    let current_block = crate::bc::apply_block(bc_db, &blocks[blocks_len - 1])?;
-
-    txs_mp_handle
-        .join()
-        .expect("txs_mp_recv: dbs pool disconnected")?;
-    //log::info!("apply_chunk: txs_mp job finish.");
-
-    Ok(current_block)
-}
diff --git a/rust-libs/duniter-dbs-write-ops/src/bc.rs b/rust-libs/duniter-dbs-write-ops/src/bc.rs
deleted file mode 100644
index 17b2c1bc2..000000000
--- a/rust-libs/duniter-dbs-write-ops/src/bc.rs
+++ /dev/null
@@ -1,325 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-mod identities;
-mod txs;
-mod uds;
-
-use crate::*;
-use duniter_dbs::databases::bc_v2::BcV2DbWritable;
-
-pub fn apply_block<B: Backend>(
-    bc_db: &duniter_dbs::databases::bc_v2::BcV2Db<B>,
-    block: &DubpBlockV10,
-) -> KvResult<BlockMetaV2> {
-    //log::info!("apply_block #{}", block.number().0);
-    let block_meta = BlockMetaV2::from(block);
-
-    (
-        bc_db.blocks_meta_write(),
-        bc_db.identities_write(),
-        bc_db.txs_hashs_write(),
-        bc_db.uds_write(),
-        bc_db.uds_reval_write(),
-        bc_db.uids_index_write(),
-        bc_db.utxos_write(),
-        bc_db.consumed_utxos_write(),
-    )
-        .write(
-            |(
-                mut blocks_meta,
-                mut identities,
-                mut txs_hashs,
-                mut uds,
-                mut uds_reval,
-                mut uids_index,
-                mut utxos,
-                mut consumed_utxos,
-            )| {
-                blocks_meta.upsert(U32BE(block.number().0), block_meta);
-                identities::update_identities::<B>(&block, &mut identities)?;
-                for idty in block.identities() {
-                    let pubkey = idty.issuers()[0];
-                    let username = idty.username().to_owned();
-                    uids_index.upsert(username, PubKeyValV2(pubkey));
-                }
-                if let Some(dividend) = block.dividend() {
-                    uds::create_uds::<B>(
-                        block.number(),
-                        dividend,
-                        &mut identities,
-                        &mut uds,
-                        &mut uds_reval,
-                    )?;
-                }
-                txs::apply_txs::<B>(
-                    block.number(),
-                    block.transactions(),
-                    &mut txs_hashs,
-                    &mut uds,
-                    &mut utxos,
-                    &mut consumed_utxos,
-                )?;
-                Ok(())
-            },
-        )?;
-
-    if block_meta.number > ROLL_BACK_MAX {
-        prune_bc_db(bc_db, BlockNumber(block_meta.number))?;
-    }
-
-    Ok(block_meta)
-}
-
-fn prune_bc_db<B: Backend>(
-    bc_db: &duniter_dbs::databases::bc_v2::BcV2Db<B>,
-    current_block_number: BlockNumber,
-) -> KvResult<()> {
-    bc_db
-        .consumed_utxos_write()
-        .remove(U32BE(current_block_number.0 - ROLL_BACK_MAX))?;
-    Ok(())
-}
-
-pub fn revert_block<B: Backend>(
-    bc_db: &duniter_dbs::databases::bc_v2::BcV2Db<B>,
-    block: &DubpBlockV10,
-) -> KvResult<Option<BlockMetaV2>> {
-    (
-        bc_db.blocks_meta_write(),
-        bc_db.identities_write(),
-        bc_db.txs_hashs_write(),
-        bc_db.uds_write(),
-        bc_db.uds_reval_write(),
-        bc_db.uids_index_write(),
-        bc_db.utxos_write(),
-        bc_db.consumed_utxos_write(),
-    )
-        .write(
-            |(
-                mut blocks_meta,
-                mut identities,
-                mut txs_hashs,
-                mut uds,
-                mut uds_reval,
-                mut uids_index,
-                mut utxos,
-                mut consumed_utxos,
-            )| {
-                txs::revert_txs::<B>(
-                    block.number(),
-                    block.transactions(),
-                    &mut txs_hashs,
-                    &mut uds,
-                    &mut utxos,
-                    &mut consumed_utxos,
-                )?;
-                if block.dividend().is_some() {
-                    uds::revert_uds::<B>(
-                        block.number(),
-                        &mut identities,
-                        &mut uds,
-                        &mut uds_reval,
-                    )?;
-                }
-                identities::revert_identities::<B>(&block, &mut identities)?;
-                for idty in block.identities() {
-                    let username = idty.username().to_owned();
-                    uids_index.remove(username);
-                }
-                blocks_meta.remove(U32BE(block.number().0));
-                Ok(if block.number() == BlockNumber(0) {
-                    None
-                } else {
-                    blocks_meta.get(&U32BE(block.number().0 - 1))?
-                })
-            },
-        )
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use dubp::{
-        crypto::keys::{ed25519::PublicKey, PublicKey as _},
-        documents::transaction::TransactionDocumentV10Stringified,
-        documents_parser::prelude::FromStringObject,
-    };
-    use duniter_dbs::{
-        databases::bc_v2::*, BlockUtxosV2Db, UtxoIdDbV2, WalletScriptWithSourceAmountV1Db,
-    };
-    use maplit::hashmap;
-
-    #[test]
-    fn test_bc_apply_block() -> anyhow::Result<()> {
-        let bc_db = BcV2Db::<Mem>::open(MemConf::default())?;
-
-        let s1 = WalletScriptV10::single_sig(PublicKey::from_base58(
-            "D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx",
-        )?);
-        let s2 = WalletScriptV10::single_sig(PublicKey::from_base58(
-            "4fHMTFBMo5sTQEc5p1CNWz28S4mnnqdUBmECq1zt4n2m",
-        )?);
-
-        let b0 = DubpBlockV10::from_string_object(&DubpBlockV10Stringified {
-            version: 10,
-            median_time: 5_243,
-            dividend: Some(1000),
-            joiners: vec!["D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx:FFeyrvYio9uYwY5aMcDGswZPNjGLrl8THn9l3EPKSNySD3SDSHjCljSfFEwb87sroyzJQoVzPwER0sW/cbZMDg==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:elois".to_owned()],
-            inner_hash: Some("0000000A65A12DB95B3153BCD05DB4D5C30CC7F0B1292D9FFBC3DE67F72F6040".to_owned()),
-            signature: "7B0hvcfajE2G8nBLp0vLVaQcQdQIyli21Gu8F2l+nimKHRe+fUNi+MWd1e/u29BYZa+RZ1yxhbHIbFzytg7fAA==".to_owned(),
-            hash: Some("0000000000000000000000000000000000000000000000000000000000000000".to_owned()),
-            ..Default::default()
-        })?;
-
-        apply_block(&bc_db, &b0)?;
-
-        assert_eq!(bc_db.blocks_meta().count()?, 1);
-        assert_eq!(bc_db.uds().count()?, 1);
-        assert_eq!(bc_db.utxos().count()?, 0);
-        assert_eq!(bc_db.consumed_utxos().count()?, 0);
-
-        let b1 = DubpBlockV10::from_string_object(&DubpBlockV10Stringified {
-            number: 1,
-            version: 10,
-            median_time: 5_245,
-            transactions: vec![TransactionDocumentV10Stringified {
-                currency: "test".to_owned(),
-                blockstamp: "0-0000000000000000000000000000000000000000000000000000000000000000".to_owned(),
-                locktime: 0,
-                issuers: vec!["D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx".to_owned()],
-                inputs: vec!["1000:0:D:D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx:0".to_owned()],
-                unlocks: vec![],
-                outputs: vec![
-                    "600:0:SIG(4fHMTFBMo5sTQEc5p1CNWz28S4mnnqdUBmECq1zt4n2m)".to_owned(),
-                    "400:0:SIG(D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx)".to_owned(),
-                ],
-                comment: "".to_owned(),
-                signatures: vec![],
-                hash: Some("0000000000000000000000000000000000000000000000000000000000000000".to_owned()),
-            }],
-            inner_hash: Some("0000000A65A12DB95B3153BCD05DB4D5C30CC7F0B1292D9FFBC3DE67F72F6040".to_owned()),
-            signature: "7B0hvcfajE2G8nBLp0vLVaQcQdQIyli21Gu8F2l+nimKHRe+fUNi+MWd1e/u29BYZa+RZ1yxhbHIbFzytg7fAA==".to_owned(),
-            hash: Some("0000000000000000000000000000000000000000000000000000000000000000".to_owned()),
-            ..Default::default()
-        })?;
-
-        apply_block(&bc_db, &b1)?;
-
-        assert_eq!(bc_db.blocks_meta().count()?, 2);
-        assert_eq!(bc_db.uds().count()?, 0);
-        assert_eq!(bc_db.utxos().count()?, 2);
-        assert_eq!(
-            bc_db
-                .utxos()
-                .iter(.., |it| it.collect::<KvResult<Vec<_>>>())?,
-            vec![
-                (
-                    UtxoIdDbV2(Hash::default(), 0),
-                    WalletScriptWithSourceAmountV1Db {
-                        wallet_script: s2.clone(),
-                        source_amount: SourceAmount::with_base0(600)
-                    }
-                ),
-                (
-                    UtxoIdDbV2(Hash::default(), 1),
-                    WalletScriptWithSourceAmountV1Db {
-                        wallet_script: s1.clone(),
-                        source_amount: SourceAmount::with_base0(400)
-                    }
-                )
-            ]
-        );
-        assert_eq!(bc_db.consumed_utxos().count()?, 0);
-
-        let b2 = DubpBlockV10::from_string_object(&DubpBlockV10Stringified {
-            number: 2,
-            version: 10,
-            median_time: 5_247,
-            transactions: vec![TransactionDocumentV10Stringified {
-                currency: "test".to_owned(),
-                blockstamp: "0-0000000000000000000000000000000000000000000000000000000000000000".to_owned(),
-                locktime: 0,
-                issuers: vec!["D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx".to_owned()],
-                inputs: vec!["400:0:T:0000000000000000000000000000000000000000000000000000000000000000:1".to_owned()],
-                unlocks: vec![],
-                outputs: vec![
-                    "300:0:SIG(D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx)".to_owned(),
-                    "100:0:SIG(4fHMTFBMo5sTQEc5p1CNWz28S4mnnqdUBmECq1zt4n2m)".to_owned(),
-                ],
-                comment: "".to_owned(),
-                signatures: vec![],
-                hash: Some("0101010101010101010101010101010101010101010101010101010101010101".to_owned()),
-            }],
-            inner_hash: Some("0000000A65A12DB95B3153BCD05DB4D5C30CC7F0B1292D9FFBC3DE67F72F6040".to_owned()),
-            signature: "7B0hvcfajE2G8nBLp0vLVaQcQdQIyli21Gu8F2l+nimKHRe+fUNi+MWd1e/u29BYZa+RZ1yxhbHIbFzytg7fAA==".to_owned(),
-            hash: Some("0000000000000000000000000000000000000000000000000000000000000000".to_owned()),
-            ..Default::default()
-        })?;
-
-        apply_block(&bc_db, &b2)?;
-
-        assert_eq!(bc_db.blocks_meta().count()?, 3);
-        assert_eq!(bc_db.uds().count()?, 0);
-        assert_eq!(bc_db.utxos().count()?, 3);
-        assert_eq!(bc_db.consumed_utxos().count()?, 1);
-
-        assert_eq!(
-            bc_db
-                .consumed_utxos()
-                .iter(.., |it| it.collect::<KvResult<Vec<_>>>())?,
-            vec![(
-                U32BE(2),
-                BlockUtxosV2Db(
-                    hashmap![UtxoIdV10 { tx_hash: Hash::default(), output_index: 1 } => WalletScriptWithSourceAmountV1Db {
-                        wallet_script: s1.clone(),
-                        source_amount: SourceAmount::with_base0(400)
-                    }]
-                )
-            )]
-        );
-
-        assert_eq!(
-            bc_db
-                .utxos()
-                .iter(.., |it| it.collect::<KvResult<Vec<_>>>())?,
-            vec![
-                (
-                    UtxoIdDbV2(Hash::default(), 0),
-                    WalletScriptWithSourceAmountV1Db {
-                        wallet_script: s2.clone(),
-                        source_amount: SourceAmount::with_base0(600)
-                    }
-                ),
-                (
-                    UtxoIdDbV2(Hash([1; 32]), 0),
-                    WalletScriptWithSourceAmountV1Db {
-                        wallet_script: s1,
-                        source_amount: SourceAmount::with_base0(300)
-                    }
-                ),
-                (
-                    UtxoIdDbV2(Hash([1; 32]), 1),
-                    WalletScriptWithSourceAmountV1Db {
-                        wallet_script: s2,
-                        source_amount: SourceAmount::with_base0(100)
-                    }
-                )
-            ]
-        );
-
-        Ok(())
-    }
-}
diff --git a/rust-libs/duniter-dbs-write-ops/src/bc/identities.rs b/rust-libs/duniter-dbs-write-ops/src/bc/identities.rs
deleted file mode 100644
index 024930874..000000000
--- a/rust-libs/duniter-dbs-write-ops/src/bc/identities.rs
+++ /dev/null
@@ -1,95 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-use duniter_dbs::databases::bc_v2::IdentitiesEvent;
-use duniter_dbs::IdtyDbV2;
-
-pub(crate) fn update_identities<B: Backend>(
-    block: &DubpBlockV10,
-    identities: &mut TxColRw<B::Col, IdentitiesEvent>,
-) -> KvResult<()> {
-    for idty in block.identities() {
-        let pubkey = idty.issuers()[0];
-        let username = idty.username().to_owned();
-        identities.upsert(
-            PubKeyKeyV2(pubkey),
-            IdtyDbV2 {
-                is_member: true,
-                username,
-            },
-        )
-    }
-    for mb in block.joiners() {
-        let pubkey = mb.issuers()[0];
-        let username = mb.identity_username().to_owned();
-        identities.upsert(
-            PubKeyKeyV2(pubkey),
-            IdtyDbV2 {
-                is_member: true,
-                username,
-            },
-        )
-    }
-    for revo in block.revoked() {
-        let pubkey = revo.issuer;
-        if let Some(mut idty) = identities.get(&PubKeyKeyV2(pubkey))? {
-            idty.is_member = false;
-            identities.upsert(PubKeyKeyV2(pubkey), idty)
-        }
-    }
-    for pubkey in block.excluded().iter().copied() {
-        if let Some(mut idty) = identities.get(&PubKeyKeyV2(pubkey))? {
-            idty.is_member = false;
-            identities.upsert(PubKeyKeyV2(pubkey), idty)
-        }
-    }
-    Ok(())
-}
-
-pub(crate) fn revert_identities<B: Backend>(
-    block: &DubpBlockV10,
-    identities: &mut TxColRw<B::Col, IdentitiesEvent>,
-) -> KvResult<()> {
-    for mb in block.joiners() {
-        let pubkey = mb.issuers()[0];
-        let username = mb.identity_username().to_owned();
-        identities.upsert(
-            PubKeyKeyV2(pubkey),
-            IdtyDbV2 {
-                is_member: false,
-                username,
-            },
-        )
-    }
-    for idty in block.identities() {
-        let pubkey = idty.issuers()[0];
-        identities.remove(PubKeyKeyV2(pubkey));
-    }
-    for revo in block.revoked() {
-        let pubkey = revo.issuer;
-        if let Some(mut idty) = identities.get(&PubKeyKeyV2(pubkey))? {
-            idty.is_member = true;
-            identities.upsert(PubKeyKeyV2(pubkey), idty)
-        }
-    }
-    for pubkey in block.excluded().iter().copied() {
-        if let Some(mut idty) = identities.get(&PubKeyKeyV2(pubkey))? {
-            idty.is_member = true;
-            identities.upsert(PubKeyKeyV2(pubkey), idty)
-        }
-    }
-    Ok(())
-}
diff --git a/rust-libs/duniter-dbs-write-ops/src/bc/txs.rs b/rust-libs/duniter-dbs-write-ops/src/bc/txs.rs
deleted file mode 100644
index d8154fd0c..000000000
--- a/rust-libs/duniter-dbs-write-ops/src/bc/txs.rs
+++ /dev/null
@@ -1,130 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use std::collections::HashMap;
-
-use crate::*;
-use dubp::documents::transaction::TransactionOutputV10;
-use duniter_dbs::{
-    databases::bc_v2::{ConsumedUtxosEvent, TxsHashsEvent, UdsEvent, UtxosEvent},
-    BlockUtxosV2Db, UdIdV2, UtxoIdDbV2, WalletScriptWithSourceAmountV1Db,
-};
-
-pub(crate) fn apply_txs<B: Backend>(
-    block_number: BlockNumber,
-    block_txs: &[TransactionDocumentV10],
-    txs_hashs: &mut TxColRw<B::Col, TxsHashsEvent>,
-    uds: &mut TxColRw<B::Col, UdsEvent>,
-    utxos: &mut TxColRw<B::Col, UtxosEvent>,
-    consumed_utxos: &mut TxColRw<B::Col, ConsumedUtxosEvent>,
-) -> KvResult<()> {
-    if !block_txs.is_empty() {
-        let mut block_consumed_utxos = HashMap::with_capacity(block_txs.len() * 3);
-        for tx in block_txs {
-            let tx_hash = tx.get_hash();
-            txs_hashs.upsert(HashKeyV2(tx_hash), ());
-            for input in tx.get_inputs() {
-                match input.id {
-                    SourceIdV10::Ud(UdSourceIdV10 {
-                        issuer,
-                        block_number,
-                    }) => {
-                        uds.remove(UdIdV2(issuer, block_number));
-                    }
-                    SourceIdV10::Utxo(utxo_id) => {
-                        let utxo_id_db = UtxoIdDbV2(utxo_id.tx_hash, utxo_id.output_index as u32);
-                        if let Some(wallet_script_with_sa) = utxos.get(&utxo_id_db)? {
-                            utxos.remove(utxo_id_db);
-                            block_consumed_utxos.insert(utxo_id, wallet_script_with_sa);
-                        } else {
-                            return Err(KvError::Custom(
-                                format!("db corrupted: not found utxo {:?}", utxo_id_db).into(),
-                            ));
-                        }
-                    }
-                }
-            }
-            for (output_index, TransactionOutputV10 { amount, conditions }) in
-                tx.get_outputs().iter().enumerate()
-            {
-                let utxo_id = UtxoIdDbV2(tx_hash, output_index as u32);
-                let wallet_script_with_sa = WalletScriptWithSourceAmountV1Db {
-                    wallet_script: conditions.script.clone(),
-                    source_amount: *amount,
-                };
-                utxos.upsert(utxo_id, wallet_script_with_sa);
-            }
-        }
-        if !block_consumed_utxos.is_empty() {
-            consumed_utxos.upsert(U32BE(block_number.0), BlockUtxosV2Db(block_consumed_utxos));
-        }
-    }
-    Ok(())
-}
-
-pub(crate) fn revert_txs<B: Backend>(
-    block_number: BlockNumber,
-    block_txs: &[TransactionDocumentV10],
-    txs_hashs: &mut TxColRw<B::Col, TxsHashsEvent>,
-    uds: &mut TxColRw<B::Col, UdsEvent>,
-    utxos: &mut TxColRw<B::Col, UtxosEvent>,
-    consumed_utxos: &mut TxColRw<B::Col, ConsumedUtxosEvent>,
-) -> KvResult<()> {
-    for tx in block_txs {
-        let tx_hash = tx.get_hash();
-        txs_hashs.remove(HashKeyV2(tx_hash));
-        for input in tx.get_inputs() {
-            match input.id {
-                SourceIdV10::Ud(UdSourceIdV10 {
-                    issuer,
-                    block_number,
-                }) => {
-                    uds.upsert(UdIdV2(issuer, block_number), ());
-                }
-                SourceIdV10::Utxo(utxo_id) => {
-                    let utxo_id_db = UtxoIdDbV2(utxo_id.tx_hash, utxo_id.output_index as u32);
-                    if let Some(block_utxos) = consumed_utxos.get(&U32BE(block_number.0))? {
-                        if let Some(wallet_script_with_sa) = block_utxos.0.get(&utxo_id) {
-                            utxos.upsert(utxo_id_db, wallet_script_with_sa.clone());
-                        } else {
-                            return Err(KvError::Custom(
-                                format!("db corrupted: not found consumed utxos {}", utxo_id)
-                                    .into(),
-                            ));
-                        }
-                    } else {
-                        return Err(KvError::Custom(
-                            format!("db corrupted: not found consumed utxos {:?}", utxo_id_db)
-                                .into(),
-                        ));
-                    }
-                }
-            }
-            if let SourceIdV10::Ud(UdSourceIdV10 {
-                issuer,
-                block_number,
-            }) = input.id
-            {
-                uds.upsert(UdIdV2(issuer, block_number), ());
-            }
-        }
-        for output_index in 0..tx.get_outputs().len() {
-            let utxo_id = UtxoIdDbV2(tx_hash, output_index as u32);
-            utxos.remove(utxo_id);
-        }
-    }
-    consumed_utxos.remove(U32BE(block_number.0));
-    Ok(())
-}
diff --git a/rust-libs/duniter-dbs-write-ops/src/bc/uds.rs b/rust-libs/duniter-dbs-write-ops/src/bc/uds.rs
deleted file mode 100644
index e8323f9bf..000000000
--- a/rust-libs/duniter-dbs-write-ops/src/bc/uds.rs
+++ /dev/null
@@ -1,69 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-use duniter_dbs::{
-    databases::bc_v2::{IdentitiesEvent, UdsEvent, UdsRevalEvent},
-    UdIdV2,
-};
-
-pub(crate) fn create_uds<B: Backend>(
-    block_number: BlockNumber,
-    dividend: SourceAmount,
-    identities: &mut TxColRw<B::Col, IdentitiesEvent>,
-    uds: &mut TxColRw<B::Col, UdsEvent>,
-    uds_reval: &mut TxColRw<B::Col, UdsRevalEvent>,
-) -> KvResult<()> {
-    let previous_ud_amount = uds_reval
-        .iter_rev(.., |it| it.values().next_res())?
-        .unwrap_or(SourceAmountValV2(SourceAmount::ZERO));
-    if dividend > previous_ud_amount.0 {
-        uds_reval.upsert(U32BE(block_number.0), SourceAmountValV2(dividend));
-    }
-
-    let members = identities.iter(.., |it| {
-        it.filter_map_ok(|(pk, idty)| if idty.is_member { Some(pk.0) } else { None })
-            .collect::<KvResult<Vec<_>>>()
-    })?;
-    for member in members {
-        uds.upsert(UdIdV2(member, block_number), ());
-    }
-    Ok(())
-}
-
-pub(crate) fn revert_uds<B: Backend>(
-    block_number: BlockNumber,
-    identities: &mut TxColRw<B::Col, IdentitiesEvent>,
-    uds: &mut TxColRw<B::Col, UdsEvent>,
-    uds_reval: &mut TxColRw<B::Col, UdsRevalEvent>,
-) -> KvResult<()> {
-    let previous_reval_block_number = uds_reval
-        .iter_rev(.., |it| it.keys().next_res())?
-        .expect("corrupted db")
-        .0;
-    if block_number.0 == previous_reval_block_number {
-        uds_reval.remove(U32BE(block_number.0));
-    }
-
-    let members = identities.iter(.., |it| {
-        it.filter_map_ok(|(pk, idty)| if idty.is_member { Some(pk.0) } else { None })
-            .collect::<KvResult<Vec<_>>>()
-    })?;
-    for member in members {
-        uds.remove(UdIdV2(member, block_number));
-    }
-
-    Ok(())
-}
diff --git a/rust-libs/duniter-dbs-write-ops/src/cm.rs b/rust-libs/duniter-dbs-write-ops/src/cm.rs
deleted file mode 100644
index 5d9a61a27..000000000
--- a/rust-libs/duniter-dbs-write-ops/src/cm.rs
+++ /dev/null
@@ -1,51 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[inline(always)]
-pub(crate) fn update_current_meta(
-    block: &DubpBlockV10,
-    global_sender: &flume::Sender<GlobalBackGroundTaskMsg>,
-) {
-    let current_block_meta = block_to_block_meta(block);
-    global_sender
-        .send(GlobalBackGroundTaskMsg::NewCurrentBlock(current_block_meta))
-        .expect("global task disconnected");
-}
-
-fn block_to_block_meta(block: &DubpBlockV10) -> BlockMetaV2 {
-    BlockMetaV2 {
-        version: 10,
-        number: block.number().0,
-        hash: block.hash().0,
-        signature: block.signature(),
-        inner_hash: block.inner_hash(),
-        previous_hash: block.previous_hash(),
-        issuer: block.issuer(),
-        previous_issuer: dubp::crypto::keys::ed25519::PublicKey::default(),
-        time: block.local_time(),
-        pow_min: block.pow_min() as u32,
-        members_count: block.members_count() as u64,
-        issuers_count: block.issuers_count() as u32,
-        issuers_frame: block.issuers_frame() as u64,
-        issuers_frame_var: 0,
-        median_time: block.common_time(),
-        nonce: block.nonce(),
-        monetary_mass: block.monetary_mass(),
-        unit_base: block.unit_base() as u32,
-        dividend: block.dividend(),
-    }
-}
diff --git a/rust-libs/duniter-dbs-write-ops/src/lib.rs b/rust-libs/duniter-dbs-write-ops/src/lib.rs
deleted file mode 100644
index b112bce01..000000000
--- a/rust-libs/duniter-dbs-write-ops/src/lib.rs
+++ /dev/null
@@ -1,55 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-#![deny(
-    clippy::unwrap_used,
-    missing_copy_implementations,
-    trivial_casts,
-    trivial_numeric_casts,
-    unstable_features,
-    unused_import_braces
-)]
-
-pub mod apply_block;
-pub mod bc;
-pub mod cm;
-pub mod txs_mp;
-
-use std::borrow::Cow;
-
-use dubp::block::prelude::*;
-use dubp::common::crypto::hashs::Hash;
-use dubp::common::prelude::*;
-use dubp::documents::{
-    prelude::*, smallvec::SmallVec, transaction::TransactionDocumentTrait,
-    transaction::TransactionDocumentV10,
-};
-use dubp::wallet::prelude::*;
-use duniter_dbs::{
-    databases::{
-        bc_v2::BcV2Db,
-        txs_mp_v2::{TxsMpV2Db, TxsMpV2DbReadable, TxsMpV2DbWritable},
-    },
-    kv_typed::prelude::*,
-    BlockMetaV2, FileBackend, HashKeyV2, PendingTxDbV2, PubKeyKeyV2, PubKeyValV2, SharedDbs,
-    SourceAmountValV2, UtxoValV2, WalletConditionsV2,
-};
-use duniter_global::GlobalBackGroundTaskMsg;
-use resiter::filter_map::FilterMap;
-use resiter::flatten::Flatten;
-use resiter::map::Map;
-use std::ops::Deref;
-
-const ROLL_BACK_MAX: u32 = 100;
diff --git a/rust-libs/duniter-dbs-write-ops/src/txs_mp.rs b/rust-libs/duniter-dbs-write-ops/src/txs_mp.rs
deleted file mode 100644
index 7f9e51395..000000000
--- a/rust-libs/duniter-dbs-write-ops/src/txs_mp.rs
+++ /dev/null
@@ -1,225 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-pub fn apply_block<B: Backend>(
-    block_txs: &[TransactionDocumentV10],
-    txs_mp_db: &TxsMpV2Db<B>,
-) -> KvResult<()> {
-    for tx in block_txs {
-        // Remove tx from mempool
-        remove_one_pending_tx(&txs_mp_db, tx.get_hash())?;
-    }
-    Ok(())
-}
-
-pub fn revert_block<B: Backend>(
-    block_txs: &[TransactionDocumentV10],
-    txs_mp_db: &TxsMpV2Db<B>,
-) -> KvResult<()> {
-    for tx in block_txs {
-        // Rewrite tx on mempool
-        add_pending_tx(|_, _| Ok(()), txs_mp_db, Cow::Borrowed(tx))?;
-    }
-    Ok(())
-}
-
-pub fn add_pending_tx<
-    B: Backend,
-    F: FnOnce(
-        &TransactionDocumentV10,
-        &TxColRw<B::Col, duniter_dbs::databases::txs_mp_v2::TxsEvent>,
-    ) -> KvResult<()>,
->(
-    control: F,
-    txs_mp_db: &TxsMpV2Db<B>,
-    tx: Cow<TransactionDocumentV10>,
-) -> KvResult<()> {
-    let tx_hash = tx.get_hash();
-    let received_time = chrono::offset::Utc::now().timestamp();
-    (
-        txs_mp_db.txs_by_recv_time_write(),
-        txs_mp_db.txs_by_issuer_write(),
-        txs_mp_db.txs_by_recipient_write(),
-        txs_mp_db.txs_write(),
-        txs_mp_db.uds_ids_write(),
-        txs_mp_db.utxos_ids_write(),
-        txs_mp_db.outputs_by_script_write(),
-    )
-        .write(
-            |(
-                mut txs_by_recv_time,
-                mut txs_by_issuer,
-                mut txs_by_recipient,
-                mut txs,
-                mut uds_ids,
-                mut utxos_ids,
-                mut outputs_by_script,
-            )| {
-                control(&tx, &txs)?;
-                // Insert on col `txs_by_recv_time`
-                let mut hashs = txs_by_recv_time.get(&received_time)?.unwrap_or_default();
-                hashs.insert(tx_hash);
-                txs_by_recv_time.upsert(received_time, hashs);
-                // Insert on col `txs_by_issuer`
-                for pubkey in tx.issuers() {
-                    let mut hashs = txs_by_issuer.get(&PubKeyKeyV2(pubkey))?.unwrap_or_default();
-                    hashs.insert(tx.get_hash());
-                    txs_by_issuer.upsert(PubKeyKeyV2(pubkey), hashs);
-                }
-                // Insert on col `txs_by_recipient`
-                for pubkey in tx.recipients_keys() {
-                    let mut hashs = txs_by_recipient
-                        .get(&PubKeyKeyV2(pubkey))?
-                        .unwrap_or_default();
-                    hashs.insert(tx.get_hash());
-                    txs_by_recipient.upsert(PubKeyKeyV2(pubkey), hashs);
-                }
-                // Insert tx inputs in cols `uds_ids` and `utxos_ids`
-                for input in tx.get_inputs() {
-                    match input.id {
-                        SourceIdV10::Ud(UdSourceIdV10 {
-                            issuer,
-                            block_number,
-                        }) => uds_ids.upsert(duniter_dbs::UdIdV2(issuer, block_number), ()),
-                        SourceIdV10::Utxo(UtxoIdV10 {
-                            tx_hash,
-                            output_index,
-                        }) => utxos_ids
-                            .upsert(duniter_dbs::UtxoIdDbV2(tx_hash, output_index as u32), ()),
-                    }
-                }
-                // Insert tx outputs in col `outputs`
-                for (output_index, output) in tx.get_outputs().iter().enumerate() {
-                    let script = WalletConditionsV2(output.conditions.script.to_owned());
-                    let utxo = UtxoValV2::new(output.amount, tx_hash, output_index as u32);
-                    let mut script_outputs = outputs_by_script.get(&script)?.unwrap_or_default();
-                    script_outputs.insert(utxo);
-                    outputs_by_script.upsert(script, script_outputs);
-                }
-                // Insert tx itself
-                txs.upsert(HashKeyV2(tx_hash), PendingTxDbV2(tx.into_owned()));
-                Ok(())
-            },
-        )
-}
-
-pub fn remove_all_pending_txs<B: Backend>(txs_mp_db: &TxsMpV2Db<B>) -> KvResult<()> {
-    txs_mp_db.txs_by_recv_time_write().clear()?;
-    txs_mp_db.txs_by_issuer_write().clear()?;
-    txs_mp_db.txs_by_recipient_write().clear()?;
-    txs_mp_db.txs_write().clear()?;
-    txs_mp_db.uds_ids_write().clear()?;
-    txs_mp_db.utxos_ids_write().clear()?;
-
-    Ok(())
-}
-
-pub fn remove_pending_tx_by_hash<B: Backend>(txs_mp_db: &TxsMpV2Db<B>, hash: Hash) -> KvResult<()> {
-    remove_one_pending_tx(&txs_mp_db, hash)?;
-    Ok(())
-}
-
-pub fn trim_expired_non_written_txs<B: Backend>(
-    txs_mp_db: &TxsMpV2Db<B>,
-    limit_time: i64,
-) -> KvResult<()> {
-    // Get hashs of tx to remove and "times" to remove
-    let mut times = Vec::new();
-    let hashs = txs_mp_db.txs_by_recv_time().iter(..limit_time, |it| {
-        it.map_ok(|(k, v)| {
-            times.push(k);
-            v
-        })
-        .flatten_ok()
-        .collect::<KvResult<SmallVec<[Hash; 4]>>>()
-    })?;
-    // For each tx to remove
-    for (hash, time) in hashs.into_iter().zip(times.into_iter()) {
-        remove_one_pending_tx(&txs_mp_db, hash)?;
-        // Remove txs hashs in col `txs_by_recv_time`
-        txs_mp_db.txs_by_recv_time_write().remove(time)?;
-    }
-
-    Ok(())
-}
-
-fn remove_one_pending_tx<B: Backend>(txs_mp_db: &TxsMpV2Db<B>, tx_hash: Hash) -> KvResult<bool> {
-    if let Some(tx) = txs_mp_db.txs().get(&HashKeyV2(tx_hash))? {
-        (
-            txs_mp_db.txs_by_issuer_write(),
-            txs_mp_db.txs_by_recipient_write(),
-            txs_mp_db.txs_write(),
-            txs_mp_db.uds_ids_write(),
-            txs_mp_db.utxos_ids_write(),
-            txs_mp_db.outputs_by_script_write(),
-        )
-            .write(
-                |(
-                    mut txs_by_issuer,
-                    mut txs_by_recipient,
-                    mut txs,
-                    mut uds_ids,
-                    mut utxos_ids,
-                    mut outputs_by_script,
-                )| {
-                    // Remove tx inputs in cols `uds_ids` and `utxos_ids`
-                    for input in tx.0.get_inputs() {
-                        match input.id {
-                            SourceIdV10::Ud(UdSourceIdV10 {
-                                issuer,
-                                block_number,
-                            }) => uds_ids.remove(duniter_dbs::UdIdV2(issuer, block_number)),
-                            SourceIdV10::Utxo(UtxoIdV10 {
-                                tx_hash,
-                                output_index,
-                            }) => utxos_ids
-                                .remove(duniter_dbs::UtxoIdDbV2(tx_hash, output_index as u32)),
-                        }
-                    }
-                    // Remove tx hash in col `txs_by_issuer`
-                    for pubkey in tx.0.issuers() {
-                        let mut hashs_ =
-                            txs_by_issuer.get(&PubKeyKeyV2(pubkey))?.unwrap_or_default();
-                        hashs_.remove(&tx_hash);
-                        txs_by_issuer.upsert(PubKeyKeyV2(pubkey), hashs_)
-                    }
-                    // Remove tx hash in col `txs_by_recipient`
-                    for pubkey in tx.0.recipients_keys() {
-                        let mut hashs_ = txs_by_recipient
-                            .get(&PubKeyKeyV2(pubkey))?
-                            .unwrap_or_default();
-                        hashs_.remove(&tx_hash);
-                        txs_by_recipient.upsert(PubKeyKeyV2(pubkey), hashs_)
-                    }
-                    // Remove tx outputs in col `outputs`
-                    for (output_index, output) in tx.0.get_outputs().iter().enumerate() {
-                        let script = WalletConditionsV2(output.conditions.script.to_owned());
-                        let utxo = UtxoValV2::new(output.amount, tx_hash, output_index as u32);
-                        let mut script_outputs =
-                            outputs_by_script.get(&script)?.unwrap_or_default();
-                        script_outputs.remove(&utxo);
-                        outputs_by_script.upsert(script, script_outputs);
-                    }
-                    // Remove tx itself
-                    txs.remove(HashKeyV2(tx_hash));
-                    Ok(true)
-                },
-            )
-    } else {
-        Ok(false)
-    }
-}
diff --git a/rust-libs/duniter-dbs/Cargo.toml b/rust-libs/duniter-dbs/Cargo.toml
deleted file mode 100644
index 85437e4e2..000000000
--- a/rust-libs/duniter-dbs/Cargo.toml
+++ /dev/null
@@ -1,48 +0,0 @@
-[package]
-name = "duniter-dbs"
-version = "0.1.0"
-authors = ["elois <elois@duniter.org>"]
-description = "Duniter blockchain DB"
-repository = "https://git.duniter.org/nodes/typescript/duniter"
-keywords = ["dubp", "duniter", "blockchain", "database"]
-license = "AGPL-3.0"
-edition = "2018"
-
-[lib]
-path = "src/lib.rs"
-
-[dependencies]
-arrayvec = "0.5.1"
-bincode = "1.2.1"
-byteorder = "1.3.4"
-chrono = { version = "0.4.15", optional = true }
-dubp = { version = "0.51.0", features = ["duniter"] }
-kv_typed = { path = "../tools/kv_typed", default-features = false }
-log = "0.4.8"
-mockall = { version = "0.9.1", optional = true }
-parking_lot = "0.11.0"
-paste = "1.0.2"
-rand = "0.7.3"
-serde = { version = "1.0.105", features = ["derive"] }
-serde_json = "1.0.53"
-smallvec = { version = "1.4.0", features = ["serde", "write"] }
-thiserror = "1.0.20"
-uninit = "0.4.0"
-zerocopy = "0.3.0"
-
-[dev-dependencies]
-anyhow = "1.0.34"
-tempfile = "3.2.0"
-unwrap = "1.2.1"
-
-[features]
-default = ["sled_backend"]
-
-# CAUTION: feature "leveldb_backend" MUST BE DISABLED by default. Uncomment this line for dev/test only ! 
-#default = ["sled_backend", "explorer", "leveldb_backend"]
-
-explorer = ["chrono", "kv_typed/explorer"]
-leveldb_backend = ["kv_typed/leveldb_backend"]
-mem = []
-#mock = ["kv_typed/mock", "mockall"]
-sled_backend = ["kv_typed/sled_backend"]
diff --git a/rust-libs/duniter-dbs/src/databases.rs b/rust-libs/duniter-dbs/src/databases.rs
deleted file mode 100644
index 19792fc7c..000000000
--- a/rust-libs/duniter-dbs/src/databases.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-pub mod bc_v1;
-pub mod bc_v2;
-pub mod cm_v1;
-pub mod network_v1;
-pub mod txs_mp_v2;
diff --git a/rust-libs/duniter-dbs/src/databases/bc_v1.rs b/rust-libs/duniter-dbs/src/databases/bc_v1.rs
deleted file mode 100644
index bf01ede5e..000000000
--- a/rust-libs/duniter-dbs/src/databases/bc_v1.rs
+++ /dev/null
@@ -1,158 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-db_schema!(
-    BcV1,
-    [
-        ["level_blockchain", MainBlocks, BlockNumberKeyV1, BlockDbV1],
-        [
-            "level_blockchain/idty",
-            MbIdty,
-            PubKeyKeyV1,
-            BlockNumberArrayV1
-        ],
-        [
-            "level_blockchain/certs",
-            MbCerts,
-            PubKeyKeyV1,
-            BlockNumberArrayV1
-        ],
-        [
-            "level_blockchain/joiners",
-            MbJoiners,
-            PubKeyKeyV1,
-            BlockNumberArrayV1
-        ],
-        [
-            "level_blockchain/actives",
-            MbActives,
-            PubKeyKeyV1,
-            BlockNumberArrayV1
-        ],
-        [
-            "level_blockchain/leavers",
-            MbLeavers,
-            PubKeyKeyV1,
-            BlockNumberArrayV1
-        ],
-        [
-            "level_blockchain/excluded",
-            MbExcluded,
-            PubKeyKeyV1,
-            BlockNumberArrayV1
-        ],
-        [
-            "level_blockchain/revoked",
-            MbRevoked,
-            PubKeyAndSigV1,
-            BlockNumberArrayV1
-        ],
-        [
-            "level_blockchain/dividends",
-            MbDividends,
-            AllKeyV1,
-            BlockNumberArrayV1
-        ],
-        [
-            "level_blockchain/transactions",
-            MbTransactions,
-            AllKeyV1,
-            BlockNumberArrayV1
-        ],
-        [
-            "level_blockchain/forks",
-            ForkBlocks,
-            BlockstampKeyV1,
-            BlockDbV1
-        ],
-        ["level_bindex", Bindex, BlockNumberKeyV1, BlockHeadDbV1],
-        ["level_iindex", Iindex, PubKeyKeyV1, IIndexDbV1],
-        [
-            "level_iindex/hash",
-            IindexHash,
-            HashKeyV1,
-            PublicKeySingletonDbV1
-        ],
-        ["level_iindex/kick", IindexKick, PubKeyKeyV1, KickDbV1],
-        [
-            "level_iindex/writtenOn",
-            IindexWrittenOn,
-            BlockNumberKeyV1,
-            PublicKeyArrayDbV1
-        ],
-        ["level_iindex/uid", Uids, UidKeyV1, PublicKeySingletonDbV1],
-        ["level_mindex", Mindex, PubKeyKeyV1, MIndexDbV1],
-        [
-            "level_mindex/expiresOn",
-            MindexExpiresOn,
-            TimestampKeyV1,
-            PublicKeyArrayDbV1
-        ],
-        [
-            "level_mindex/revokesOn",
-            MindexRevokesOn,
-            TimestampKeyV1,
-            PublicKeyArrayDbV1
-        ],
-        [
-            "level_mindex/writtenOn",
-            MindexWrittenOn,
-            BlockNumberKeyV1,
-            PublicKeyArrayDbV1
-        ],
-        ["level_cindex", Cindex, PubKeyKeyV1, CIndexDbV1],
-        [
-            "level_cindex/expiresOn",
-            CindexExpiresOn,
-            BlockNumberKeyV1,
-            PublicKeyArrayDbV1
-        ],
-        [
-            "level_cindex/writtenOn",
-            CindexWrittenOn,
-            BlockNumberKeyV1,
-            PublicKeyArrayDbV1
-        ],
-        ["level_wallet", Wallet, WalletConditionsV1, WalletDbV1],
-        ["level_dividend", Uds, PubKeyKeyV1, UdEntryDbV1],
-        [
-            "level_dividend/level_dividend_trim_index",
-            UdsTrim,
-            BlockNumberKeyV1,
-            PublicKeyArrayDbV1
-        ],
-        ["level_sindex", Sindex, SourceKeyV1, SIndexDBV1],
-        [
-            "level_sindex/written_on",
-            SindexWrittenOn,
-            BlockNumberKeyV1,
-            SourceKeyArrayDbV1
-        ],
-        [
-            "level_sindex/consumed_on",
-            SindexConsumedOn,
-            BlockNumberKeyV1,
-            SourceKeyArrayDbV1
-        ],
-        [
-            "level_sindex/conditions",
-            SindexConditions,
-            WalletConditionsV1,
-            SourceKeyArrayDbV1
-        ],
-    ]
-);
diff --git a/rust-libs/duniter-dbs/src/databases/bc_v2.rs b/rust-libs/duniter-dbs/src/databases/bc_v2.rs
deleted file mode 100644
index c52560296..000000000
--- a/rust-libs/duniter-dbs/src/databases/bc_v2.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-db_schema!(
-    BcV2,
-    [
-        ["blocks_meta", BlocksMeta, U32BE, BlockMetaV2],
-        ["identities", Identities, PubKeyKeyV2, IdtyDbV2],
-        ["txs_hashs", TxsHashs, HashKeyV2, ()],
-        ["uds", Uds, UdIdV2, ()],
-        ["uds_reval", UdsReval, U32BE, SourceAmountValV2],
-        ["uids_index", UidsIndex, String, PubKeyValV2],
-        ["utxos", Utxos, UtxoIdDbV2, WalletScriptWithSourceAmountV1Db],
-        ["consumed_utxos", ConsumedUtxos, U32BE, BlockUtxosV2Db],
-    ]
-);
diff --git a/rust-libs/duniter-dbs/src/databases/cm_v1.rs b/rust-libs/duniter-dbs/src/databases/cm_v1.rs
deleted file mode 100644
index 4cea86827..000000000
--- a/rust-libs/duniter-dbs/src/databases/cm_v1.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-db_schema!(CmV1, [["current_block", CurrentBlock, (), BlockDbV2],]);
diff --git a/rust-libs/duniter-dbs/src/databases/network_v1.rs b/rust-libs/duniter-dbs/src/databases/network_v1.rs
deleted file mode 100644
index db55149ae..000000000
--- a/rust-libs/duniter-dbs/src/databases/network_v1.rs
+++ /dev/null
@@ -1,24 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-db_schema!(
-    NetworkV1,
-    [
-        ["heads_old", HeadsOld, DunpNodeIdV1Db, DunpHeadDbV1],
-        ["peers_old", PeersOld, PubKeyKeyV2, PeerCardDbV1],
-    ]
-);
diff --git a/rust-libs/duniter-dbs/src/databases/txs_mp_v2.rs b/rust-libs/duniter-dbs/src/databases/txs_mp_v2.rs
deleted file mode 100644
index e05532807..000000000
--- a/rust-libs/duniter-dbs/src/databases/txs_mp_v2.rs
+++ /dev/null
@@ -1,29 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-db_schema!(
-    TxsMpV2,
-    [
-        ["txs", Txs, HashKeyV2, PendingTxDbV2],
-        ["txs_by_issuer", TxsByIssuer, PubKeyKeyV2, BTreeSet<Hash>],
-        ["txs_by_recipient", TxsByRecipient, PubKeyKeyV2, BTreeSet<Hash>],
-        ["txs_by_received_time", TxsByRecvTime, i64, BTreeSet<Hash>],
-        ["uds_ids", UdsIds, UdIdV2, ()],
-        ["utxos_ids", UtxosIds, UtxoIdDbV2, ()],
-        ["outputs_by_script", OutputsByScript, WalletConditionsV2, BTreeSet<UtxoValV2>],
-    ]
-);
diff --git a/rust-libs/duniter-dbs/src/keys.rs b/rust-libs/duniter-dbs/src/keys.rs
deleted file mode 100644
index b5d2db16b..000000000
--- a/rust-libs/duniter-dbs/src/keys.rs
+++ /dev/null
@@ -1,28 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-pub mod all;
-pub mod block_number;
-pub mod blockstamp;
-pub mod dunp_node_id;
-pub mod hash;
-pub mod pubkey;
-pub mod pubkey_and_sig;
-pub mod source_key;
-pub mod timestamp;
-pub mod ud_id;
-pub mod uid;
-pub mod utxo_id;
-pub mod wallet_conditions;
diff --git a/rust-libs/duniter-dbs/src/keys/all.rs b/rust-libs/duniter-dbs/src/keys/all.rs
deleted file mode 100644
index 3515a52f5..000000000
--- a/rust-libs/duniter-dbs/src/keys/all.rs
+++ /dev/null
@@ -1,57 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd)]
-pub struct AllKeyV1;
-
-impl AsBytes for AllKeyV1 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        f(b"ALL")
-    }
-}
-
-impl kv_typed::prelude::FromBytes for AllKeyV1 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        if bytes == b"ALL" {
-            Ok(Self)
-        } else {
-            Err(CorruptedBytes(format!(
-                "Invalid key: expected '{:?}', found '{:?}'",
-                b"ALL", bytes
-            )))
-        }
-    }
-}
-
-impl ToDumpString for AllKeyV1 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableKey for AllKeyV1 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerKeyErr> {
-        <Self as kv_typed::prelude::FromBytes>::from_bytes(source.as_bytes())
-            .map_err(|e| FromExplorerKeyErr(e.0.into()))
-    }
-    fn to_explorer_string(&self) -> KvResult<String> {
-        self.as_bytes(|bytes| Ok(unsafe { std::str::from_utf8_unchecked(bytes) }.to_owned()))
-    }
-}
diff --git a/rust-libs/duniter-dbs/src/keys/block_number.rs b/rust-libs/duniter-dbs/src/keys/block_number.rs
deleted file mode 100644
index afd226849..000000000
--- a/rust-libs/duniter-dbs/src/keys/block_number.rs
+++ /dev/null
@@ -1,72 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd)]
-pub struct BlockNumberKeyV1(pub BlockNumber);
-
-impl AsBytes for BlockNumberKeyV1 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        if self.0 == BlockNumber(u32::MAX) {
-            f(b"0000000NaN")
-        } else {
-            f(format!("{:010}", (self.0).0).as_bytes())
-        }
-    }
-}
-
-impl FromBytes for BlockNumberKeyV1 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        let key_str = std::str::from_utf8(bytes).map_err(|e| CorruptedBytes(e.to_string()))?;
-        if key_str == "0000000NaN" {
-            Ok(BlockNumberKeyV1(BlockNumber(u32::MAX)))
-        } else {
-            Ok(BlockNumberKeyV1(BlockNumber(key_str.parse().map_err(
-                |e| CorruptedBytes(format!("{}: {}", e, key_str)),
-            )?)))
-        }
-    }
-}
-
-impl ToDumpString for BlockNumberKeyV1 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableKey for BlockNumberKeyV1 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerKeyErr> {
-        Self::from_bytes(source.as_bytes()).map_err(|e| FromExplorerKeyErr(e.0.into()))
-    }
-    fn to_explorer_string(&self) -> KvResult<String> {
-        Ok(format!("{}", (self.0).0))
-    }
-}
-
-#[cfg(test)]
-mod tests {
-
-    use super::*;
-
-    #[test]
-    fn test_block_number_str_10_ser() {
-        BlockNumberKeyV1(BlockNumber(35))
-            .as_bytes(|bytes| assert_eq!(bytes, &[48, 48, 48, 48, 48, 48, 48, 48, 51, 53]))
-    }
-}
diff --git a/rust-libs/duniter-dbs/src/keys/blockstamp.rs b/rust-libs/duniter-dbs/src/keys/blockstamp.rs
deleted file mode 100644
index 6b4a8df39..000000000
--- a/rust-libs/duniter-dbs/src/keys/blockstamp.rs
+++ /dev/null
@@ -1,100 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd)]
-pub struct BlockstampKeyV1(Blockstamp);
-
-impl AsBytes for BlockstampKeyV1 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        f(format!("{:010}-{}", self.0.number.0, self.0.hash).as_bytes())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for BlockstampKeyV1 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        let blockstamp_strs: ArrayVec<[&str; 2]> = std::str::from_utf8(bytes)
-            .map_err(|e| CorruptedBytes(e.to_string()))?
-            .split('-')
-            .collect();
-        let block_number = blockstamp_strs[0]
-            .parse()
-            .map_err(|e: ParseIntError| CorruptedBytes(e.to_string()))?;
-        let block_hash =
-            Hash::from_hex(blockstamp_strs[1]).map_err(|e| CorruptedBytes(e.to_string()))?;
-        Ok(BlockstampKeyV1(Blockstamp {
-            number: BlockNumber(block_number),
-            hash: BlockHash(block_hash),
-        }))
-    }
-}
-
-impl ToDumpString for BlockstampKeyV1 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableKey for BlockstampKeyV1 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerKeyErr> {
-        Self::from_bytes(source.as_bytes()).map_err(|e| FromExplorerKeyErr(e.0.into()))
-    }
-    fn to_explorer_string(&self) -> KvResult<String> {
-        Ok(format!("{}", self.0))
-    }
-}
-
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd)]
-pub struct BlockstampKeyV2(Blockstamp);
-
-impl AsBytes for BlockstampKeyV2 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        let bytes: [u8; 36] = self.0.into();
-        f(&bytes[..])
-    }
-}
-
-impl kv_typed::prelude::FromBytes for BlockstampKeyV2 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        use dubp::common::bytes_traits::FromBytes as _;
-        Ok(Self(
-            Blockstamp::from_bytes(bytes).map_err(|e| CorruptedBytes(e.to_string()))?,
-        ))
-    }
-}
-
-impl ToDumpString for BlockstampKeyV2 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableKey for BlockstampKeyV2 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerKeyErr> {
-        Ok(Self(
-            Blockstamp::from_str(source).map_err(|e| FromExplorerKeyErr(e.into()))?,
-        ))
-    }
-    fn to_explorer_string(&self) -> KvResult<String> {
-        Ok(format!("{}", self.0))
-    }
-}
diff --git a/rust-libs/duniter-dbs/src/keys/dunp_node_id.rs b/rust-libs/duniter-dbs/src/keys/dunp_node_id.rs
deleted file mode 100644
index 31e232d41..000000000
--- a/rust-libs/duniter-dbs/src/keys/dunp_node_id.rs
+++ /dev/null
@@ -1,111 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-use std::fmt::Display;
-use uninit::prelude::*;
-
-#[derive(
-    Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, zerocopy::AsBytes, zerocopy::FromBytes,
-)]
-#[repr(transparent)]
-pub struct DunpNodeIdV1Db([u8; 37]); // uuid ++ pubkey
-
-impl DunpNodeIdV1Db {
-    pub fn new(uuid: u32, pubkey: PublicKey) -> Self {
-        let mut buffer = uninit_array![u8; 37];
-        let (pubkey_buffer, uuid_buffer) = buffer.as_out().split_at_out(33);
-
-        pubkey_buffer.copy_from_slice(pubkey.as_ref());
-        uuid_buffer.copy_from_slice(&uuid.to_be_bytes()[..]);
-
-        Self(unsafe { std::mem::transmute(buffer) })
-    }
-    pub fn get_uuid(&self) -> u32 {
-        let mut buffer = uninit_array![u8; 4];
-
-        buffer.as_out().copy_from_slice(&self.0[33..]);
-
-        u32::from_be_bytes(unsafe { std::mem::transmute(buffer) })
-    }
-    pub fn get_pubkey(&self) -> PublicKey {
-        let mut buffer = uninit_array![u8; 33];
-
-        buffer.as_out().copy_from_slice(&self.0[..33]);
-        let bytes: [u8; 33] = unsafe { std::mem::transmute(buffer) };
-
-        PublicKey::try_from(&bytes[..]).unwrap_or_else(|_| unreachable!())
-    }
-}
-
-impl Default for DunpNodeIdV1Db {
-    fn default() -> Self {
-        DunpNodeIdV1Db([0u8; 37])
-    }
-}
-
-impl Display for DunpNodeIdV1Db {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(f, "{:x}-{}", self.get_uuid(), self.get_pubkey())
-    }
-}
-
-impl AsBytes for DunpNodeIdV1Db {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        f(self.0.as_ref())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for DunpNodeIdV1Db {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        let layout = zerocopy::LayoutVerified::<_, DunpNodeIdV1Db>::new(bytes)
-            .ok_or_else(|| CorruptedBytes("corrupted db".to_owned()))?;
-        Ok(*layout)
-    }
-}
-
-impl ToDumpString for DunpNodeIdV1Db {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableKey for DunpNodeIdV1Db {
-    fn from_explorer_str(_: &str) -> std::result::Result<Self, FromExplorerKeyErr> {
-        unimplemented!()
-    }
-    fn to_explorer_string(&self) -> KvResult<String> {
-        Ok(self.to_string())
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn test_serde() {
-        let node_id = DunpNodeIdV1Db::new(42, PublicKey::default());
-        assert_eq!(node_id.get_uuid(), 42);
-        assert_eq!(node_id.get_pubkey(), PublicKey::default());
-        let mut node_id_ = DunpNodeIdV1Db([0u8; 37]);
-        node_id_.0[32] = 32;
-        node_id_.0[36] = 42;
-        assert_eq!(node_id_, node_id)
-    }
-}
diff --git a/rust-libs/duniter-dbs/src/keys/hash.rs b/rust-libs/duniter-dbs/src/keys/hash.rs
deleted file mode 100644
index c223810c7..000000000
--- a/rust-libs/duniter-dbs/src/keys/hash.rs
+++ /dev/null
@@ -1,106 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd)]
-pub struct HashKeyV1(pub Hash);
-
-impl AsBytes for HashKeyV1 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        f(self.0.to_hex().as_bytes())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for HashKeyV1 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        let hash_str = std::str::from_utf8(bytes).map_err(|e| CorruptedBytes(e.to_string()))?;
-        Ok(HashKeyV1(
-            Hash::from_hex(&hash_str).map_err(|e| CorruptedBytes(e.to_string()))?,
-        ))
-    }
-}
-
-impl ToDumpString for HashKeyV1 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableKey for HashKeyV1 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerKeyErr> {
-        Self::from_bytes(source.as_bytes()).map_err(|e| FromExplorerKeyErr(e.0.into()))
-    }
-    fn to_explorer_string(&self) -> KvResult<String> {
-        self.as_bytes(|bytes| Ok(unsafe { std::str::from_utf8_unchecked(bytes) }.to_owned()))
-    }
-}
-
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd)]
-#[repr(transparent)]
-pub struct HashKeyV2(pub Hash);
-
-impl HashKeyV2 {
-    pub fn from_ref(hash: &Hash) -> &Self {
-        #[allow(trivial_casts)]
-        unsafe {
-            &*(hash as *const Hash as *const HashKeyV2)
-        }
-    }
-}
-
-impl AsBytes for HashKeyV2 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        f(self.0.as_ref())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for HashKeyV2 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        if bytes.len() != 32 {
-            Err(CorruptedBytes(format!(
-                "Invalid length: expected 32 found {}",
-                bytes.len()
-            )))
-        } else {
-            let mut buffer = [0u8; 32];
-            buffer.copy_from_slice(bytes);
-            Ok(HashKeyV2(Hash(buffer)))
-        }
-    }
-}
-
-impl ToDumpString for HashKeyV2 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableKey for HashKeyV2 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerKeyErr> {
-        Ok(Self(
-            Hash::from_hex(source).map_err(|e| FromExplorerKeyErr(e.into()))?,
-        ))
-    }
-    fn to_explorer_string(&self) -> KvResult<String> {
-        Ok(self.0.to_hex())
-    }
-}
diff --git a/rust-libs/duniter-dbs/src/keys/pubkey.rs b/rust-libs/duniter-dbs/src/keys/pubkey.rs
deleted file mode 100644
index 7441f5130..000000000
--- a/rust-libs/duniter-dbs/src/keys/pubkey.rs
+++ /dev/null
@@ -1,117 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd)]
-pub struct PubKeyKeyV1(pub PublicKey);
-
-impl PubKeyKeyV1 {
-    const ALL: &'static str = "ALL";
-    const ALL_WITH_LEADING_1: &'static str = "11111111111111111111111111111ALL";
-
-    pub fn all() -> Self {
-        Self(PublicKey::from_base58(Self::ALL).expect("invalid PubKeyKeyV1::all()"))
-    }
-}
-
-impl AsBytes for PubKeyKeyV1 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        let b58_string = self.0.to_base58();
-        if b58_string == Self::ALL_WITH_LEADING_1 {
-            f(Self::ALL.as_bytes())
-        } else {
-            f(self.0.to_base58().as_bytes())
-        }
-    }
-}
-
-impl kv_typed::prelude::FromBytes for PubKeyKeyV1 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        let pubkey_str = std::str::from_utf8(bytes).map_err(|e| CorruptedBytes(e.to_string()))?;
-        Ok(PubKeyKeyV1(PublicKey::from_base58(&pubkey_str).map_err(
-            |e| CorruptedBytes(format!("{}: {}", e, pubkey_str)),
-        )?))
-    }
-}
-
-impl ToDumpString for PubKeyKeyV1 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd)]
-pub struct PubKeyKeyV2(pub PublicKey);
-
-impl AsBytes for PubKeyKeyV2 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        f(self.0.as_ref())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for PubKeyKeyV2 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        Ok(PubKeyKeyV2(PublicKey::try_from(bytes).map_err(|e| {
-            CorruptedBytes(format!("{}: {:?}", e, bytes))
-        })?))
-    }
-}
-
-impl ToDumpString for PubKeyKeyV2 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableKey for PubKeyKeyV1 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerKeyErr> {
-        Self::from_bytes(source.as_bytes()).map_err(|e| FromExplorerKeyErr(e.0.into()))
-    }
-    fn to_explorer_string(&self) -> KvResult<String> {
-        self.as_bytes(|bytes| Ok(unsafe { std::str::from_utf8_unchecked(bytes) }.to_owned()))
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableKey for PubKeyKeyV2 {
-    fn from_explorer_str(pubkey_str: &str) -> std::result::Result<Self, FromExplorerKeyErr> {
-        Ok(PubKeyKeyV2(PublicKey::from_base58(&pubkey_str).map_err(
-            |e| FromExplorerKeyErr(format!("{}: {}", e, pubkey_str).into()),
-        )?))
-    }
-    fn to_explorer_string(&self) -> KvResult<String> {
-        Ok(self.0.to_base58())
-    }
-}
-
-#[cfg(test)]
-mod tests {
-
-    use super::*;
-    #[test]
-    fn pubkey_all() {
-        let all = PubKeyKeyV1::all();
-        assert_eq!(
-            all.as_bytes(|bytes| bytes.to_vec()),
-            PubKeyKeyV1::ALL.as_bytes()
-        )
-    }
-}
diff --git a/rust-libs/duniter-dbs/src/keys/pubkey_and_sig.rs b/rust-libs/duniter-dbs/src/keys/pubkey_and_sig.rs
deleted file mode 100644
index 47a14c90c..000000000
--- a/rust-libs/duniter-dbs/src/keys/pubkey_and_sig.rs
+++ /dev/null
@@ -1,69 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-pub struct PubKeyAndSigV1(PublicKey, Signature);
-
-impl PubKeyAndSigV1 {
-    pub fn all() -> Self {
-        Self(PublicKey::default(), Signature([0u8; 64]))
-    }
-}
-
-impl AsBytes for PubKeyAndSigV1 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        if self == &Self::all() {
-            f(b"ALL")
-        } else {
-            f(format!("{}:{}", self.0.to_base58(), self.1.to_base64()).as_bytes())
-        }
-    }
-}
-
-impl kv_typed::prelude::FromBytes for PubKeyAndSigV1 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        let raw_str = std::str::from_utf8(bytes).map_err(|e| CorruptedBytes(e.to_string()))?;
-        if raw_str == "ALL" {
-            Ok(PubKeyAndSigV1::all())
-        } else {
-            let array_str: ArrayVec<[&str; 2]> = raw_str.split(':').collect();
-            let pubkey =
-                PublicKey::from_base58(array_str[0]).map_err(|e| CorruptedBytes(e.to_string()))?;
-            let sig =
-                Signature::from_base64(array_str[1]).map_err(|e| CorruptedBytes(e.to_string()))?;
-            Ok(PubKeyAndSigV1(pubkey, sig))
-        }
-    }
-}
-
-impl ToDumpString for PubKeyAndSigV1 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableKey for PubKeyAndSigV1 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerKeyErr> {
-        Self::from_bytes(source.as_bytes()).map_err(|e| FromExplorerKeyErr(e.0.into()))
-    }
-    fn to_explorer_string(&self) -> KvResult<String> {
-        self.as_bytes(|bytes| Ok(unsafe { std::str::from_utf8_unchecked(bytes) }.to_owned()))
-    }
-}
diff --git a/rust-libs/duniter-dbs/src/keys/source_key.rs b/rust-libs/duniter-dbs/src/keys/source_key.rs
deleted file mode 100644
index accb5c9a9..000000000
--- a/rust-libs/duniter-dbs/src/keys/source_key.rs
+++ /dev/null
@@ -1,93 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, PartialOrd, Serialize)]
-pub struct SourceKeyV1 {
-    pub tx_hash: Hash,
-    pub pos: u32,
-    pub consumed: Option<bool>,
-}
-
-impl ToString for SourceKeyV1 {
-    fn to_string(&self) -> String {
-        format!(
-            "{}-{:010}{}",
-            self.tx_hash,
-            self.pos,
-            match self.consumed {
-                Some(true) => "-1",
-                Some(false) => "-0",
-                None => "",
-            }
-        )
-    }
-}
-
-impl AsBytes for SourceKeyV1 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        f(self.to_string().as_bytes())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for SourceKeyV1 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        let strs: ArrayVec<[&str; 3]> = std::str::from_utf8(bytes)
-            .map_err(|e| CorruptedBytes(e.to_string()))?
-            .split('-')
-            .collect();
-        let tx_hash = Hash::from_hex(strs[0]).map_err(|e| CorruptedBytes(e.to_string()))?;
-        let pos = strs[1]
-            .parse()
-            .map_err(|e: ParseIntError| CorruptedBytes(e.to_string()))?;
-        let consumed = if strs.len() <= 2 {
-            None
-        } else {
-            match strs[2] {
-                "1" => Some(true),
-                "0" => Some(false),
-                _ => {
-                    return Err(CorruptedBytes(
-                        "invalid format: field consumed must be encoded with '0' or '1'".to_owned(),
-                    ))
-                }
-            }
-        };
-        Ok(SourceKeyV1 {
-            tx_hash,
-            pos,
-            consumed,
-        })
-    }
-}
-
-impl ToDumpString for SourceKeyV1 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableKey for SourceKeyV1 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerKeyErr> {
-        Self::from_bytes(source.as_bytes()).map_err(|e| FromExplorerKeyErr(e.0.into()))
-    }
-    fn to_explorer_string(&self) -> KvResult<String> {
-        self.as_bytes(|bytes| Ok(unsafe { std::str::from_utf8_unchecked(bytes) }.to_owned()))
-    }
-}
diff --git a/rust-libs/duniter-dbs/src/keys/timestamp.rs b/rust-libs/duniter-dbs/src/keys/timestamp.rs
deleted file mode 100644
index 96a6cb8ce..000000000
--- a/rust-libs/duniter-dbs/src/keys/timestamp.rs
+++ /dev/null
@@ -1,56 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd)]
-pub struct TimestampKeyV1(pub u64);
-
-impl AsBytes for TimestampKeyV1 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        f(format!("{}", self.0).as_bytes())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for TimestampKeyV1 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        let key_str = std::str::from_utf8(bytes).map_err(|e| CorruptedBytes(e.to_string()))?;
-        Ok(TimestampKeyV1(key_str.parse().map_err(|e| {
-            CorruptedBytes(format!("{}: {}", e, key_str))
-        })?))
-    }
-}
-
-impl ToDumpString for TimestampKeyV1 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableKey for TimestampKeyV1 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerKeyErr> {
-        NaiveDateTime::parse_from_str(source, "%Y-%m-%d %H:%M:%S")
-            .map(|dt| TimestampKeyV1(dt.timestamp() as u64))
-            .map_err(|e| FromExplorerKeyErr(format!("{}: {}", e, source).into()))
-    }
-    fn to_explorer_string(&self) -> KvResult<String> {
-        Ok(NaiveDateTime::from_timestamp(self.0 as i64, 0)
-            .format("%Y-%m-%d %H:%M:%S")
-            .to_string())
-    }
-}
diff --git a/rust-libs/duniter-dbs/src/keys/ud_id.rs b/rust-libs/duniter-dbs/src/keys/ud_id.rs
deleted file mode 100644
index a1e3b24ce..000000000
--- a/rust-libs/duniter-dbs/src/keys/ud_id.rs
+++ /dev/null
@@ -1,123 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-use uninit::prelude::*;
-
-#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
-pub struct UdIdV2(pub PublicKey, pub BlockNumber);
-
-impl PartialOrd for UdIdV2 {
-    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
-        match self.0.partial_cmp(&other.0) {
-            Some(std::cmp::Ordering::Equal) => self.1.partial_cmp(&other.1),
-            o => o,
-        }
-    }
-}
-impl Ord for UdIdV2 {
-    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
-        match self.0.cmp(&other.0) {
-            std::cmp::Ordering::Equal => self.1.cmp(&other.1),
-            o => o,
-        }
-    }
-}
-
-impl AsBytes for UdIdV2 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        let mut buffer = uninit_array![u8; 37];
-        let (pubkey_buffer, block_number_buffer) = buffer.as_out().split_at_out(33);
-        let pubkey_buffer = pubkey_buffer.copy_from_slice(self.0.as_ref());
-        block_number_buffer.copy_from_slice(&(self.1).0.to_be_bytes());
-        f(unsafe { std::slice::from_raw_parts_mut(pubkey_buffer.as_mut_ptr(), 37) })
-    }
-}
-
-impl FromBytes for UdIdV2 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        let pubkey = PublicKey::try_from(&bytes[..33])
-            .map_err(|e| CorruptedBytes(format!("{}: {:?}", e, bytes)))?;
-        let block_number = BlockNumber(
-            zerocopy::LayoutVerified::<_, zerocopy::U32<byteorder::BigEndian>>::new(&bytes[33..])
-                .ok_or_else(|| {
-                    CorruptedBytes(
-                        "Corrupted DB: BlockNumber bytes are invalid length or unaligned"
-                            .to_owned(),
-                    )
-                })?
-                .get(),
-        );
-        Ok(UdIdV2(pubkey, block_number))
-    }
-}
-
-impl ToDumpString for UdIdV2 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableKey for UdIdV2 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerKeyErr> {
-        let mut source = source.split(':');
-        if let Some(pubkey_str) = source.next() {
-            let pubkey = PublicKey::from_base58(&pubkey_str)
-                .map_err(|e| FromExplorerKeyErr(format!("{}: {}", e, pubkey_str).into()))?;
-            if let Some(block_number_str) = source.next() {
-                Ok(UdIdV2(
-                    pubkey,
-                    BlockNumber::from_str(block_number_str)
-                        .map_err(|e| FromExplorerKeyErr(e.into()))?,
-                ))
-            } else {
-                Err(FromExplorerKeyErr("UdIdV2: Invalid format".into()))
-            }
-        } else {
-            Err(FromExplorerKeyErr("UdIdV2: Invalid format".into()))
-        }
-    }
-    fn to_explorer_string(&self) -> KvResult<String> {
-        Ok(format!("{}:{}", self.0.to_base58(), (self.1).0))
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn ud_id_v2_as_bytes() -> anyhow::Result<()> {
-        let ud_id = UdIdV2(PublicKey::default(), BlockNumber(3));
-
-        let ud_id_2_res = ud_id.as_bytes(|bytes| {
-            assert_eq!(
-                bytes,
-                [
-                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                    0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 3
-                ]
-            );
-            UdIdV2::from_bytes(bytes)
-        });
-
-        assert_eq!(ud_id_2_res?, ud_id);
-
-        Ok(())
-    }
-}
diff --git a/rust-libs/duniter-dbs/src/keys/uid.rs b/rust-libs/duniter-dbs/src/keys/uid.rs
deleted file mode 100644
index a5e4bd7dd..000000000
--- a/rust-libs/duniter-dbs/src/keys/uid.rs
+++ /dev/null
@@ -1,65 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-const USERNAME_MAX_LEN: usize = 100;
-
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd)]
-pub struct UidKeyV1(pub ArrayString<[u8; USERNAME_MAX_LEN]>);
-
-impl AsBytes for UidKeyV1 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        f(self.0.as_str().as_bytes())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for UidKeyV1 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        let uid_str = std::str::from_utf8(bytes).map_err(|e| CorruptedBytes(e.to_string()))?;
-        Ok(Self(
-            ArrayString::<[u8; USERNAME_MAX_LEN]>::from_str(uid_str)
-                .map_err(|e| CorruptedBytes(e.to_string()))?,
-        ))
-    }
-}
-
-impl FromStr for UidKeyV1 {
-    type Err = arrayvec::CapacityError;
-
-    fn from_str(source: &str) -> std::result::Result<Self, Self::Err> {
-        Ok(UidKeyV1(ArrayString::<[u8; USERNAME_MAX_LEN]>::from_str(
-            source,
-        )?))
-    }
-}
-
-impl ToDumpString for UidKeyV1 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableKey for UidKeyV1 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerKeyErr> {
-        Self::from_bytes(source.as_bytes()).map_err(|e| FromExplorerKeyErr(e.0.into()))
-    }
-    fn to_explorer_string(&self) -> KvResult<String> {
-        self.as_bytes(|bytes| Ok(unsafe { std::str::from_utf8_unchecked(bytes) }.to_owned()))
-    }
-}
diff --git a/rust-libs/duniter-dbs/src/keys/utxo_id.rs b/rust-libs/duniter-dbs/src/keys/utxo_id.rs
deleted file mode 100644
index ca57bf0cb..000000000
--- a/rust-libs/duniter-dbs/src/keys/utxo_id.rs
+++ /dev/null
@@ -1,124 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-use uninit::prelude::*;
-
-type OutputIndex = u32;
-
-#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
-pub struct UtxoIdDbV2(pub Hash, pub OutputIndex);
-
-impl PartialOrd for UtxoIdDbV2 {
-    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
-        match self.0.partial_cmp(&other.0) {
-            Some(std::cmp::Ordering::Equal) => self.1.partial_cmp(&other.1),
-            o => o,
-        }
-    }
-}
-impl Ord for UtxoIdDbV2 {
-    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
-        match self.0.cmp(&other.0) {
-            std::cmp::Ordering::Equal => self.1.cmp(&other.1),
-            o => o,
-        }
-    }
-}
-
-impl AsBytes for UtxoIdDbV2 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        let mut buffer = uninit_array![u8; 36];
-        let (hash_buffer, index_buffer) = buffer.as_out().split_at_out(32);
-        let hash_buffer = hash_buffer.copy_from_slice(self.0.as_ref());
-        index_buffer.copy_from_slice(&(self.1).to_be_bytes());
-        f(unsafe { std::slice::from_raw_parts_mut(hash_buffer.as_mut_ptr(), 36) })
-    }
-}
-
-impl FromBytes for UtxoIdDbV2 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        let hash = zerocopy::LayoutVerified::<_, Hash>::new(&bytes[..32]).ok_or_else(|| {
-            CorruptedBytes("Corrupted DB: Hash bytes are invalid length or unaligned".to_owned())
-        })?;
-        let output_index =
-            zerocopy::LayoutVerified::<_, zerocopy::U32<byteorder::BigEndian>>::new(&bytes[32..])
-                .ok_or_else(|| {
-                    CorruptedBytes(
-                        "Corrupted DB: OutputIndex bytes are invalid length or unaligned"
-                            .to_owned(),
-                    )
-                })?
-                .get();
-        Ok(UtxoIdDbV2(*hash, output_index))
-    }
-}
-
-impl ToDumpString for UtxoIdDbV2 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableKey for UtxoIdDbV2 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerKeyErr> {
-        let mut source = source.split(':');
-        if let Some(hash_str) = source.next() {
-            let hash = Hash::from_hex(&hash_str)
-                .map_err(|e| FromExplorerKeyErr(format!("{}: {}", e, hash_str).into()))?;
-            if let Some(output_index_str) = source.next() {
-                Ok(UtxoIdDbV2(
-                    hash,
-                    u32::from_str(output_index_str).map_err(|e| FromExplorerKeyErr(e.into()))?,
-                ))
-            } else {
-                Err(FromExplorerKeyErr("UtxoIdDbV2: Invalid format".into()))
-            }
-        } else {
-            Err(FromExplorerKeyErr("UtxoIdDbV2: Invalid format".into()))
-        }
-    }
-    fn to_explorer_string(&self) -> KvResult<String> {
-        Ok(format!("{}:{}", self.0.to_hex(), self.1))
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn utxo_id_v2_as_bytes() -> anyhow::Result<()> {
-        let utxo_id = UtxoIdDbV2(Hash::default(), 3);
-
-        let utxo_id_2_res = utxo_id.as_bytes(|bytes| {
-            assert_eq!(
-                bytes,
-                [
-                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                    0, 0, 0, 0, 0, 0, 0, 0, 0, 3
-                ]
-            );
-            UtxoIdDbV2::from_bytes(bytes)
-        });
-
-        assert_eq!(utxo_id_2_res?, utxo_id);
-
-        Ok(())
-    }
-}
diff --git a/rust-libs/duniter-dbs/src/keys/wallet_conditions.rs b/rust-libs/duniter-dbs/src/keys/wallet_conditions.rs
deleted file mode 100644
index 56af52a2a..000000000
--- a/rust-libs/duniter-dbs/src/keys/wallet_conditions.rs
+++ /dev/null
@@ -1,112 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-const CONDITIONS_MAX_LEN: usize = 256;
-
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd)]
-pub struct WalletConditionsV1(pub ArrayString<[u8; CONDITIONS_MAX_LEN]>);
-
-impl AsBytes for WalletConditionsV1 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        f(self.0.as_str().as_bytes())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for WalletConditionsV1 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        let uid_str = std::str::from_utf8(bytes).map_err(|e| CorruptedBytes(e.to_string()))?;
-        Ok(Self(
-            ArrayString::<[u8; CONDITIONS_MAX_LEN]>::from_str(uid_str)
-                .map_err(|e| CorruptedBytes(e.to_string()))?,
-        ))
-    }
-}
-
-impl FromStr for WalletConditionsV1 {
-    type Err = arrayvec::CapacityError;
-
-    fn from_str(source: &str) -> std::result::Result<Self, Self::Err> {
-        Ok(WalletConditionsV1(
-            ArrayString::<[u8; CONDITIONS_MAX_LEN]>::from_str(source)?,
-        ))
-    }
-}
-
-impl ToDumpString for WalletConditionsV1 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableKey for WalletConditionsV1 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerKeyErr> {
-        Self::from_bytes(source.as_bytes()).map_err(|e| FromExplorerKeyErr(e.0.into()))
-    }
-    fn to_explorer_string(&self) -> KvResult<String> {
-        self.as_bytes(|bytes| Ok(unsafe { std::str::from_utf8_unchecked(bytes) }.to_owned()))
-    }
-}
-
-#[derive(Clone, Debug, Eq, Hash, PartialEq)]
-pub struct WalletConditionsV2(pub WalletScriptV10);
-
-impl WalletConditionsV2 {
-    pub fn from_ref(script: &WalletScriptV10) -> &Self {
-        #[allow(trivial_casts)]
-        unsafe {
-            &*(script as *const WalletScriptV10 as *const WalletConditionsV2)
-        }
-    }
-}
-
-impl AsBytes for WalletConditionsV2 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        let mut buffer = SmallVec::<[u8; 256]>::new();
-        bincode::serialize_into(&mut buffer, &self.0).unwrap_or_else(|_| unreachable!());
-        f(buffer.as_ref())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for WalletConditionsV2 {
-    type Err = bincode::Error;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        Ok(Self(bincode::deserialize(bytes)?))
-    }
-}
-
-impl ToDumpString for WalletConditionsV2 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableKey for WalletConditionsV2 {
-    fn from_explorer_str(s: &str) -> std::result::Result<Self, FromExplorerKeyErr> {
-        Ok(Self(
-            dubp::documents_parser::wallet_script_from_str(s)
-                .map_err(|e| FromExplorerKeyErr(e.into()))?,
-        ))
-    }
-    fn to_explorer_string(&self) -> KvResult<String> {
-        Ok(self.0.to_string())
-    }
-}
diff --git a/rust-libs/duniter-dbs/src/lib.rs b/rust-libs/duniter-dbs/src/lib.rs
deleted file mode 100644
index 63d8a82ad..000000000
--- a/rust-libs/duniter-dbs/src/lib.rs
+++ /dev/null
@@ -1,144 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-#![allow(clippy::upper_case_acronyms)]
-#![deny(
-    clippy::unwrap_used,
-    missing_copy_implementations,
-    trivial_casts,
-    trivial_numeric_casts,
-    unstable_features,
-    unused_import_braces
-)]
-
-pub mod databases;
-mod keys;
-mod open_dbs;
-mod values;
-
-// Re-export dependencies
-pub use arrayvec;
-#[cfg(feature = "explorer")]
-pub use kv_typed::regex;
-pub use serde;
-pub use serde_json;
-pub use smallvec;
-
-// Re-export crates
-pub use kv_typed;
-
-// Prelude
-pub mod prelude {
-    pub use crate::open_dbs::BackendConf;
-    pub use crate::SharedDbs;
-    #[cfg(feature = "explorer")]
-    pub use kv_typed::explorer::{
-        DbExplorable, EntryFound, ExplorerAction, ExplorerActionResponse, ValueCaptures,
-    };
-}
-
-// Export technical types and functions
-pub use crate::open_dbs::open_dbs;
-
-// Export profession types
-pub use crate::keys::utxo_id::UtxoIdDbV2;
-pub use keys::all::AllKeyV1;
-pub use keys::block_number::BlockNumberKeyV1;
-pub use keys::blockstamp::{BlockstampKeyV1, BlockstampKeyV2};
-pub use keys::dunp_node_id::DunpNodeIdV1Db;
-pub use keys::hash::{HashKeyV1, HashKeyV2};
-pub use keys::pubkey::{PubKeyKeyV1, PubKeyKeyV2};
-pub use keys::pubkey_and_sig::PubKeyAndSigV1;
-pub use keys::source_key::SourceKeyV1;
-pub use keys::timestamp::TimestampKeyV1;
-pub use keys::ud_id::UdIdV2;
-pub use keys::uid::UidKeyV1;
-pub use keys::wallet_conditions::{WalletConditionsV1, WalletConditionsV2};
-pub use values::block_db::{BlockDbEnum, BlockDbV1, BlockDbV2, TransactionInBlockDbV1};
-pub use values::block_head_db::BlockHeadDbV1;
-pub use values::block_meta::BlockMetaV2;
-pub use values::block_number_array_db::BlockNumberArrayV1;
-pub use values::cindex_db::CIndexDbV1;
-pub use values::dunp_head::DunpHeadDbV1;
-pub use values::idty_db::IdtyDbV2;
-pub use values::iindex_db::IIndexDbV1;
-pub use values::kick_db::KickDbV1;
-pub use values::mindex_db::MIndexDbV1;
-pub use values::peer_card::PeerCardDbV1;
-pub use values::pubkey_db::{PubKeyValV2, PublicKeyArrayDbV1, PublicKeySingletonDbV1};
-pub use values::sindex_db::{SIndexDBV1, SourceKeyArrayDbV1};
-pub use values::source_amount::SourceAmountValV2;
-pub use values::tx_db::PendingTxDbV2;
-pub use values::txs::BlockTxsDbV2;
-pub use values::ud_entry_db::{ConsumedUdDbV1, UdAmountDbV1, UdEntryDbV1};
-pub use values::utxo::{BlockUtxosV2Db, UtxoValV2};
-pub use values::wallet_db::WalletDbV1;
-pub use values::wallet_script_with_sa::WalletScriptWithSourceAmountV1Db;
-
-// Crate imports
-pub(crate) use arrayvec::{ArrayString, ArrayVec};
-#[cfg(feature = "explorer")]
-use chrono::NaiveDateTime;
-pub(crate) use dubp::common::crypto::bases::b58::ToBase58 as _;
-pub(crate) use dubp::common::crypto::bases::BaseConversionError;
-pub(crate) use dubp::common::crypto::hashs::Hash;
-pub(crate) use dubp::common::crypto::keys::ed25519::{PublicKey, Signature};
-pub(crate) use dubp::common::crypto::keys::{PublicKey as _, Signature as _};
-pub(crate) use dubp::common::prelude::*;
-pub(crate) use dubp::documents::dubp_wallet::prelude::*;
-pub(crate) use kv_typed::db_schema;
-pub(crate) use kv_typed::prelude::*;
-pub(crate) use serde::{Deserialize, Serialize};
-pub(crate) use smallvec::SmallVec;
-pub(crate) use std::{
-    collections::BTreeSet, convert::TryFrom, fmt::Debug, iter::Iterator, num::ParseIntError,
-    path::Path, str::FromStr,
-};
-
-#[derive(Debug, Error)]
-#[error("{0}")]
-pub struct CorruptedBytes(pub String);
-
-pub trait ToDumpString {
-    fn to_dump_string(&self) -> String;
-}
-
-#[cfg(all(not(feature = "mem"), not(test)))]
-pub type FileBackend = kv_typed::backend::sled::Sled;
-#[cfg(any(feature = "mem", test))]
-pub type FileBackend = kv_typed::backend::memory::Mem;
-
-#[derive(Clone, Debug)]
-pub struct SharedDbs<B: Backend> {
-    pub bc_db_ro: databases::bc_v2::BcV2DbRo<B>,
-    pub cm_db: databases::cm_v1::CmV1Db<MemSingleton>,
-    pub dunp_db: databases::network_v1::NetworkV1Db<B>,
-    pub txs_mp_db: databases::txs_mp_v2::TxsMpV2Db<B>,
-}
-
-impl SharedDbs<Mem> {
-    pub fn mem() -> KvResult<Self> {
-        use databases::bc_v2::BcV2DbWritable as _;
-        use databases::cm_v1::CmV1DbWritable as _;
-        use databases::network_v1::NetworkV1DbWritable as _;
-        use databases::txs_mp_v2::TxsMpV2DbWritable as _;
-        Ok(SharedDbs {
-            bc_db_ro: databases::bc_v2::BcV2Db::<Mem>::open(MemConf::default())?.get_ro_handler(),
-            cm_db: databases::cm_v1::CmV1Db::<MemSingleton>::open(MemSingletonConf::default())?,
-            dunp_db: databases::network_v1::NetworkV1Db::<Mem>::open(MemConf::default())?,
-            txs_mp_db: databases::txs_mp_v2::TxsMpV2Db::<Mem>::open(MemConf::default())?,
-        })
-    }
-}
diff --git a/rust-libs/duniter-dbs/src/open_dbs.rs b/rust-libs/duniter-dbs/src/open_dbs.rs
deleted file mode 100644
index 05f1ffd1b..000000000
--- a/rust-libs/duniter-dbs/src/open_dbs.rs
+++ /dev/null
@@ -1,109 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::databases::bc_v2::BcV2DbWritable as _;
-use crate::databases::cm_v1::CmV1DbWritable as _;
-use crate::databases::network_v1::NetworkV1DbWritable as _;
-use crate::databases::txs_mp_v2::TxsMpV2DbWritable as _;
-use crate::*;
-
-pub fn open_dbs<B: BackendConf>(
-    profile_path_opt: Option<&Path>,
-) -> KvResult<(crate::databases::bc_v2::BcV2Db<B>, SharedDbs<B>)> {
-    let bc_db = crate::databases::bc_v2::BcV2Db::<B>::open(B::gen_backend_conf(
-        crate::databases::bc_v2::BcV2Db::<B>::NAME,
-        profile_path_opt,
-    ))?;
-    let dbs = SharedDbs {
-        bc_db_ro: bc_db.get_ro_handler(),
-        cm_db: crate::databases::cm_v1::CmV1Db::<MemSingleton>::open(MemSingletonConf::default())
-            .expect("fail to open CmV1 DB"),
-        dunp_db: crate::databases::network_v1::NetworkV1Db::<B>::open(B::gen_backend_conf(
-            "dunp_v1",
-            profile_path_opt,
-        ))?,
-        txs_mp_db: crate::databases::txs_mp_v2::TxsMpV2Db::<B>::open(B::gen_backend_conf(
-            crate::databases::txs_mp_v2::TxsMpV2Db::<B>::NAME,
-            profile_path_opt,
-        ))?,
-    };
-    Ok((bc_db, dbs))
-}
-
-pub trait BackendConf: Backend {
-    fn gen_backend_conf(
-        db_name: &'static str,
-        profile_path_opt: Option<&Path>,
-    ) -> <Self as Backend>::Conf;
-}
-
-impl BackendConf for Mem {
-    #[inline(always)]
-    fn gen_backend_conf(_db_name: &'static str, _profile_path_opt: Option<&Path>) -> MemConf {
-        MemConf::default()
-    }
-}
-
-/*impl BackendConf for Lmdb {
-    #[inline(always)]
-    fn gen_backend_conf(db_name: &'static str, profile_path_opt: Option<&Path>) -> LmdbConf {
-        let conf = LmdbConf::default();
-        if let Some(data_path) = profile_path_opt {
-            conf.folder_path(data_path.join(format!("data/{}_lmdb", db_name)))
-        } else {
-            let random = rand::random::<u128>();
-            conf.folder_path(PathBuf::from(format!(
-                "/dev/shm/duniter/_{}/{}_lmdb",
-                random, db_name
-            )))
-            .temporary(true)
-        }
-    }
-}*/
-
-impl BackendConf for Sled {
-    #[inline(always)]
-    fn gen_backend_conf(db_name: &'static str, profile_path_opt: Option<&Path>) -> SledConf {
-        let mut conf = SledConf::default().flush_every_ms(Some(10_000));
-        conf = match db_name {
-            "bc_v2" => {
-                if let Ok(compression_level) = std::env::var("DUNITER_BC_DB_COMPRESSION") {
-                    conf.use_compression(true)
-                        .compression_factor(i32::from_str(&compression_level).expect(
-                        "Env var DUNITER_BC_DB_COMPRESSION must be a number beetween 1 and 22 !",
-                    ))
-                } else {
-                    conf.use_compression(false)
-                }
-            }
-            "gva_v1" => {
-                if let Ok(compression_level) = std::env::var("DUNITER_GVA_DB_COMPRESSION") {
-                    conf.use_compression(true)
-                        .compression_factor(i32::from_str(&compression_level).expect(
-                        "Env var DUNITER_GVA_DB_COMPRESSION must be a number beetween 1 and 22 !",
-                    ))
-                } else {
-                    conf.use_compression(false)
-                }
-            }
-            _ => conf.use_compression(false),
-        };
-        if let Some(data_path) = profile_path_opt {
-            conf.path(data_path.join(format!("data/{}_sled", db_name)))
-        } else {
-            conf.temporary(true)
-        }
-    }
-}
diff --git a/rust-libs/duniter-dbs/src/values.rs b/rust-libs/duniter-dbs/src/values.rs
deleted file mode 100644
index a77cb7fd2..000000000
--- a/rust-libs/duniter-dbs/src/values.rs
+++ /dev/null
@@ -1,35 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-pub mod block_db;
-pub mod block_head_db;
-pub mod block_meta;
-pub mod block_number_array_db;
-pub mod cindex_db;
-pub mod dunp_head;
-pub mod idty_db;
-pub mod iindex_db;
-pub mod kick_db;
-pub mod mindex_db;
-pub mod peer_card;
-pub mod pubkey_db;
-pub mod sindex_db;
-pub mod source_amount;
-pub mod tx_db;
-pub mod txs;
-pub mod ud_entry_db;
-pub mod utxo;
-pub mod wallet_db;
-pub mod wallet_script_with_sa;
diff --git a/rust-libs/duniter-dbs/src/values/block_db.rs b/rust-libs/duniter-dbs/src/values/block_db.rs
deleted file mode 100644
index c288cda97..000000000
--- a/rust-libs/duniter-dbs/src/values/block_db.rs
+++ /dev/null
@@ -1,152 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Debug)]
-pub enum BlockDbEnum {
-    BlockDbV1(BlockDbV1),
-}
-
-#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
-#[serde(rename_all = "camelCase")]
-pub struct BlockDbV1 {
-    pub version: u64,
-    pub number: u64,
-    pub currency: String,
-    pub hash: String,
-    pub signature: String,
-    #[serde(rename = "inner_hash")]
-    pub inner_hash: String,
-    pub previous_hash: Option<String>,
-    pub issuer: String,
-    pub previous_issuer: Option<String>,
-    pub time: u64,
-    pub pow_min: u64,
-    #[serde(rename = "unitbase")]
-    pub unit_base: u64,
-    pub members_count: u64,
-    pub issuers_count: u64,
-    pub issuers_frame: u64,
-    pub issuers_frame_var: i64,
-    pub identities: Vec<String>,
-    pub joiners: Vec<String>,
-    pub actives: Vec<String>,
-    pub leavers: Vec<String>,
-    pub revoked: Vec<String>,
-    pub excluded: Vec<String>,
-    pub certifications: Vec<String>,
-    pub transactions: Vec<TransactionInBlockDbV1>,
-    pub median_time: u64,
-    pub nonce: u64,
-    pub fork: bool,
-    pub parameters: String,
-    pub monetary_mass: u64,
-    pub dividend: Option<u64>,
-    #[serde(rename = "UDTime")]
-    pub ud_time: Option<u64>,
-    #[serde(rename = "writtenOn")]
-    pub written_on: Option<u64>,
-    #[serde(rename = "written_on")]
-    pub written_on_str: String,
-    pub wrong: bool,
-}
-
-impl AsBytes for BlockDbV1 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        let json = serde_json::to_string(self).expect("unreachable");
-        f(json.as_bytes())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for BlockDbV1 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        let json_str = std::str::from_utf8(bytes).expect("corrupted db : invalid utf8 bytes");
-        serde_json::from_str(&json_str)
-            .map_err(|e| CorruptedBytes(format!("{}: '{}'", e, json_str)))
-    }
-}
-
-impl ToDumpString for BlockDbV1 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableValue for BlockDbV1 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerValueErr> {
-        Self::from_bytes(source.as_bytes()).map_err(|e| FromExplorerValueErr(e.0.into()))
-    }
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        serde_json::to_value(self).map_err(|e| KvError::DeserError(e.into()))
-    }
-}
-
-#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
-#[serde(rename_all = "camelCase")]
-pub struct TransactionInBlockDbV1 {
-    version: u64,
-    currency: String,
-    #[serde(rename = "locktime")]
-    lock_time: u64,
-    hash: Option<String>,
-    blockstamp: String,
-    blockstamp_time: u64,
-    issuers: SmallVec<[String; 1]>,
-    inputs: SmallVec<[String; 4]>,
-    outputs: SmallVec<[String; 2]>,
-    unlocks: SmallVec<[String; 4]>,
-    signatures: SmallVec<[String; 1]>,
-    comment: String,
-}
-
-// V2
-
-#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
-pub struct BlockDbV2(pub dubp::block::DubpBlockV10);
-
-impl AsBytes for BlockDbV2 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        let bytes = bincode::serialize(self).unwrap_or_else(|_| unreachable!());
-        f(bytes.as_ref())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for BlockDbV2 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        bincode::deserialize(&bytes).map_err(|e| CorruptedBytes(format!("{}: '{:?}'", e, bytes)))
-    }
-}
-
-impl ToDumpString for BlockDbV2 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableValue for BlockDbV2 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerValueErr> {
-        serde_json::from_str(source).map_err(|e| FromExplorerValueErr(e.into()))
-    }
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        serde_json::to_value(self).map_err(|e| KvError::DeserError(e.into()))
-    }
-}
diff --git a/rust-libs/duniter-dbs/src/values/block_head_db.rs b/rust-libs/duniter-dbs/src/values/block_head_db.rs
deleted file mode 100644
index 97c3f6a04..000000000
--- a/rust-libs/duniter-dbs/src/values/block_head_db.rs
+++ /dev/null
@@ -1,85 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
-#[serde(rename_all = "camelCase")]
-pub struct BlockHeadDbV1 {
-    pub version: u64,
-    pub currency: Option<String>,
-    #[serde(rename = "bsize")]
-    pub block_size: u64,
-    pub avg_block_size: u64,
-    pub ud_time: u64,
-    pub ud_reeval_time: u64,
-    pub mass_reeval: u64,
-    pub mass: u64,
-    pub hash: String,
-    pub previous_hash: Option<String>,
-    pub previous_issuer: Option<String>,
-    pub issuer: String,
-    pub time: u64,
-    pub median_time: u64,
-    pub number: u64,
-    pub pow_min: u64,
-    pub diff_number: u64,
-    pub issuers_count: u64,
-    pub issuers_frame: u64,
-    pub issuers_frame_var: i64,
-    pub issuer_diff: u64,
-    pub pow_zeros: u64,
-    pub pow_remainder: u64,
-    pub speed: f64,
-    pub unit_base: u64,
-    pub members_count: u64,
-    pub dividend: u64,
-    #[serde(rename = "new_dividend")]
-    pub new_dividend: Option<u64>,
-    pub issuer_is_member: bool,
-}
-
-impl AsBytes for BlockHeadDbV1 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        let json = serde_json::to_string(self).unwrap_or_else(|_| unreachable!());
-        f(json.as_bytes())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for BlockHeadDbV1 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        let json_str = std::str::from_utf8(bytes).expect("corrupted db : invalid utf8 bytes");
-        serde_json::from_str(&json_str)
-            .map_err(|e| CorruptedBytes(format!("{}: '{}'", e, json_str)))
-    }
-}
-
-impl ToDumpString for BlockHeadDbV1 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableValue for BlockHeadDbV1 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerValueErr> {
-        Self::from_bytes(source.as_bytes()).map_err(|e| FromExplorerValueErr(e.0.into()))
-    }
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        serde_json::to_value(self).map_err(|e| KvError::DeserError(e.into()))
-    }
-}
diff --git a/rust-libs/duniter-dbs/src/values/block_meta.rs b/rust-libs/duniter-dbs/src/values/block_meta.rs
deleted file mode 100644
index 949a644d9..000000000
--- a/rust-libs/duniter-dbs/src/values/block_meta.rs
+++ /dev/null
@@ -1,133 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use dubp::block::DubpBlockV10;
-
-use crate::*;
-
-const BLOCK_META_SERIALIZED_SIZE: usize = 323;
-
-#[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize)]
-pub struct BlockMetaV2 {
-    pub version: u64,                   // 8
-    pub number: u32,                    // 4
-    pub hash: Hash,                     // 32
-    pub signature: Signature,           // 64
-    pub inner_hash: Hash,               // 32
-    pub previous_hash: Hash,            // 32
-    pub issuer: PublicKey,              // 33
-    pub previous_issuer: PublicKey,     // 33
-    pub time: u64,                      // 8
-    pub pow_min: u32,                   // 4
-    pub members_count: u64,             // 8
-    pub issuers_count: u32,             // 4
-    pub issuers_frame: u64,             // 8
-    pub issuers_frame_var: i64,         // 8
-    pub median_time: u64,               // 8
-    pub nonce: u64,                     // 8
-    pub monetary_mass: u64,             // 8
-    pub unit_base: u32,                 // 4
-    pub dividend: Option<SourceAmount>, // 17 -> TOTAL SIZE == 335 bytes
-}
-impl BlockMetaV2 {
-    pub fn blockstamp(&self) -> Blockstamp {
-        Blockstamp {
-            number: BlockNumber(self.number),
-            hash: BlockHash(self.hash),
-        }
-    }
-}
-
-impl AsBytes for BlockMetaV2 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        let mut buffer = [0u8; BLOCK_META_SERIALIZED_SIZE];
-        bincode::serialize_into(&mut buffer[..], self).unwrap_or_else(|_| unreachable!());
-        f(buffer.as_ref())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for BlockMetaV2 {
-    type Err = bincode::Error;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        bincode::deserialize(bytes)
-    }
-}
-
-impl ToDumpString for BlockMetaV2 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableValue for BlockMetaV2 {
-    fn from_explorer_str(json_str: &str) -> std::result::Result<Self, FromExplorerValueErr> {
-        serde_json::from_str(&json_str)
-            .map_err(|e| FromExplorerValueErr(format!("{}: '{}'", e, json_str).into()))
-    }
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        serde_json::to_value(self).map_err(|e| KvError::DeserError(e.into()))
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use unwrap::unwrap;
-
-    #[test]
-    fn block_meta_v2_as_bytes() {
-        assert_eq!(
-            unwrap!(bincode::serialized_size(&BlockMetaV2 {
-                dividend: Some(SourceAmount::new(42, 0)),
-                ..Default::default()
-            })),
-            BLOCK_META_SERIALIZED_SIZE as u64
-        );
-        let bloc_meta = BlockMetaV2::default();
-
-        let bm2_res = bloc_meta.as_bytes(|bytes| unwrap!(BlockMetaV2::from_bytes(bytes)));
-
-        assert_eq!(bm2_res, bloc_meta);
-    }
-}
-
-impl From<&DubpBlockV10> for BlockMetaV2 {
-    fn from(block: &DubpBlockV10) -> Self {
-        use dubp::block::prelude::DubpBlockTrait;
-        BlockMetaV2 {
-            version: 10,
-            number: block.number().0,
-            hash: block.hash().0,
-            signature: block.signature(),
-            inner_hash: block.inner_hash(),
-            previous_hash: block.previous_hash(),
-            issuer: block.issuer(),
-            previous_issuer: PublicKey::default(),
-            time: block.local_time(),
-            pow_min: block.pow_min() as u32,
-            members_count: block.members_count() as u64,
-            issuers_count: block.issuers_count() as u32,
-            issuers_frame: block.issuers_frame() as u64,
-            issuers_frame_var: 0,
-            median_time: block.common_time(),
-            nonce: block.nonce(),
-            monetary_mass: block.monetary_mass(),
-            dividend: block.dividend(),
-            unit_base: block.unit_base() as u32,
-        }
-    }
-}
diff --git a/rust-libs/duniter-dbs/src/values/block_number_array_db.rs b/rust-libs/duniter-dbs/src/values/block_number_array_db.rs
deleted file mode 100644
index e4b5f0c36..000000000
--- a/rust-libs/duniter-dbs/src/values/block_number_array_db.rs
+++ /dev/null
@@ -1,53 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
-pub struct BlockNumberArrayV1(pub SmallVec<[BlockNumber; 1]>);
-
-impl AsBytes for BlockNumberArrayV1 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        let json_string = serde_json::to_string(self).unwrap_or_else(|_| unreachable!());
-        f(format!("[{}]", json_string).as_bytes())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for BlockNumberArrayV1 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        let json_str = std::str::from_utf8(bytes).expect("corrupted db : invalid utf8 bytes");
-        //println!("json_str='{}'", &json_str);
-        serde_json::from_str(&json_str)
-            .map_err(|e| CorruptedBytes(format!("{}: '{}'", e, json_str)))
-    }
-}
-
-impl ToDumpString for BlockNumberArrayV1 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableValue for BlockNumberArrayV1 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerValueErr> {
-        Self::from_bytes(source.as_bytes()).map_err(|e| FromExplorerValueErr(e.0.into()))
-    }
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        serde_json::to_value(self).map_err(|e| KvError::DeserError(e.into()))
-    }
-}
diff --git a/rust-libs/duniter-dbs/src/values/cindex_db.rs b/rust-libs/duniter-dbs/src/values/cindex_db.rs
deleted file mode 100644
index ded4657e5..000000000
--- a/rust-libs/duniter-dbs/src/values/cindex_db.rs
+++ /dev/null
@@ -1,98 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
-pub struct CIndexDbV1 {
-    pub received: SmallVec<[String; 10]>,
-    pub issued: Vec<CIndexLineDbV1>,
-}
-
-impl AsBytes for CIndexDbV1 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        let json_string = serde_json::to_string(self).unwrap_or_else(|_| unreachable!());
-        f(format!("[{}]", json_string).as_bytes())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for CIndexDbV1 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        let json_str = std::str::from_utf8(bytes).expect("corrupted db : invalid utf8 bytes");
-        //println!("json_str='{}'", &json_str);
-        serde_json::from_str(&json_str)
-            .map_err(|e| CorruptedBytes(format!("{}: '{}'", e, json_str)))
-    }
-}
-
-impl ToDumpString for CIndexDbV1 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableValue for CIndexDbV1 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerValueErr> {
-        Self::from_bytes(source.as_bytes()).map_err(|e| FromExplorerValueErr(e.0.into()))
-    }
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        serde_json::to_value(self).map_err(|e| KvError::DeserError(e.into()))
-    }
-}
-
-#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
-#[serde(rename_all = "camelCase")]
-pub struct CIndexLineDbV1 {
-    pub op: String,
-    #[serde(rename = "writtenOn")]
-    pub written_on: Option<u64>,
-    #[serde(rename = "written_on")]
-    pub written_on_str: String,
-    pub issuer: String,
-    pub receiver: String,
-    #[serde(rename = "created_on")]
-    pub created_on: u64,
-    pub sig: Option<String>,
-    #[serde(rename = "chainable_on")]
-    pub chainable_on: Option<u64>,
-    #[serde(rename = "replayable_on")]
-    pub replayable_on: Option<u64>,
-    #[serde(rename = "expires_on")]
-    pub expires_on: Option<u64>,
-    #[serde(rename = "expired_on")]
-    pub expired_on: u64,
-    pub unchainables: Option<u64>,
-    pub age: Option<u64>,
-    pub stock: Option<u64>,
-    pub from_member: Option<bool>,
-    pub to_member: Option<bool>,
-    pub to_newcomer: Option<bool>,
-    pub to_leaver: Option<bool>,
-    pub is_replay: Option<bool>,
-    pub is_replayable: Option<bool>,
-    #[serde(rename = "sigOK")]
-    pub sig_ok: Option<bool>,
-    #[serde(rename = "created_on_ref")]
-    pub created_on_ref: Option<CreatedOnRef>,
-}
-
-#[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize)]
-#[serde(rename_all = "camelCase")]
-pub struct CreatedOnRef {
-    pub median_time: u64,
-}
diff --git a/rust-libs/duniter-dbs/src/values/dunp_head.rs b/rust-libs/duniter-dbs/src/values/dunp_head.rs
deleted file mode 100644
index bf42b21a4..000000000
--- a/rust-libs/duniter-dbs/src/values/dunp_head.rs
+++ /dev/null
@@ -1,124 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
-pub struct DunpHeadDbV1 {
-    pub api: String,
-    pub pubkey: PublicKey,
-    pub blockstamp: Blockstamp,
-    pub software: String,
-    pub software_version: String,
-    pub pow_prefix: u32,
-    pub free_member_room: u32,
-    pub free_mirror_room: u32,
-    pub signature: Signature,
-}
-
-impl DunpHeadDbV1 {
-    pub fn from_stringified(message_v2: &str, signature: &str) -> KvResult<(DunpNodeIdV1Db, Self)> {
-        let signature =
-            Signature::from_base64(signature).map_err(|e| KvError::DeserError(e.into()))?;
-
-        let strs: SmallVec<[&str; 11]> = message_v2.split(':').collect();
-        if strs.len() < 11 {
-            return Err(KvError::DeserError(
-                "DunpHeadDbV1::from_stringified(): invalid message_v2".into(),
-            ));
-        }
-
-        let uuid = u32::from_str_radix(strs[5], 16).map_err(|e| KvError::DeserError(e.into()))?;
-        let pubkey = PublicKey::from_base58(strs[3]).map_err(|e| KvError::DeserError(e.into()))?;
-        let blockstamp =
-            Blockstamp::from_str(strs[4]).map_err(|e| KvError::DeserError(e.into()))?;
-
-        Ok((
-            DunpNodeIdV1Db::new(uuid, pubkey),
-            DunpHeadDbV1 {
-                api: strs[0].to_owned(),
-                pubkey,
-                blockstamp,
-                software: strs[6].to_owned(),
-                software_version: strs[7].to_owned(),
-                pow_prefix: u32::from_str(strs[8]).map_err(|e| KvError::DeserError(e.into()))?,
-                free_member_room: u32::from_str(strs[9])
-                    .map_err(|e| KvError::DeserError(e.into()))?,
-                free_mirror_room: u32::from_str(strs[10])
-                    .map_err(|e| KvError::DeserError(e.into()))?,
-                signature,
-            },
-        ))
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn test_dunp_head_from_stringified() -> KvResult<()> {
-        let message = "WS2POCAIC:HEAD:2:GX1nYVburxeaVP1SCNuhVKwNy6M2h6wPamHhyoSF4Ccn:379783-0000001BB2B88D077605C1330CA60AA222624FAA3BA60566D6CA51A9122376F7:882a5ad1:duniter:1.8.1:1:1:1";
-        let sig = "qBvJ7JZ4i8tKeItmZ/lurzr5O2/jKnB1reoIjEIl5x6sqbAhVsVsHut85yQoP30tURGfVX5FwMhCuC4DvCSFCg==";
-        let (node_id, head) = DunpHeadDbV1::from_stringified(message, sig)?;
-
-        assert_eq!(&format!("{:x}", node_id.get_uuid()), "882a5ad1");
-        assert_eq!(
-            &node_id.get_pubkey().to_string(),
-            "GX1nYVburxeaVP1SCNuhVKwNy6M2h6wPamHhyoSF4Ccn"
-        );
-        assert_eq!(&head.api, "WS2POCAIC");
-        assert_eq!(
-            &head.pubkey.to_string(),
-            "GX1nYVburxeaVP1SCNuhVKwNy6M2h6wPamHhyoSF4Ccn"
-        );
-        assert_eq!(
-            &head.blockstamp.to_string(),
-            "379783-0000001BB2B88D077605C1330CA60AA222624FAA3BA60566D6CA51A9122376F7"
-        );
-        Ok(())
-    }
-}
-
-impl AsBytes for DunpHeadDbV1 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        let bytes = bincode::serialize(self).unwrap_or_else(|_| unreachable!());
-        f(bytes.as_ref())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for DunpHeadDbV1 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        bincode::deserialize(&bytes).map_err(|e| CorruptedBytes(format!("{}: '{:?}'", e, bytes)))
-    }
-}
-
-impl ToDumpString for DunpHeadDbV1 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableValue for DunpHeadDbV1 {
-    fn from_explorer_str(_source: &str) -> std::result::Result<Self, FromExplorerValueErr> {
-        unimplemented!()
-    }
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        serde_json::to_value(self).map_err(|e| KvError::DeserError(e.into()))
-    }
-}
diff --git a/rust-libs/duniter-dbs/src/values/idty_db.rs b/rust-libs/duniter-dbs/src/values/idty_db.rs
deleted file mode 100644
index 504f79950..000000000
--- a/rust-libs/duniter-dbs/src/values/idty_db.rs
+++ /dev/null
@@ -1,52 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
-pub struct IdtyDbV2 {
-    pub is_member: bool,
-    pub username: String,
-}
-
-impl AsBytes for IdtyDbV2 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        f(&bincode::serialize(&self).unwrap_or_else(|_| unreachable!()))
-    }
-}
-
-impl kv_typed::prelude::FromBytes for IdtyDbV2 {
-    type Err = bincode::Error;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        bincode::deserialize(bytes)
-    }
-}
-
-impl ToDumpString for IdtyDbV2 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableValue for IdtyDbV2 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerValueErr> {
-        serde_json::from_str(source).map_err(|e| FromExplorerValueErr(e.into()))
-    }
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        serde_json::to_value(&self).map_err(|e| KvError::DeserError(e.into()))
-    }
-}
diff --git a/rust-libs/duniter-dbs/src/values/iindex_db.rs b/rust-libs/duniter-dbs/src/values/iindex_db.rs
deleted file mode 100644
index 947494fbd..000000000
--- a/rust-libs/duniter-dbs/src/values/iindex_db.rs
+++ /dev/null
@@ -1,81 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
-pub struct IIndexDbV1(pub SmallVec<[IIndexLineDbV1; 1]>);
-
-impl AsBytes for IIndexDbV1 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        let json_string = serde_json::to_string(self).unwrap_or_else(|_| unreachable!());
-        f(format!("[{}]", json_string).as_bytes())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for IIndexDbV1 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        let json_str = std::str::from_utf8(bytes).expect("corrupted db : invalid utf8 bytes");
-        //println!("json_str='{}'", &json_str);
-        serde_json::from_str(&json_str)
-            .map_err(|e| CorruptedBytes(format!("{}: '{}'", e, json_str)))
-    }
-}
-
-impl ToDumpString for IIndexDbV1 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableValue for IIndexDbV1 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerValueErr> {
-        Self::from_bytes(source.as_bytes()).map_err(|e| FromExplorerValueErr(e.0.into()))
-    }
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        serde_json::to_value(self).map_err(|e| KvError::DeserError(e.into()))
-    }
-}
-
-#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
-#[serde(rename_all = "camelCase")]
-pub struct IIndexLineDbV1 {
-    pub op: String,
-    #[serde(rename = "writtenOn")]
-    pub written_on: Option<u64>,
-    #[serde(rename = "written_on")]
-    pub written_on_str: String,
-    pub uid: Option<String>,
-    #[serde(rename = "pub")]
-    pub pubkey: String,
-    pub hash: Option<String>,
-    pub sig: Option<String>,
-    #[serde(rename = "created_on")]
-    pub created_on: Option<String>,
-    pub member: Option<bool>,
-    pub was_member: Option<bool>,
-    pub kick: Option<bool>,
-    #[serde(rename = "wotb_id")]
-    pub wotb_id: Option<usize>,
-    pub age: Option<u64>,
-    pub pub_unique: Option<bool>,
-    pub excluded_is_member: Option<bool>,
-    pub is_being_kicked: Option<bool>,
-    pub uid_unique: Option<bool>,
-    pub has_to_be_excluded: Option<bool>,
-}
diff --git a/rust-libs/duniter-dbs/src/values/kick_db.rs b/rust-libs/duniter-dbs/src/values/kick_db.rs
deleted file mode 100644
index b616cdc75..000000000
--- a/rust-libs/duniter-dbs/src/values/kick_db.rs
+++ /dev/null
@@ -1,55 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
-pub struct KickDbV1 {
-    on: Option<u64>,          // The next time that the identity must be kicked
-    done: SmallVec<[u64; 4]>, // The reversion history
-}
-
-impl AsBytes for KickDbV1 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        let json = serde_json::to_string(self).unwrap_or_else(|_| unreachable!());
-        f(json.as_bytes())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for KickDbV1 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        let json_str = std::str::from_utf8(bytes).expect("corrupted db : invalid utf8 bytes");
-        serde_json::from_str(&json_str)
-            .map_err(|e| CorruptedBytes(format!("{}: '{}'", e, json_str)))
-    }
-}
-
-impl ToDumpString for KickDbV1 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableValue for KickDbV1 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerValueErr> {
-        Self::from_bytes(source.as_bytes()).map_err(|e| FromExplorerValueErr(e.0.into()))
-    }
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        serde_json::to_value(self).map_err(|e| KvError::DeserError(e.into()))
-    }
-}
diff --git a/rust-libs/duniter-dbs/src/values/mindex_db.rs b/rust-libs/duniter-dbs/src/values/mindex_db.rs
deleted file mode 100644
index eb7d42a35..000000000
--- a/rust-libs/duniter-dbs/src/values/mindex_db.rs
+++ /dev/null
@@ -1,105 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
-pub struct MIndexDbV1(pub SmallVec<[MIndexLineDbV1; 1]>);
-
-impl AsBytes for MIndexDbV1 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        let json_string = serde_json::to_string(self).unwrap_or_else(|_| unreachable!());
-        f(format!("[{}]", json_string).as_bytes())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for MIndexDbV1 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        let json_str = std::str::from_utf8(bytes).expect("corrupted db : invalid utf8 bytes");
-        //println!("json_str='{}'", &json_str);
-        serde_json::from_str(&json_str)
-            .map_err(|e| CorruptedBytes(format!("{}: '{}'", e, json_str)))
-    }
-}
-
-impl ToDumpString for MIndexDbV1 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableValue for MIndexDbV1 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerValueErr> {
-        Self::from_bytes(source.as_bytes()).map_err(|e| FromExplorerValueErr(e.0.into()))
-    }
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        serde_json::to_value(self).map_err(|e| KvError::DeserError(e.into()))
-    }
-}
-
-#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
-#[serde(rename_all = "camelCase")]
-pub struct MIndexLineDbV1 {
-    pub op: String,
-    #[serde(rename = "writtenOn")]
-    pub written_on: Option<u64>,
-    #[serde(rename = "written_on")]
-    pub written_on_str: String,
-    #[serde(rename = "pub")]
-    pub pubkey: String,
-    pub created_on: Option<String>,
-    #[serde(rename = "type")]
-    pub r#type: Option<String>,
-    #[serde(rename = "expires_on")]
-    pub expires_on: Option<u64>,
-    #[serde(rename = "expired_on")]
-    pub expired_on: Option<u64>,
-    pub revocation: Option<String>,
-    #[serde(rename = "revokes_on")]
-    pub revokes_on: Option<u64>,
-    #[serde(rename = "chainable_on")]
-    pub chainable_on: Option<u64>,
-    #[serde(rename = "revoked_on")]
-    pub revoked_on: Option<String>,
-    pub leaving: Option<bool>,
-    pub age: Option<u64>,
-    pub is_being_revoked: Option<bool>,
-    pub unchainables: Option<u64>,
-    pub number_following: Option<bool>,
-    #[serde(rename = "distanceOK")]
-    pub distance_ok: Option<bool>,
-    pub on_revoked: Option<bool>,
-    pub joins_twice: Option<bool>,
-    pub enough_certs: Option<bool>,
-    pub leaver_is_member: Option<bool>,
-    pub active_is_member: Option<bool>,
-    pub revoked_is_member: Option<bool>,
-    pub already_revoked: Option<bool>,
-    #[serde(rename = "revocationSigOK")]
-    pub revocation_sig_ok: Option<bool>,
-    #[serde(rename = "created_on_ref")]
-    pub created_on_ref: Option<BlockstampTimed>,
-}
-
-#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
-#[serde(rename_all = "camelCase")]
-pub struct BlockstampTimed {
-    pub median_time: u64,
-    pub number: u32,
-    pub hash: String,
-}
diff --git a/rust-libs/duniter-dbs/src/values/peer_card.rs b/rust-libs/duniter-dbs/src/values/peer_card.rs
deleted file mode 100644
index ee08696d7..000000000
--- a/rust-libs/duniter-dbs/src/values/peer_card.rs
+++ /dev/null
@@ -1,58 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
-pub struct PeerCardDbV1 {
-    pub version: u32,
-    pub currency: String,
-    pub pubkey: String,
-    pub blockstamp: String,
-    pub endpoints: Vec<String>,
-    pub status: String,
-    pub signature: String,
-}
-
-impl AsBytes for PeerCardDbV1 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        let bytes = bincode::serialize(self).unwrap_or_else(|_| unreachable!());
-        f(bytes.as_ref())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for PeerCardDbV1 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        bincode::deserialize(&bytes).map_err(|e| CorruptedBytes(format!("{}: '{:?}'", e, bytes)))
-    }
-}
-
-impl ToDumpString for PeerCardDbV1 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableValue for PeerCardDbV1 {
-    fn from_explorer_str(_source: &str) -> std::result::Result<Self, FromExplorerValueErr> {
-        unimplemented!()
-    }
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        serde_json::to_value(self).map_err(|e| KvError::DeserError(e.into()))
-    }
-}
diff --git a/rust-libs/duniter-dbs/src/values/pubkey_db.rs b/rust-libs/duniter-dbs/src/values/pubkey_db.rs
deleted file mode 100644
index 7c16eedd6..000000000
--- a/rust-libs/duniter-dbs/src/values/pubkey_db.rs
+++ /dev/null
@@ -1,149 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-// V1
-
-#[derive(Copy, Clone, Debug, PartialEq)]
-pub struct PublicKeySingletonDbV1(pub PublicKey);
-
-impl AsBytes for PublicKeySingletonDbV1 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        f(format!("[\"{}\"]", self.0).as_bytes())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for PublicKeySingletonDbV1 {
-    type Err = BaseConversionError;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        let mut pubkey_str = std::str::from_utf8(bytes).expect("corrupted db : invalid utf8 bytes");
-
-        pubkey_str = &pubkey_str[2..pubkey_str.len() - 2];
-        Ok(Self(PublicKey::from_base58(pubkey_str)?))
-    }
-}
-
-impl ToDumpString for PublicKeySingletonDbV1 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableValue for PublicKeySingletonDbV1 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerValueErr> {
-        Ok(Self(
-            PublicKey::from_base58(source).map_err(|e| FromExplorerValueErr(e.into()))?,
-        ))
-    }
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        Ok(serde_json::Value::String(self.0.to_base58()))
-    }
-}
-
-#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
-pub struct PublicKeyArrayDbV1(pub SmallVec<[PublicKey; 8]>);
-
-impl AsBytes for PublicKeyArrayDbV1 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        let vec_pub_str = self
-            .0
-            .iter()
-            .map(|pubkey| pubkey.to_base58())
-            .collect::<SmallVec<[String; 8]>>();
-        let json = serde_json::to_string(&vec_pub_str).unwrap_or_else(|_| unreachable!());
-        f(json.as_bytes())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for PublicKeyArrayDbV1 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        let json_str = std::str::from_utf8(bytes).expect("corrupted db : invalid utf8 bytes");
-        let vec_pub_str: SmallVec<[String; 8]> = serde_json::from_str(&json_str)
-            .map_err(|e| CorruptedBytes(format!("{}: '{}'", e, json_str)))?;
-        Ok(Self(
-            vec_pub_str
-                .into_iter()
-                .map(|pub_str| {
-                    PublicKey::from_base58(&pub_str).map_err(|e| CorruptedBytes(e.to_string()))
-                })
-                .collect::<std::result::Result<SmallVec<[PublicKey; 8]>, Self::Err>>()?,
-        ))
-    }
-}
-
-impl ToDumpString for PublicKeyArrayDbV1 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableValue for PublicKeyArrayDbV1 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerValueErr> {
-        Self::from_bytes(source.as_bytes()).map_err(|e| FromExplorerValueErr(e.0.into()))
-    }
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        Ok(serde_json::Value::Array(
-            self.0
-                .iter()
-                .map(|pubkey| serde_json::Value::String(pubkey.to_base58()))
-                .collect(),
-        ))
-    }
-}
-
-// V2
-
-#[derive(Clone, Copy, Debug, Eq, PartialEq)]
-pub struct PubKeyValV2(pub PublicKey);
-
-impl AsBytes for PubKeyValV2 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        f(self.0.as_ref())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for PubKeyValV2 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        Ok(PubKeyValV2(PublicKey::try_from(bytes).map_err(|e| {
-            CorruptedBytes(format!("{}: {:?}", e, bytes))
-        })?))
-    }
-}
-
-impl ToDumpString for PubKeyValV2 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableValue for PubKeyValV2 {
-    fn from_explorer_str(pubkey_str: &str) -> std::result::Result<Self, FromExplorerValueErr> {
-        Ok(PubKeyValV2(PublicKey::from_base58(&pubkey_str).map_err(
-            |e| FromExplorerValueErr(format!("{}: {}", e, pubkey_str).into()),
-        )?))
-    }
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        Ok(serde_json::Value::String(self.0.to_base58()))
-    }
-}
diff --git a/rust-libs/duniter-dbs/src/values/sindex_db.rs b/rust-libs/duniter-dbs/src/values/sindex_db.rs
deleted file mode 100644
index 4d5b9f204..000000000
--- a/rust-libs/duniter-dbs/src/values/sindex_db.rs
+++ /dev/null
@@ -1,123 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
-#[serde(rename_all = "camelCase")]
-pub struct SIndexDBV1 {
-    pub src_type: String,
-    pub tx: Option<String>,
-    pub identifier: String,
-    pub pos: u32,
-    #[serde(rename = "created_on")]
-    pub created_on: Option<String>,
-    #[serde(rename = "written_time")]
-    pub written_time: u64,
-    #[serde(rename = "locktime")]
-    pub lock_time: u64,
-    pub unlock: Option<String>,
-    pub amount: u32,
-    pub base: u32,
-    pub conditions: String,
-    pub consumed: bool,
-    pub tx_obj: TransactionInBlockDbV1,
-    pub age: u64,
-    #[serde(rename = "type")]
-    pub type_: Option<String>,
-    pub available: Option<bool>,
-    pub is_locked: Option<bool>,
-    pub is_time_locked: Option<bool>,
-}
-
-impl AsBytes for SIndexDBV1 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        let json = serde_json::to_string(self).unwrap_or_else(|_| unreachable!());
-        f(json.as_bytes())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for SIndexDBV1 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        let json_str = std::str::from_utf8(bytes).expect("corrupted db : invalid utf8 bytes");
-        serde_json::from_str(&json_str)
-            .map_err(|e| CorruptedBytes(format!("{}: '{}'", e, json_str)))
-    }
-}
-
-impl ToDumpString for SIndexDBV1 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableValue for SIndexDBV1 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerValueErr> {
-        Self::from_bytes(source.as_bytes()).map_err(|e| FromExplorerValueErr(e.0.into()))
-    }
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        serde_json::to_value(self).map_err(|e| KvError::DeserError(e.into()))
-    }
-}
-
-#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
-pub struct SourceKeyArrayDbV1(pub SmallVec<[SourceKeyV1; 8]>);
-
-impl AsBytes for SourceKeyArrayDbV1 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        let vec_pub_str = self
-            .0
-            .iter()
-            .map(|source_key| source_key.to_string())
-            .collect::<SmallVec<[String; 8]>>();
-        let json = serde_json::to_string(&vec_pub_str).unwrap_or_else(|_| unreachable!());
-        f(json.as_bytes())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for SourceKeyArrayDbV1 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        let json_str = std::str::from_utf8(bytes).expect("corrupted db : invalid utf8 bytes");
-        let vec_source_key_str: SmallVec<[String; 8]> = serde_json::from_str(&json_str)
-            .map_err(|e| CorruptedBytes(format!("{}: '{}'", e, json_str)))?;
-        Ok(Self(
-            vec_source_key_str
-                .into_iter()
-                .map(|source_key_str| SourceKeyV1::from_bytes(source_key_str.as_bytes()))
-                .collect::<std::result::Result<SmallVec<[SourceKeyV1; 8]>, Self::Err>>()?,
-        ))
-    }
-}
-
-impl ToDumpString for SourceKeyArrayDbV1 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableValue for SourceKeyArrayDbV1 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerValueErr> {
-        Self::from_bytes(source.as_bytes()).map_err(|e| FromExplorerValueErr(e.0.into()))
-    }
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        serde_json::to_value(self).map_err(|e| KvError::DeserError(e.into()))
-    }
-}
diff --git a/rust-libs/duniter-dbs/src/values/source_amount.rs b/rust-libs/duniter-dbs/src/values/source_amount.rs
deleted file mode 100644
index 331493f7d..000000000
--- a/rust-libs/duniter-dbs/src/values/source_amount.rs
+++ /dev/null
@@ -1,67 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Clone, Copy, Debug, Default, PartialEq)]
-pub struct SourceAmountValV2(pub SourceAmount);
-
-impl AsBytes for SourceAmountValV2 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        use zerocopy::AsBytes as _;
-        f(self.0.as_bytes())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for SourceAmountValV2 {
-    type Err = LayoutVerifiedErr;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        let layout = zerocopy::LayoutVerified::<_, SourceAmount>::new(bytes)
-            .ok_or(LayoutVerifiedErr(stringify!(SourceAmount)))?;
-        Ok(Self(*layout))
-    }
-}
-
-impl ToDumpString for SourceAmountValV2 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableValue for SourceAmountValV2 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerValueErr> {
-        let mut source = source.split(':');
-        let amount_str = source
-            .next()
-            .ok_or_else(|| FromExplorerValueErr("Missing amount".into()))?;
-        let base_str = source
-            .next()
-            .ok_or_else(|| FromExplorerValueErr("Missing base".into()))?;
-        let amount = i64::from_str(amount_str)
-            .map_err(|e| FromExplorerValueErr(format!("Invalid amount: {}", e).into()))?;
-        let base = i64::from_str(base_str)
-            .map_err(|e| FromExplorerValueErr(format!("Invalid base: {}", e).into()))?;
-        Ok(Self(SourceAmount::new(amount, base)))
-    }
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        Ok(serde_json::Value::String(format!(
-            "{}:{}",
-            self.0.amount(),
-            self.0.base()
-        )))
-    }
-}
diff --git a/rust-libs/duniter-dbs/src/values/tx_db.rs b/rust-libs/duniter-dbs/src/values/tx_db.rs
deleted file mode 100644
index bcc06d149..000000000
--- a/rust-libs/duniter-dbs/src/values/tx_db.rs
+++ /dev/null
@@ -1,51 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-use dubp::documents::transaction::TransactionDocumentV10;
-#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
-pub struct PendingTxDbV2(pub TransactionDocumentV10);
-
-impl AsBytes for PendingTxDbV2 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        let bytes = bincode::serialize(self).unwrap_or_else(|_| unreachable!());
-        f(bytes.as_ref())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for PendingTxDbV2 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        bincode::deserialize(&bytes).map_err(|e| CorruptedBytes(format!("{}: '{:?}'", e, bytes)))
-    }
-}
-
-impl ToDumpString for PendingTxDbV2 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableValue for PendingTxDbV2 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerValueErr> {
-        Self::from_bytes(source.as_bytes()).map_err(|e| FromExplorerValueErr(e.0.into()))
-    }
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        serde_json::to_value(self).map_err(|e| KvError::DeserError(e.into()))
-    }
-}
diff --git a/rust-libs/duniter-dbs/src/values/txs.rs b/rust-libs/duniter-dbs/src/values/txs.rs
deleted file mode 100644
index f150673ef..000000000
--- a/rust-libs/duniter-dbs/src/values/txs.rs
+++ /dev/null
@@ -1,51 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-use dubp::documents::transaction::TransactionDocumentV10;
-#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
-pub struct BlockTxsDbV2(pub SmallVec<[TransactionDocumentV10; 8]>);
-
-impl AsBytes for BlockTxsDbV2 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        let bytes = bincode::serialize(self).unwrap_or_else(|_| unreachable!());
-        f(bytes.as_ref())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for BlockTxsDbV2 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        bincode::deserialize(&bytes).map_err(|e| CorruptedBytes(format!("{}: '{:?}'", e, bytes)))
-    }
-}
-
-impl ToDumpString for BlockTxsDbV2 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableValue for BlockTxsDbV2 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerValueErr> {
-        serde_json::from_str(source).map_err(|e| FromExplorerValueErr(e.into()))
-    }
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        serde_json::to_value(self).map_err(|e| KvError::DeserError(e.into()))
-    }
-}
diff --git a/rust-libs/duniter-dbs/src/values/ud_entry_db.rs b/rust-libs/duniter-dbs/src/values/ud_entry_db.rs
deleted file mode 100644
index a32efd774..000000000
--- a/rust-libs/duniter-dbs/src/values/ud_entry_db.rs
+++ /dev/null
@@ -1,79 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
-#[serde(rename_all = "camelCase")]
-pub struct UdEntryDbV1 {
-    #[serde(rename = "pub")]
-    pub pubkey: String,
-    pub member: bool,
-    pub availables: Vec<u32>,
-    pub consumed: Vec<u32>,
-    #[serde(rename = "consumedUDs")]
-    pub consumed_uds: Vec<ConsumedUdDbV1>,
-    pub dividends: Vec<UdAmountDbV1>,
-}
-
-impl AsBytes for UdEntryDbV1 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        let json = serde_json::to_string(self).unwrap_or_else(|_| unreachable!());
-        f(json.as_bytes())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for UdEntryDbV1 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        let json_str = std::str::from_utf8(bytes).expect("corrupted db : invalid utf8 bytes");
-        serde_json::from_str(&json_str)
-            .map_err(|e| CorruptedBytes(format!("{}: '{}'", e, json_str)))
-    }
-}
-
-impl ToDumpString for UdEntryDbV1 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableValue for UdEntryDbV1 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerValueErr> {
-        Self::from_bytes(source.as_bytes()).map_err(|e| FromExplorerValueErr(e.0.into()))
-    }
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        serde_json::to_value(self).map_err(|e| KvError::DeserError(e.into()))
-    }
-}
-
-#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
-#[serde(rename_all = "camelCase")]
-pub struct ConsumedUdDbV1 {
-    pub dividend_number: u32,
-    pub tx_hash: String,
-    pub tx_created_on: String,
-    #[serde(rename = "txLocktime")]
-    pub tx_lock_time: u32,
-    pub dividend: UdAmountDbV1,
-}
-
-#[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize)]
-pub struct UdAmountDbV1 {
-    pub amount: u32,
-    pub base: u32,
-}
diff --git a/rust-libs/duniter-dbs/src/values/utxo.rs b/rust-libs/duniter-dbs/src/values/utxo.rs
deleted file mode 100644
index dc5b60e56..000000000
--- a/rust-libs/duniter-dbs/src/values/utxo.rs
+++ /dev/null
@@ -1,159 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-use std::{collections::HashMap, ops::Deref};
-
-#[derive(
-    Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, zerocopy::AsBytes, zerocopy::FromBytes,
-)]
-#[repr(transparent)]
-pub struct UtxoValV2([u8; 52]); // 16(SourceAmount) + 32(Hash) + 4(u32)
-impl UtxoValV2 {
-    pub fn new(amount: SourceAmount, tx_hash: Hash, output_index: u32) -> Self {
-        let mut buffer = [0; 52];
-        use zerocopy::AsBytes as _;
-        buffer[..16].copy_from_slice(amount.as_bytes());
-        buffer[16..48].copy_from_slice(tx_hash.as_ref());
-        buffer[48..].copy_from_slice(&output_index.to_le_bytes()[..]);
-        Self(buffer)
-    }
-    pub fn amount(&self) -> &SourceAmount {
-        let layout =
-            zerocopy::LayoutVerified::<_, SourceAmount>::new(&self.0[..16]).expect("dev error");
-
-        unsafe { std::mem::transmute(layout.deref()) }
-    }
-    pub fn tx_hash(&self) -> &Hash {
-        let layout = zerocopy::LayoutVerified::<_, Hash>::new(&self.0[16..48]).expect("dev error");
-
-        unsafe { std::mem::transmute(layout.deref()) }
-    }
-    pub fn output_index(&self) -> u32 {
-        zerocopy::LayoutVerified::<_, zerocopy::U32<byteorder::LittleEndian>>::new(&self.0[48..])
-            .expect("dev error")
-            .get()
-    }
-}
-
-impl Default for UtxoValV2 {
-    fn default() -> Self {
-        UtxoValV2([0u8; 52])
-    }
-}
-
-impl std::fmt::Display for UtxoValV2 {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        let amount = self.amount();
-        write!(
-            f,
-            "{}:{}:T:{}:{}",
-            amount.amount(),
-            amount.base(),
-            self.tx_hash(),
-            self.output_index()
-        )
-    }
-}
-
-impl FromStr for UtxoValV2 {
-    type Err = CorruptedBytes;
-
-    fn from_str(_s: &str) -> std::result::Result<Self, Self::Err> {
-        unimplemented!()
-    }
-}
-
-impl AsBytes for UtxoValV2 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        f(self.0.as_ref())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for UtxoValV2 {
-    type Err = LayoutVerifiedErr;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        let layout = zerocopy::LayoutVerified::<_, UtxoValV2>::new(bytes)
-            .ok_or(LayoutVerifiedErr(stringify!(UtxoValV2)))?;
-        Ok(*layout)
-    }
-}
-
-impl ToDumpString for UtxoValV2 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableValue for UtxoValV2 {
-    fn from_explorer_str(_: &str) -> std::result::Result<Self, FromExplorerValueErr> {
-        unimplemented!()
-    }
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        Ok(serde_json::Value::String(self.to_string()))
-    }
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
-pub struct BlockUtxosV2Db(pub HashMap<UtxoIdV10, WalletScriptWithSourceAmountV1Db>);
-
-impl AsBytes for BlockUtxosV2Db {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        f(&bincode::serialize(&self).unwrap_or_else(|_| unreachable!()))
-    }
-}
-
-impl kv_typed::prelude::FromBytes for BlockUtxosV2Db {
-    type Err = bincode::Error;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        bincode::deserialize(bytes)
-    }
-}
-
-impl ToDumpString for BlockUtxosV2Db {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableValue for BlockUtxosV2Db {
-    fn from_explorer_str(_: &str) -> std::result::Result<Self, FromExplorerValueErr> {
-        unimplemented!()
-    }
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        serde_json::to_value(self).map_err(|e| KvError::DeserError(e.into()))
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn utxo_val_v2() {
-        let amount = SourceAmount::with_base0(42);
-        let tx_hash = Hash::default();
-        let output_index = 3;
-        let utxo_val = UtxoValV2::new(amount, tx_hash, output_index);
-
-        assert_eq!(utxo_val.amount(), &amount);
-        assert_eq!(utxo_val.tx_hash(), &tx_hash);
-        assert_eq!(utxo_val.output_index(), output_index);
-    }
-}
diff --git a/rust-libs/duniter-dbs/src/values/wallet_db.rs b/rust-libs/duniter-dbs/src/values/wallet_db.rs
deleted file mode 100644
index 465346100..000000000
--- a/rust-libs/duniter-dbs/src/values/wallet_db.rs
+++ /dev/null
@@ -1,55 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
-pub struct WalletDbV1 {
-    pub conditions: String,
-    pub balance: u64,
-}
-
-impl AsBytes for WalletDbV1 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        let json = serde_json::to_string(self).unwrap_or_else(|_| unreachable!());
-        f(json.as_bytes())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for WalletDbV1 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        let json_str = std::str::from_utf8(bytes).expect("corrupted db : invalid utf8 bytes");
-        serde_json::from_str(&json_str)
-            .map_err(|e| CorruptedBytes(format!("{}: '{}'", e, json_str)))
-    }
-}
-
-impl ToDumpString for WalletDbV1 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableValue for WalletDbV1 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerValueErr> {
-        Self::from_bytes(source.as_bytes()).map_err(|e| FromExplorerValueErr(e.0.into()))
-    }
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        serde_json::to_value(self).map_err(|e| KvError::DeserError(e.into()))
-    }
-}
diff --git a/rust-libs/duniter-dbs/src/values/wallet_script_with_sa.rs b/rust-libs/duniter-dbs/src/values/wallet_script_with_sa.rs
deleted file mode 100644
index 5d40dd95a..000000000
--- a/rust-libs/duniter-dbs/src/values/wallet_script_with_sa.rs
+++ /dev/null
@@ -1,52 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
-pub struct WalletScriptWithSourceAmountV1Db {
-    pub wallet_script: WalletScriptV10,
-    pub source_amount: SourceAmount,
-}
-
-impl AsBytes for WalletScriptWithSourceAmountV1Db {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        f(&bincode::serialize(&self).unwrap_or_else(|_| unreachable!()))
-    }
-}
-
-impl kv_typed::prelude::FromBytes for WalletScriptWithSourceAmountV1Db {
-    type Err = bincode::Error;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        bincode::deserialize(bytes)
-    }
-}
-
-impl ToDumpString for WalletScriptWithSourceAmountV1Db {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableValue for WalletScriptWithSourceAmountV1Db {
-    fn from_explorer_str(_: &str) -> std::result::Result<Self, FromExplorerValueErr> {
-        unimplemented!()
-    }
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        serde_json::to_value(self).map_err(|e| KvError::DeserError(e.into()))
-    }
-}
diff --git a/rust-libs/duniter-dbs/tests/test_explorer.rs b/rust-libs/duniter-dbs/tests/test_explorer.rs
deleted file mode 100644
index 2dabf7ef4..000000000
--- a/rust-libs/duniter-dbs/tests/test_explorer.rs
+++ /dev/null
@@ -1,253 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-#[cfg(feature = "explorer")]
-mod explorer {
-    use dubp::common::crypto::keys::ed25519::PublicKey;
-    use dubp::common::crypto::keys::PublicKey as _;
-    //use dubp::common::prelude::*;
-    use duniter_dbs::kv_typed::prelude::*;
-    use duniter_dbs::kv_typed::regex;
-    use duniter_dbs::prelude::*;
-    use duniter_dbs::smallvec::smallvec;
-    use duniter_dbs::{
-        databases::bc_v1::{BcV1Db, BcV1DbWritable},
-        PublicKeySingletonDbV1, UidKeyV1,
-    };
-    use std::{num::NonZeroUsize, str::FromStr};
-    use tempfile::TempDir;
-    use unwrap::unwrap;
-
-    const COLLECTION_NAME: &str = "uids";
-
-    fn stringify_json_value_test(v: serde_json::Value) -> serde_json::Value {
-        v
-    }
-
-    #[test]
-    fn explorer_test_leveldb() -> anyhow::Result<()> {
-        let tmp_dir = unwrap!(TempDir::new());
-
-        let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(tmp_dir.path().to_owned()))?;
-
-        explorer_test(&db)
-    }
-
-    #[test]
-    fn explorer_test_sled() -> anyhow::Result<()> {
-        let db = BcV1Db::<Sled>::open(SledConf::new().temporary(true))?;
-
-        explorer_test(&db)
-    }
-
-    fn explorer_test<B: Backend>(db: &BcV1Db<B>) -> anyhow::Result<()> {
-        // Defines test data
-        let k1 = unwrap!(UidKeyV1::from_str("toto"));
-        let k2 = unwrap!(UidKeyV1::from_str("titi"));
-        let v1 = PublicKeySingletonDbV1(unwrap!(PublicKey::from_base58(
-            "ByE9TU6qhktHYYVAqeTcWcaULBx151siQLyL3TrKvY85"
-        )));
-        let v2 = PublicKeySingletonDbV1(unwrap!(PublicKey::from_base58(
-            "8B5XCAHknsckCkMWeGF9FoGibSNZXF9HtAvzxzg3bSyp"
-        )));
-
-        // Insert test data
-        db.uids_write().upsert(k1, v1)?;
-        db.uids_write().upsert(k2, v2)?;
-
-        // Test action count
-        let res = db.explore(
-            COLLECTION_NAME,
-            ExplorerAction::Count,
-            stringify_json_value_test,
-        )??;
-        assert_eq!(ExplorerActionResponse::Count(2), res);
-
-        // Test action get
-        let res = db.explore(
-            COLLECTION_NAME,
-            ExplorerAction::Get { key: "unexist" },
-            stringify_json_value_test,
-        )??;
-        assert_eq!(ExplorerActionResponse::Get(None), res);
-        let res = db.explore(
-            COLLECTION_NAME,
-            ExplorerAction::Get { key: "toto" },
-            stringify_json_value_test,
-        )??;
-        assert_eq!(
-            ExplorerActionResponse::Get(Some(serde_json::Value::String(
-                "ByE9TU6qhktHYYVAqeTcWcaULBx151siQLyL3TrKvY85".to_owned()
-            ))),
-            res
-        );
-
-        // Test action put
-        let res = db.explore(
-            COLLECTION_NAME,
-            ExplorerAction::Put {
-                key: "titu",
-                value: "Bi6ECSc352gdfEvVzGiQuuDQyaTptHkcxooMGTJk14Tr",
-            },
-            stringify_json_value_test,
-        )??;
-        assert_eq!(ExplorerActionResponse::PutOk, res);
-        let res = db.explore(
-            COLLECTION_NAME,
-            ExplorerAction::Get { key: "titu" },
-            stringify_json_value_test,
-        )??;
-        assert_eq!(
-            ExplorerActionResponse::Get(Some(serde_json::Value::String(
-                "Bi6ECSc352gdfEvVzGiQuuDQyaTptHkcxooMGTJk14Tr".to_owned()
-            ))),
-            res
-        );
-        let res = db.explore(
-            COLLECTION_NAME,
-            ExplorerAction::Count,
-            stringify_json_value_test,
-        )??;
-        assert_eq!(ExplorerActionResponse::Count(3), res);
-
-        // Test action find
-        let range_res = db.explore(
-            COLLECTION_NAME,
-            ExplorerAction::Find {
-                key_min: Some("ti00".to_owned()),
-                key_max: Some("tizz".to_owned()),
-                key_regex: None,
-                value_regex: None,
-                limit: Some(10),
-                reverse: false,
-                step: unsafe { NonZeroUsize::new_unchecked(1) },
-            },
-            stringify_json_value_test,
-        )??;
-        assert_eq!(
-            ExplorerActionResponse::Find(vec![
-                EntryFound {
-                    key: "titi".to_owned(),
-                    value: serde_json::Value::String(
-                        "8B5XCAHknsckCkMWeGF9FoGibSNZXF9HtAvzxzg3bSyp".to_owned()
-                    ),
-                    captures: None,
-                },
-                EntryFound {
-                    key: "titu".to_owned(),
-                    value: serde_json::Value::String(
-                        "Bi6ECSc352gdfEvVzGiQuuDQyaTptHkcxooMGTJk14Tr".to_owned()
-                    ),
-                    captures: None,
-                },
-            ]),
-            range_res
-        );
-
-        // Test action find with limit
-        let range_res = db.explore(
-            COLLECTION_NAME,
-            ExplorerAction::Find {
-                key_min: Some("ti00".to_owned()),
-                key_max: Some("tizz".to_owned()),
-                key_regex: None,
-                value_regex: None,
-                limit: Some(1),
-                reverse: false,
-                step: unsafe { NonZeroUsize::new_unchecked(1) },
-            },
-            stringify_json_value_test,
-        )??;
-        assert_eq!(
-            ExplorerActionResponse::Find(vec![EntryFound {
-                key: "titi".to_owned(),
-                value: serde_json::Value::String(
-                    "8B5XCAHknsckCkMWeGF9FoGibSNZXF9HtAvzxzg3bSyp".to_owned()
-                ),
-                captures: None,
-            }]),
-            range_res
-        );
-
-        // Test action find with limit and reverse
-        let range_res = db.explore(
-            COLLECTION_NAME,
-            ExplorerAction::Find {
-                key_min: Some("ti00".to_owned()),
-                key_max: Some("tizz".to_owned()),
-                key_regex: None,
-                value_regex: None,
-                limit: Some(1),
-                reverse: true,
-                step: unsafe { NonZeroUsize::new_unchecked(1) },
-            },
-            stringify_json_value_test,
-        )??;
-        assert_eq!(
-            ExplorerActionResponse::Find(vec![EntryFound {
-                key: "titu".to_owned(),
-                value: serde_json::Value::String(
-                    "Bi6ECSc352gdfEvVzGiQuuDQyaTptHkcxooMGTJk14Tr".to_owned()
-                ),
-                captures: None,
-            }]),
-            range_res
-        );
-
-        // Test action find with regex capture
-        let range_res = db.explore(
-            COLLECTION_NAME,
-            ExplorerAction::Find {
-                key_min: Some("ti00".to_owned()),
-                key_max: Some("tizz".to_owned()),
-                key_regex: None,
-                value_regex: Some(regex::Regex::new("(E[Cv])[A-Z]").expect("wrong regex")),
-                limit: Some(10),
-                reverse: false,
-                step: unsafe { NonZeroUsize::new_unchecked(1) },
-            },
-            stringify_json_value_test,
-        )??;
-        assert_eq!(
-            ExplorerActionResponse::Find(vec![EntryFound {
-                key: "titu".to_owned(),
-                value: serde_json::Value::String(
-                    "Bi6ECSc352gdfEvVzGiQuuDQyaTptHkcxooMGTJk14Tr".to_owned()
-                ),
-                captures: Some(ValueCaptures(smallvec![
-                    smallvec![Some("EC".to_owned())],
-                    smallvec![Some("Ev".to_owned())]
-                ])),
-            }]),
-            range_res
-        );
-
-        // Test action delete
-        let res = db.explore(
-            COLLECTION_NAME,
-            ExplorerAction::Delete { key: "toto" },
-            stringify_json_value_test,
-        )??;
-        assert_eq!(ExplorerActionResponse::DeleteOk, res);
-        let res = db.explore(
-            COLLECTION_NAME,
-            ExplorerAction::Get { key: "toto" },
-            stringify_json_value_test,
-        )??;
-        assert_eq!(ExplorerActionResponse::Get(None), res);
-
-        Ok(())
-    }
-}
diff --git a/rust-libs/duniter-dbs/tests/test_read_write.rs b/rust-libs/duniter-dbs/tests/test_read_write.rs
deleted file mode 100644
index d626b963a..000000000
--- a/rust-libs/duniter-dbs/tests/test_read_write.rs
+++ /dev/null
@@ -1,405 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use dubp::common::crypto::keys::ed25519::PublicKey;
-use dubp::common::crypto::keys::PublicKey as _;
-use dubp::common::prelude::*;
-use duniter_dbs::kv_typed::prelude::*;
-use duniter_dbs::{
-    databases::bc_v1::{BcV1Db, BcV1DbReadable, BcV1DbWritable, MainBlocksEvent},
-    BlockDbV1, BlockNumberKeyV1, PublicKeySingletonDbV1, UidKeyV1,
-};
-use kv_typed::channel::TryRecvError;
-use std::str::FromStr;
-use tempfile::TempDir;
-use unwrap::unwrap;
-
-#[test]
-fn write_read_delete_b0_leveldb() -> KvResult<()> {
-    let tmp_dir = unwrap!(TempDir::new());
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(tmp_dir.path().to_owned()))?;
-
-    write_read_delete_b0_test(&db)
-}
-
-#[test]
-fn write_read_delete_b0_sled() -> KvResult<()> {
-    let db = BcV1Db::<Sled>::open(SledConf::new().temporary(true))?;
-
-    write_read_delete_b0_test(&db)
-}
-
-#[test]
-fn iter_test_leveldb() -> KvResult<()> {
-    let tmp_dir = unwrap!(TempDir::new());
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(tmp_dir.path().to_owned()))?;
-
-    write_some_entries_and_iter(&db)
-}
-
-#[test]
-fn iter_test_mem() -> KvResult<()> {
-    let db = BcV1Db::<Mem>::open(MemConf::default())?;
-
-    write_some_entries_and_iter(&db)
-}
-
-#[test]
-fn iter_test_sled() -> KvResult<()> {
-    let db = BcV1Db::<Sled>::open(SledConf::new().temporary(true))?;
-
-    write_some_entries_and_iter(&db)
-}
-
-#[test]
-fn batch_test_leveldb() -> KvResult<()> {
-    let tmp_dir = unwrap!(TempDir::new());
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(tmp_dir.path().to_owned()))?;
-
-    batch_test(&db)
-}
-
-#[test]
-fn batch_test_mem() -> KvResult<()> {
-    let db = BcV1Db::<Mem>::open(MemConf::default())?;
-
-    batch_test(&db)
-}
-
-#[test]
-fn batch_test_sled() -> KvResult<()> {
-    let db = BcV1Db::<Sled>::open(SledConf::new().temporary(true))?;
-
-    batch_test(&db)
-}
-
-fn write_read_delete_b0_test<B: Backend>(db: &BcV1Db<B>) -> KvResult<()> {
-    let main_blocks_reader = db.main_blocks();
-
-    let (subscriber, events_recv) = kv_typed::channel::unbounded();
-
-    main_blocks_reader.subscribe(subscriber)?;
-
-    // Empty db
-    assert_eq!(
-        main_blocks_reader.get(&BlockNumberKeyV1(BlockNumber(0)))?,
-        None
-    );
-    assert_eq!(
-        main_blocks_reader.get(&BlockNumberKeyV1(BlockNumber(1)))?,
-        None
-    );
-    assert_eq!(
-        main_blocks_reader.iter(.., |iter| iter.keys().next_res())?,
-        None
-    );
-    assert_eq!(
-        main_blocks_reader.iter(.., |iter| iter.values().next_res())?,
-        None
-    );
-    if let Err(TryRecvError::Empty) = events_recv.try_recv() {
-    } else {
-        panic!("should not receive event");
-    }
-
-    // Insert b0
-    let b0 = BlockDbV1::default();
-    let main_blocks_writer = db.main_blocks_write();
-    main_blocks_writer.upsert(BlockNumberKeyV1(BlockNumber(0)), b0.clone())?;
-    assert_eq!(
-        main_blocks_reader
-            .get(&BlockNumberKeyV1(BlockNumber(0)))?
-            .as_ref(),
-        Some(&b0)
-    );
-    assert_eq!(
-        main_blocks_reader.get(&BlockNumberKeyV1(BlockNumber(1)))?,
-        None
-    );
-    main_blocks_reader.iter(.., |iter| {
-        let mut keys_iter = iter.keys();
-        assert_eq!(
-            keys_iter.next_res()?,
-            Some(BlockNumberKeyV1(BlockNumber(0)))
-        );
-        assert_eq!(keys_iter.next_res()?, None);
-        Ok::<(), KvError>(())
-    })?;
-    main_blocks_reader.iter(.., |iter| {
-        let mut values_iter = iter.values();
-        assert_eq!(values_iter.next_res()?, Some(b0.clone()));
-        assert_eq!(values_iter.next_res()?, None);
-
-        Ok::<(), KvError>(())
-    })?;
-    if let Ok(events) = events_recv.try_recv() {
-        assert_eq!(events.len(), 1);
-        let event = &events[0];
-        assert_eq!(
-            event,
-            &MainBlocksEvent::Upsert {
-                key: BlockNumberKeyV1(BlockNumber(0)),
-                value: b0,
-            },
-        );
-    } else {
-        panic!("should receive event");
-    }
-
-    // Delete b0
-    main_blocks_writer.remove(BlockNumberKeyV1(BlockNumber(0)))?;
-    assert_eq!(
-        main_blocks_reader.get(&BlockNumberKeyV1(BlockNumber(0)))?,
-        None
-    );
-    assert_eq!(
-        main_blocks_reader.get(&BlockNumberKeyV1(BlockNumber(1)))?,
-        None
-    );
-    assert_eq!(
-        main_blocks_reader.iter(.., |it| it.keys().next_res())?,
-        None
-    );
-    assert_eq!(
-        main_blocks_reader.iter(.., |it| it.values().next_res())?,
-        None
-    );
-    if let Ok(events) = events_recv.try_recv() {
-        assert_eq!(events.len(), 1);
-        let event = &events[0];
-        assert_eq!(
-            event,
-            &MainBlocksEvent::Remove {
-                key: BlockNumberKeyV1(BlockNumber(0)),
-            },
-        );
-    } else {
-        panic!("should receive event");
-    }
-
-    Ok(())
-}
-
-fn write_some_entries_and_iter<B: Backend>(db: &BcV1Db<B>) -> KvResult<()> {
-    let k1 = unwrap!(UidKeyV1::from_str("titi"));
-    let p1 = PublicKeySingletonDbV1(unwrap!(PublicKey::from_base58(
-        "42jMJtb8chXrpHMAMcreVdyPJK7LtWjEeRqkPw4eSEVp"
-    )));
-    let k2 = unwrap!(UidKeyV1::from_str("titu"));
-    let p2 = PublicKeySingletonDbV1(unwrap!(PublicKey::from_base58(
-        "D7CYHJXjaH4j7zRdWngUbsURPnSnjsCYtvo6f8dvW3C"
-    )));
-    let k3 = unwrap!(UidKeyV1::from_str("toto"));
-    let p3 = PublicKeySingletonDbV1(unwrap!(PublicKey::from_base58(
-        "8B5XCAHknsckCkMWeGF9FoGibSNZXF9HtAvzxzg3bSyp"
-    )));
-    let uids_writer = db.uids_write();
-    uids_writer.upsert(k1, p1)?;
-    uids_writer.upsert(k2, p2)?;
-    uids_writer.upsert(k3, p3)?;
-
-    let uids_reader = db.uids();
-    {
-        uids_reader.iter(.., |it| {
-            let mut values_iter_step_2 = it.values().step_by(2);
-
-            assert_eq!(Some(p1), values_iter_step_2.next_res()?);
-            assert_eq!(Some(p3), values_iter_step_2.next_res()?);
-            assert_eq!(None, values_iter_step_2.next_res()?);
-            Ok::<(), KvError>(())
-        })?;
-
-        uids_reader.iter(.., |it| {
-            let mut entries_iter_step_2 = it.step_by(2);
-
-            assert_eq!(Some((k1, p1)), entries_iter_step_2.next_res()?);
-            assert_eq!(Some((k3, p3)), entries_iter_step_2.next_res()?);
-            assert_eq!(None, entries_iter_step_2.next_res()?);
-            Ok::<(), KvError>(())
-        })?;
-
-        uids_reader.iter(k2.., |mut entries_iter| {
-            assert_eq!(Some((k2, p2)), entries_iter.next_res()?);
-            assert_eq!(Some((k3, p3)), entries_iter.next_res()?);
-            assert_eq!(None, entries_iter.next_res()?);
-            Ok::<(), KvError>(())
-        })?;
-
-        uids_reader.iter(..=k2, |mut entries_iter| {
-            assert_eq!(Some((k1, p1)), entries_iter.next_res()?);
-            assert_eq!(Some((k2, p2)), entries_iter.next_res()?);
-            assert_eq!(None, entries_iter.next_res()?);
-            Ok::<(), KvError>(())
-        })?;
-
-        uids_reader.iter_rev(k2.., |mut entries_iter_rev| {
-            assert_eq!(Some((k3, p3)), entries_iter_rev.next_res()?);
-            assert_eq!(Some((k2, p2)), entries_iter_rev.next_res()?);
-            assert_eq!(None, entries_iter_rev.next_res()?);
-            Ok::<(), KvError>(())
-        })?;
-
-        uids_reader.iter_rev(..=k2, |mut entries_iter_rev| {
-            assert_eq!(Some((k2, p2)), entries_iter_rev.next_res()?);
-            assert_eq!(Some((k1, p1)), entries_iter_rev.next_res()?);
-            Ok::<(), KvError>(())
-        })?;
-
-        uids_reader.iter_rev(..=k2, |iter_rev| {
-            let mut keys_iter_rev = iter_rev.keys();
-            assert_eq!(Some(k2), keys_iter_rev.next_res()?);
-            assert_eq!(Some(k1), keys_iter_rev.next_res()?);
-            assert_eq!(None, keys_iter_rev.next_res()?);
-            Ok::<(), KvError>(())
-        })?;
-    }
-
-    uids_writer.remove(k3)?;
-
-    uids_reader.iter(.., |it| {
-        let mut keys_iter = it.keys();
-
-        assert_eq!(Some(k1), keys_iter.next_res()?);
-        assert_eq!(Some(k2), keys_iter.next_res()?);
-        assert_eq!(None, keys_iter.next_res()?);
-        Ok::<(), KvError>(())
-    })?;
-
-    Ok(())
-}
-
-fn batch_test<B: Backend>(db: &BcV1Db<B>) -> KvResult<()> {
-    let main_blocks_reader = db.main_blocks();
-
-    let mut batch = db.new_batch();
-
-    let (subscriber, events_recv) = kv_typed::channel::unbounded();
-
-    main_blocks_reader.subscribe(subscriber)?;
-
-    // Empty db
-    assert_eq!(
-        main_blocks_reader.get(&BlockNumberKeyV1(BlockNumber(0)))?,
-        None
-    );
-    assert_eq!(
-        main_blocks_reader.get(&BlockNumberKeyV1(BlockNumber(1)))?,
-        None
-    );
-    assert_eq!(
-        main_blocks_reader.iter(.., |it| it.keys().next_res())?,
-        None
-    );
-    assert_eq!(
-        main_blocks_reader.iter(.., |it| it.values().next_res())?,
-        None
-    );
-    if let Err(TryRecvError::Empty) = events_recv.try_recv() {
-    } else {
-        panic!("should not receive event");
-    }
-
-    // Insert b0 in batch
-    let b0 = BlockDbV1::default();
-    batch
-        .main_blocks()
-        .upsert(BlockNumberKeyV1(BlockNumber(0)), b0.clone());
-
-    // bo should written in batch
-    assert_eq!(
-        batch.main_blocks().get(&BlockNumberKeyV1(BlockNumber(0))),
-        BatchGet::Updated(&b0)
-    );
-
-    // bo should not written in db
-    assert_eq!(
-        db.main_blocks().get(&BlockNumberKeyV1(BlockNumber(0)))?,
-        None
-    );
-
-    if let Err(TryRecvError::Empty) = events_recv.try_recv() {
-    } else {
-        panic!("should not receive event");
-    }
-
-    // Insert b1 in batch
-    let b1 = BlockDbV1 {
-        number: 1,
-        ..Default::default()
-    };
-    batch
-        .main_blocks()
-        .upsert(BlockNumberKeyV1(BlockNumber(1)), b1.clone());
-
-    // Write batch in db
-    db.write_batch(batch)?;
-
-    // bo should written in db
-    assert_eq!(
-        db.main_blocks()
-            .get(&BlockNumberKeyV1(BlockNumber(0)))?
-            .as_ref(),
-        Some(&b0)
-    );
-    db.main_blocks().iter(.., |it| {
-        let mut keys_iter = it.keys();
-
-        assert_eq!(
-            keys_iter.next_res()?,
-            Some(BlockNumberKeyV1(BlockNumber(0)))
-        );
-        assert_eq!(
-            keys_iter.next_res()?,
-            Some(BlockNumberKeyV1(BlockNumber(1)))
-        );
-        assert_eq!(keys_iter.next_res()?, None);
-        Ok::<(), KvError>(())
-    })?;
-    db.main_blocks().iter(.., |it| {
-        let mut values_iter = it.values();
-
-        assert_eq!(values_iter.next_res()?.as_ref(), Some(&b0));
-        assert_eq!(values_iter.next_res()?.as_ref(), Some(&b1));
-        assert_eq!(values_iter.next_res()?, None);
-        Ok::<(), KvError>(())
-    })?;
-    if let Ok(events) = events_recv.try_recv() {
-        assert_eq!(events.len(), 2);
-        assert!(assert_eq_pairs(
-            [&events[0], &events[1]],
-            [
-                &MainBlocksEvent::Upsert {
-                    key: BlockNumberKeyV1(BlockNumber(0)),
-                    value: b0,
-                },
-                &MainBlocksEvent::Upsert {
-                    key: BlockNumberKeyV1(BlockNumber(1)),
-                    value: b1,
-                }
-            ]
-        ));
-    } else {
-        panic!("should receive event");
-    }
-
-    Ok(())
-}
-
-fn assert_eq_pairs<T: PartialEq>(a: [T; 2], b: [T; 2]) -> bool {
-    (a[0] == b[0] && a[1] == b[1]) || (a[1] == b[0] && a[0] == b[1])
-}
diff --git a/rust-libs/duniter-dbs/tests/test_tmp_real.rs b/rust-libs/duniter-dbs/tests/test_tmp_real.rs
deleted file mode 100644
index 563a71d03..000000000
--- a/rust-libs/duniter-dbs/tests/test_tmp_real.rs
+++ /dev/null
@@ -1,767 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-/*use dubp_common::crypto::bases::b58::ToBase58 as _;
-use dubp_common::crypto::hashs::Hash;
-use dubp_common::crypto::keys::PublicKey;
-use dubp_common::prelude::*;
-use duniter_dbs::kv_typed::prelude::*;
-use duniter_dbs::*;
-use duniter_dbs::{
-    BcV1Db, BcV1DbReadable, BcV1DbWritable, BlockDbV1, BlockNumberKeyV1, PublicKeySingletonDbV1,
-    Result, UidKeyV1,
-};
-use once_cell::sync::Lazy;
-use std::{path::PathBuf, str::FromStr, sync::Mutex};
-use unwrap::unwrap;
-
-// Empty mutex used to ensure that only one test runs at a time
-static MUTEX: Lazy<Mutex<()>> = Lazy::new(|| Mutex::new(()));
-
-//const DB_PATH: &str = "/home/elois/.config/duniter/duniter_default/data";
-const DB_PATH: &str = "/home/elois/Documents/ml/leveldb-archives/g1-317499/leveldb";
-
-#[test]
-#[ignore]
-fn db_v1_main_blocks__() -> Result<()> {
-    let _lock = MUTEX.lock().expect("MUTEX poisoned");
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(PathBuf::from(DB_PATH)))?;
-
-    //let block52 = db.get::<MainBlocksColV1>(&MainBlockKeyV1(52))?;
-    //println!("{:#?}", block52);
-
-    let current_block_number_opt = db
-        .main_blocks()
-        .iter(..)
-        .keys()
-        .reverse()
-        .next()
-        .transpose()?;
-    if let Some(current_block_number) = current_block_number_opt {
-        println!("current_block_number={:#?}", current_block_number);
-        let current_block = db.main_blocks().get(&current_block_number)?;
-        println!("current_block={:#?}", current_block);
-    }
-
-    /*// Collect all main blocks
-    let entries = db
-        .main_blocks()
-        .iter(..)
-        .collect::<KvResult<Vec<(BlockNumberKeyV1, BlockDbV1)>>>()?;
-    println!("entries_len={}", entries.len());*/
-
-    Ok(())
-}
-
-#[test]
-#[ignore]
-fn db_v1_main_blocks_idty() -> Result<()> {
-    let _lock = MUTEX.lock().expect("MUTEX poisoned");
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(PathBuf::from(DB_PATH)))?;
-
-    let all = unwrap!(db.mb_idty().get(&PubKeyKeyV1::all())?);
-    assert!(all.0.len() > 2);
-
-    // Collect all main blocks idty
-    let entries = db
-        .mb_idty()
-        .iter(..)
-        .collect::<KvResult<Vec<(PubKeyKeyV1, BlockNumberArrayV1)>>>()?;
-    println!("identities_count={}", entries.len() - 1);
-    for (k, v) in &entries {
-        if v.0.len() == 2 {
-            println!("{:?}", k.0.as_ref());
-        }
-    }
-
-    Ok(())
-}
-
-#[test]
-#[ignore]
-fn db_v1_main_blocks_certs() -> Result<()> {
-    let _lock = MUTEX.lock().expect("MUTEX poisoned");
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(PathBuf::from(DB_PATH)))?;
-
-    // Collect all main blocks idty
-    let entries = db
-        .mb_certs()
-        .iter(..)
-        .collect::<KvResult<Vec<(PubKeyKeyV1, BlockNumberArrayV1)>>>()?;
-    println!("certifications_count={}", entries.len() - 1);
-    for (k, v) in &entries[..10] {
-        if v.0.len() > 1 {
-            println!("{}={:?}", k.0, v.0);
-        }
-    }
-
-    Ok(())
-}
-
-#[test]
-#[ignore]
-fn db_v1_main_blocks_joiners() -> Result<()> {
-    let _lock = MUTEX.lock().expect("MUTEX poisoned");
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(PathBuf::from(DB_PATH)))?;
-
-    let all = unwrap!(db.mb_joiners().get(&PubKeyKeyV1::all())?);
-    assert!(all.0.len() > 100);
-
-    // Collect all main blocks joiners
-    let entries = db
-        .mb_joiners()
-        .iter(..)
-        .collect::<KvResult<Vec<(PubKeyKeyV1, BlockNumberArrayV1)>>>()?;
-    println!("joiners_count={}", entries.len() - 1);
-
-    Ok(())
-}
-
-#[test]
-#[ignore]
-fn db_v1_main_blocks_actives() -> Result<()> {
-    let _lock = MUTEX.lock().expect("MUTEX poisoned");
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(PathBuf::from(DB_PATH)))?;
-
-    let all = unwrap!(db.mb_actives().get(&PubKeyKeyV1::all())?);
-    assert!(all.0.len() > 100);
-
-    // Collect all main blocks actives
-    let entries = db
-        .mb_actives()
-        .iter(..)
-        .collect::<KvResult<Vec<(PubKeyKeyV1, BlockNumberArrayV1)>>>()?;
-    println!("actives_count={}", entries.len() - 1);
-
-    Ok(())
-}
-
-#[test]
-#[ignore]
-fn db_v1_main_blocks_leavers() -> Result<()> {
-    let _lock = MUTEX.lock().expect("MUTEX poisoned");
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(PathBuf::from(DB_PATH)))?;
-
-    let all = unwrap!(db.mb_leavers().get(&PubKeyKeyV1::all())?);
-    assert!(all.0.len() >= 3);
-
-    // Collect all main blocks with leavers
-    let entries = db
-        .mb_leavers()
-        .iter(..)
-        .collect::<KvResult<Vec<(PubKeyKeyV1, BlockNumberArrayV1)>>>()?;
-    println!("leavers_count={}", entries.len() - 1);
-    for (k, v) in entries {
-        println!("{}={:?}", k.0, v.0);
-    }
-
-    Ok(())
-}
-
-#[test]
-#[ignore]
-fn db_v1_main_blocks_excluded() -> Result<()> {
-    let _lock = MUTEX.lock().expect("MUTEX poisoned");
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(PathBuf::from(DB_PATH)))?;
-
-    let all = unwrap!(db.mb_excluded().get(&PubKeyKeyV1::all())?);
-    assert!(all.0.len() >= 50);
-
-    // Collect all main blocks with excluded
-    let entries = db
-        .mb_excluded()
-        .iter(..)
-        .collect::<KvResult<Vec<(PubKeyKeyV1, BlockNumberArrayV1)>>>()?;
-    println!("excluded_count={}", entries.len() - 1);
-    /*for (k, v) in entries {
-        println!("{}={:?}", k.0, v.0);
-    }*/
-
-    Ok(())
-}
-
-#[test]
-#[ignore]
-fn db_v1_main_blocks_revoked() -> Result<()> {
-    let _lock = MUTEX.lock().expect("MUTEX poisoned");
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(PathBuf::from(DB_PATH)))?;
-
-    let all = unwrap!(db.mb_revoked().get(&PubKeyAndSigV1::all())?);
-    assert!(all.0.len() >= 20);
-
-    // Collect all main blocks with revoked
-    let entries = db
-        .mb_revoked()
-        .iter(..)
-        .collect::<KvResult<Vec<(PubKeyAndSigV1, BlockNumberArrayV1)>>>()?;
-    println!("revoked_count={}", entries.len() - 1);
-
-    Ok(())
-}
-
-#[test]
-#[ignore]
-fn db_v1_main_blocks_dividend() -> Result<()> {
-    let _lock = MUTEX.lock().expect("MUTEX poisoned");
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(PathBuf::from(DB_PATH)))?;
-
-    let all = unwrap!(db.mb_dividends().get(&AllKeyV1)?);
-    assert!(all.0.len() >= 900);
-    println!("blocks with dividend={}", all.0.len());
-    println!("last block with dividend={:?}", all.0.last());
-
-    // Collect all main blocks with dividends
-    let entries = db
-        .mb_dividends()
-        .iter(..)
-        .collect::<KvResult<Vec<(AllKeyV1, BlockNumberArrayV1)>>>()?;
-    println!("dividends_keys={}", entries.len());
-
-    Ok(())
-}
-
-#[test]
-#[ignore]
-fn db_v1_main_blocks_transactions() -> Result<()> {
-    let _lock = MUTEX.lock().expect("MUTEX poisoned");
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(PathBuf::from(DB_PATH)))?;
-
-    let all = unwrap!(db.mb_transactions().get(&AllKeyV1)?);
-    assert!(all.0.len() >= 900);
-    println!("blocks with tx={}", all.0.len());
-    println!("last block with tx={:?}", all.0.last());
-
-    // Collect all main blocks with transactions
-    let entries = db
-        .mb_transactions()
-        .iter(..)
-        .collect::<KvResult<Vec<(AllKeyV1, BlockNumberArrayV1)>>>()?;
-    println!("transactions_keys={}", entries.len());
-
-    Ok(())
-}
-
-#[test]
-#[ignore]
-fn db_v1_fork_blocks() -> Result<()> {
-    let _lock = MUTEX.lock().expect("MUTEX poisoned");
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(PathBuf::from(DB_PATH)))?;
-
-    /*let fork_blocks_keys = db
-        .keys_iter::<ForkBlocksColV1, _>(..)
-        .take(1)
-        .collect::<KvResult<Vec<BlockstampKeyV1>>>()?;
-    let one_fork_block = unwrap!(db.get::<ForkBlocksColV1>(&fork_blocks_keys[0])?);
-
-    println!("{:#?}", one_fork_block);*/
-
-    // Collect all fork blocks
-    let entries = db
-        .fork_blocks()
-        .iter(..)
-        .collect::<KvResult<Vec<(BlockstampKeyV1, BlockDbV1)>>>()?;
-    println!("entries_len={}", entries.len());
-
-    Ok(())
-}
-
-#[test]
-#[ignore]
-fn db_v1_bindex() -> Result<()> {
-    let _lock = MUTEX.lock().expect("MUTEX poisoned");
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(PathBuf::from(DB_PATH)))?;
-
-    // Collect all bindex entries
-    let entries = db
-        .bindex()
-        .iter(..)
-        .collect::<KvResult<Vec<(BlockNumberKeyV1, BlockHeadDbV1)>>>()?;
-    println!("entries_len={}", entries.len());
-    //println!("last_bindex={:?}", entries.last());
-    //for (_k, v) in entries {}
-
-    Ok(())
-}
-
-#[test]
-#[ignore]
-fn db_v1_iindex__() -> Result<()> {
-    let _lock = MUTEX.lock().expect("MUTEX poisoned");
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(PathBuf::from(DB_PATH)))?;
-
-    let iindex_keys = db
-        .iindex()
-        .iter(..)
-        .keys()
-        .take(1)
-        .collect::<KvResult<Vec<PubKeyKeyV1>>>()?;
-    let one_iindex_db = unwrap!(db.iindex().get(&iindex_keys[0])?);
-    assert_eq!(one_iindex_db.0[0].pubkey, iindex_keys[0].0.to_base58());
-
-    //println!("{:#?}", one_iindex_db);
-
-    if let Some(ref hash) = one_iindex_db.0[0].hash {
-        let pubkey = unwrap!(db
-            .iindex_hash()
-            .get(&HashKeyV1(unwrap!(Hash::from_hex(hash))))?);
-        assert_eq!(pubkey.0, iindex_keys[0].0);
-    }
-
-    // Count iindex entries
-    let count = db.iindex().count()?;
-    println!("iindex size={}", count);
-
-    // Count members
-    let count_members = db
-        .iindex()
-        .iter(..)
-        .filter_map(KvResult::ok)
-        .filter(|(_k, v)| v.0[0].member.is_some() && unwrap!(v.0[0].member))
-        .count();
-    println!("count_members={}", count_members);
-
-    // Collect all iindex entries
-    let entries = db
-        .iindex()
-        .iter(..)
-        .collect::<KvResult<Vec<(PubKeyKeyV1, IIndexDbV1)>>>()?;
-    println!("entries_len={}", entries.len());
-
-    Ok(())
-}
-
-#[test]
-#[ignore]
-fn db_v1_iindex_hash() -> Result<()> {
-    let _lock = MUTEX.lock().expect("MUTEX poisoned");
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(PathBuf::from(DB_PATH)))?;
-
-    let iindex_entries = db
-        .iindex_hash()
-        .iter(..)
-        .take(3)
-        .collect::<KvResult<Vec<(HashKeyV1, PublicKeySingletonDbV1)>>>()?;
-
-    println!(
-        "(hash, pub)=({:#?},{:#?})",
-        iindex_entries[0].0, iindex_entries[0].1
-    );
-
-    // Collect all iindex/hash entries
-    let entries = db
-        .iindex_hash()
-        .iter(..)
-        .collect::<KvResult<Vec<(HashKeyV1, PublicKeySingletonDbV1)>>>()?;
-    println!("entries_len={}", entries.len());
-
-    Ok(())
-}
-
-#[test]
-#[ignore]
-fn db_v1_iindex_kick() -> Result<()> {
-    let _lock = MUTEX.lock().expect("MUTEX poisoned");
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(PathBuf::from(DB_PATH)))?;
-
-    let entries = db
-        .iindex_kick()
-        .iter(..)
-        .take(3)
-        .collect::<KvResult<Vec<(PubKeyKeyV1, KickDbV1)>>>()?;
-
-    println!("(pub, kick)=({:#?},{:#?})", entries[0].0, entries[0].1);
-
-    // Collect all iindex/kick entries
-    let entries = db
-        .iindex_kick()
-        .iter(..)
-        .collect::<KvResult<Vec<(PubKeyKeyV1, KickDbV1)>>>()?;
-    println!("entries_len={}", entries.len());
-
-    Ok(())
-}
-
-#[test]
-#[ignore]
-fn db_v1_iindex_written_on() -> Result<()> {
-    let _lock = MUTEX.lock().expect("MUTEX poisoned");
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(PathBuf::from(DB_PATH)))?;
-
-    // Collect all iindex/written_on entries
-    let entries = db
-        .iindex_written_on()
-        .iter(..)
-        .collect::<KvResult<Vec<(BlockNumberKeyV1, PublicKeyArrayDbV1)>>>()?;
-    println!("entries_len={}", entries.len());
-    println!("entries={:?}", entries);
-
-    Ok(())
-}
-
-#[test]
-#[ignore]
-fn db_v1_uid_col() -> Result<()> {
-    let _lock = MUTEX.lock().expect("MUTEX poisoned");
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(PathBuf::from(DB_PATH)))?;
-
-    let uid_keys = db
-        .uids()
-        .iter(..)
-        .keys()
-        .take(1)
-        .collect::<KvResult<Vec<UidKeyV1>>>()?;
-    let one_pubkey_db = db.uids().get(&uid_keys[0])?;
-
-    println!(
-        "(uid, pubkey) = ({}, {:#?})",
-        uid_keys[0].0.as_str(),
-        one_pubkey_db
-    );
-
-    let start_key = unwrap!(UidKeyV1::from_str("1b"));
-    let end_key = unwrap!(UidKeyV1::from_str("404_not_found"));
-    let uid_index = db
-        .uids()
-        .iter(start_key..end_key)
-        .collect::<KvResult<Vec<(UidKeyV1, PublicKeySingletonDbV1)>>>()?;
-    assert_eq!(
-        uid_index,
-        vec![(
-            unwrap!(UidKeyV1::from_str("1claude1")),
-            PublicKeySingletonDbV1(unwrap!(PublicKey::from_base58(
-                "8B5XCAHknsckCkMWeGF9FoGibSNZXF9HtAvzxzg3bSyp"
-            )))
-        )],
-    );
-
-    // Collect all iindex/uid entries
-    let entries = db
-        .uids()
-        .iter(..)
-        .collect::<KvResult<Vec<(UidKeyV1, PublicKeySingletonDbV1)>>>()?;
-    println!("entries_len={}", entries.len());
-
-    Ok(())
-}
-
-#[test]
-#[ignore]
-fn db_v1_mindex__() -> Result<()> {
-    let _lock = MUTEX.lock().expect("MUTEX poisoned");
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(PathBuf::from(DB_PATH)))?;
-
-    let mindex_keys = db
-        .mindex()
-        .iter(..)
-        .keys()
-        .take(1)
-        .collect::<KvResult<Vec<PubKeyKeyV1>>>()?;
-    let one_mindex_db = unwrap!(db.mindex().get(&mindex_keys[0])?);
-    assert_eq!(one_mindex_db.0[0].pubkey, mindex_keys[0].0.to_base58());
-
-    //println!("{:#?}", one_mindex_db);
-
-    // Count mindex entries
-    let count = db.mindex().count()?;
-    println!("mindex size={}", count);
-
-    // Collect all mindex entries
-    let entries = db
-        .mindex()
-        .iter(..)
-        .collect::<KvResult<Vec<(PubKeyKeyV1, MIndexDbV1)>>>()?;
-    println!("entries_len={}", entries.len());
-
-    Ok(())
-}
-
-#[test]
-#[ignore]
-fn db_v1_mindex_expires_on() -> Result<()> {
-    let _lock = MUTEX.lock().expect("MUTEX poisoned");
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(PathBuf::from(DB_PATH)))?;
-
-    // Collect all mindex/expires_on entries
-    let entries = db
-        .mindex_expires_on()
-        .iter(..)
-        .collect::<KvResult<Vec<(TimestampKeyV1, PublicKeyArrayDbV1)>>>()?;
-    println!("entries_len={}", entries.len());
-    /*for (k, v) in entries {
-        if k.0 == BlockNumber(u32::MAX) {
-            println!("{:?}", v.0)
-        }
-    }*/
-
-    Ok(())
-}
-
-#[test]
-#[ignore]
-fn db_v1_mindex_revokes_on() -> Result<()> {
-    let _lock = MUTEX.lock().expect("MUTEX poisoned");
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(PathBuf::from(DB_PATH)))?;
-
-    // Collect all mindex/revokes_on entries
-    let entries = db
-        .mindex_revokes_on()
-        .iter(..)
-        .collect::<KvResult<Vec<(TimestampKeyV1, PublicKeyArrayDbV1)>>>()?;
-    println!("entries_len={}", entries.len());
-
-    Ok(())
-}
-
-#[test]
-#[ignore]
-fn db_v1_mindex_written_on() -> Result<()> {
-    let _lock = MUTEX.lock().expect("MUTEX poisoned");
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(PathBuf::from(DB_PATH)))?;
-
-    // Collect all mindex/written_on entries
-    let entries = db
-        .mindex_written_on()
-        .iter(..)
-        .collect::<KvResult<Vec<(BlockNumberKeyV1, PublicKeyArrayDbV1)>>>()?;
-    println!("entries_len={}", entries.len());
-    for (k, v) in entries {
-        if k.0 == BlockNumber(u32::MAX) {
-            println!("{:?}", v.0)
-        }
-    }
-
-    Ok(())
-}
-
-#[test]
-#[ignore]
-fn db_v1_cindex__() -> Result<()> {
-    let _lock = MUTEX.lock().expect("MUTEX poisoned");
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(PathBuf::from(DB_PATH)))?;
-
-    // Collect all bindex entries
-    let entries = db
-        .cindex()
-        .iter(..)
-        .collect::<KvResult<Vec<(PubKeyKeyV1, CIndexDbV1)>>>()?;
-    println!("entries_len={}", entries.len());
-    //println!("last_bindex={:?}", entries.last());
-    for (_k, v) in entries {
-        for cindex_line in v.issued {
-            if cindex_line.created_on_ref.is_some() {
-                println!("cindex_line={:?}", cindex_line)
-            }
-        }
-    }
-
-    Ok(())
-}
-
-#[test]
-#[ignore]
-fn db_v1_cindex_expires_on() -> Result<()> {
-    let _lock = MUTEX.lock().expect("MUTEX poisoned");
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(PathBuf::from(DB_PATH)))?;
-
-    // Collect all cindex/expires_on entries
-    let entries = db
-        .cindex_expires_on()
-        .iter(..)
-        .collect::<KvResult<Vec<(BlockNumberKeyV1, PublicKeyArrayDbV1)>>>()?;
-    println!("entries_len={}", entries.len());
-
-    Ok(())
-}
-
-#[test]
-#[ignore]
-fn db_v1_cindex_written_on() -> Result<()> {
-    let _lock = MUTEX.lock().expect("MUTEX poisoned");
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(PathBuf::from(DB_PATH)))?;
-
-    // Collect all cindex/written_on entries
-    let entries = db
-        .cindex_written_on()
-        .iter(..)
-        .collect::<KvResult<Vec<(BlockNumberKeyV1, PublicKeyArrayDbV1)>>>()?;
-    println!("entries_len={}", entries.len());
-
-    Ok(())
-}
-
-#[test]
-#[ignore]
-fn db_v1_wallet() -> Result<()> {
-    let _lock = MUTEX.lock().expect("MUTEX poisoned");
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(PathBuf::from(DB_PATH)))?;
-
-    // Collect all wallet entries
-    let entries = db
-        .wallet()
-        .iter(..)
-        .collect::<KvResult<Vec<(WalletConditionsV1, WalletDbV1)>>>()?;
-    println!("entries_len={}", entries.len());
-    let mut max_cond_len = 0;
-    for (k, _v) in entries {
-        if k.0.len() > max_cond_len {
-            max_cond_len = k.0.len();
-            println!("k={}", k.0.as_str());
-        }
-    }
-    println!("max_cond_len={}", max_cond_len);
-
-    Ok(())
-}
-
-#[test]
-#[ignore]
-fn db_v1_dividend() -> Result<()> {
-    let _lock = MUTEX.lock().expect("MUTEX poisoned");
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(PathBuf::from(DB_PATH)))?;
-
-    // Collect all level_dividend entries
-    let entries = db
-        .uds()
-        .iter(..)
-        .collect::<KvResult<Vec<(PubKeyKeyV1, UdEntryDbV1)>>>()?;
-    println!("entries_len={}", entries.len());
-
-    println!("entries[0]=({:?}, {:?})", entries[0].0, entries[0].1);
-
-    Ok(())
-}
-
-#[test]
-#[ignore]
-fn db_v1_dividend_written_on() -> Result<()> {
-    let _lock = MUTEX.lock().expect("MUTEX poisoned");
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(PathBuf::from(DB_PATH)))?;
-
-    // Collect all level_dividend/level_dividend_trim_index entries
-    let entries = db
-        .uds_trim()
-        .iter(..)
-        .collect::<KvResult<Vec<(BlockNumberKeyV1, PublicKeyArrayDbV1)>>>()?;
-    println!("entries_len={}", entries.len());
-
-    Ok(())
-}
-
-#[test]
-#[ignore]
-fn db_v1_sindex() -> Result<()> {
-    let _lock = MUTEX.lock().expect("MUTEX poisoned");
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(PathBuf::from(DB_PATH)))?;
-
-    // Collect all level_sindex entries
-    let entries = db
-        .sindex()
-        .iter(..)
-        .collect::<KvResult<Vec<(SourceKeyV1, SIndexDBV1)>>>()?;
-    println!("entries_len={}", entries.len());
-
-    println!("entries[0]=({:?}, {:?})", entries[0].0, entries[0].1);
-
-    Ok(())
-}
-
-#[test]
-#[ignore]
-fn db_v1_sindex_written_on() -> Result<()> {
-    let _lock = MUTEX.lock().expect("MUTEX poisoned");
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(PathBuf::from(DB_PATH)))?;
-
-    // Collect all mindex/written_on entries
-    let entries = db
-        .sindex_written_on()
-        .iter(..)
-        .collect::<KvResult<Vec<(BlockNumberKeyV1, SourceKeyArrayDbV1)>>>()?;
-    println!("entries_len={}", entries.len());
-    for (k, v) in entries {
-        if k.0 == BlockNumber(u32::MAX) {
-            println!("{:?}", v.0)
-        }
-    }
-
-    Ok(())
-}
-
-#[test]
-#[ignore]
-fn db_v1_sindex_consumed_on() -> Result<()> {
-    let _lock = MUTEX.lock().expect("MUTEX poisoned");
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(PathBuf::from(DB_PATH)))?;
-    // Collect all mindex/written_on entries
-    let entries = db
-        .sindex_consumed_on()
-        .iter(..)
-        .collect::<KvResult<Vec<(BlockNumberKeyV1, SourceKeyArrayDbV1)>>>()?;
-    println!("entries_len={}", entries.len());
-    for (k, v) in entries {
-        println!("{:?} => {:?}", k.0, v.0)
-    }
-
-    Ok(())
-}
-
-#[test]
-#[ignore]
-fn db_v1_sindex_conditions_on() -> Result<()> {
-    let _lock = MUTEX.lock().expect("MUTEX poisoned");
-
-    let db = BcV1Db::<LevelDb>::open(LevelDbConf::path(PathBuf::from(DB_PATH)))?;
-
-    // Collect all mindex/written_on entries
-    let entries = db
-        .sindex_conditions()
-        .iter(..)
-        .collect::<KvResult<Vec<(WalletConditionsV1, SourceKeyArrayDbV1)>>>()?;
-    println!("entries_len={}", entries.len());
-    /*for (k, v) in entries {
-        println!("{:?} => {:?}", k.0, v.0)
-    }*/
-
-    Ok(())
-}*/
diff --git a/rust-libs/duniter-global/Cargo.toml b/rust-libs/duniter-global/Cargo.toml
deleted file mode 100644
index a67f4cda7..000000000
--- a/rust-libs/duniter-global/Cargo.toml
+++ /dev/null
@@ -1,18 +0,0 @@
-[package]
-name = "duniter-global"
-version = "1.8.1"
-authors = ["librelois <elois@duniter.org>"]
-license = "AGPL-3.0"
-edition = "2018"
-
-[dependencies]
-async-rwlock = "1.3.0"
-dubp = { version = "0.51.0", features = ["duniter"] }
-duniter-dbs = { path = "../duniter-dbs" }
-flume = "0.10"
-mockall = { version = "0.9", optional = true }
-once_cell = "1.5"
-tokio = { version = "1.2", features = ["io-util", "rt-multi-thread"] }
-
-[features]
-mock = ["mockall"]
diff --git a/rust-libs/duniter-global/src/lib.rs b/rust-libs/duniter-global/src/lib.rs
deleted file mode 100644
index ddfd94679..000000000
--- a/rust-libs/duniter-global/src/lib.rs
+++ /dev/null
@@ -1,155 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-#![deny(
-    clippy::unwrap_used,
-    missing_copy_implementations,
-    trivial_casts,
-    trivial_numeric_casts,
-    unstable_features,
-    unused_import_braces
-)]
-
-pub use tokio;
-
-use async_rwlock::RwLock;
-use dubp::wallet::prelude::SourceAmount;
-use duniter_dbs::BlockMetaV2;
-use once_cell::sync::OnceCell;
-use std::ops::Deref;
-
-pub static SELF_ENDPOINTS: RwLock<Option<Vec<String>>> = RwLock::new(None);
-
-static ASYNC_RUNTIME: OnceCell<tokio::runtime::Runtime> = OnceCell::new();
-static CURRENT_META: RwLock<Option<CurrentMeta>> = RwLock::new(None);
-static SELF_PEER_OLD: RwLock<Option<duniter_dbs::PeerCardDbV1>> = RwLock::new(None);
-
-#[derive(Clone, Copy, Debug, Default)]
-pub struct CurrentMeta {
-    pub current_ud: SourceAmount,
-    pub current_block_meta: BlockMetaV2,
-}
-
-#[derive(Clone, Debug)]
-pub enum GlobalBackGroundTaskMsg {
-    InitCurrentMeta(CurrentMeta),
-    NewCurrentBlock(BlockMetaV2),
-    GetSelfEndpoints(flume::Sender<Option<Vec<String>>>),
-    SetSelfPeerOld(duniter_dbs::PeerCardDbV1),
-}
-
-pub async fn start_global_background_task(recv: flume::Receiver<GlobalBackGroundTaskMsg>) {
-    tokio::spawn(async move {
-        while let Ok(msg) = recv.recv_async().await {
-            match msg {
-                GlobalBackGroundTaskMsg::InitCurrentMeta(current_meta) => {
-                    let mut write_guard = CURRENT_META.write().await;
-                    write_guard.replace(current_meta);
-                }
-                GlobalBackGroundTaskMsg::NewCurrentBlock(current_block_meta) => {
-                    let upgradable_read_guard = CURRENT_META.upgradable_read().await;
-                    let new_current_meta = if let Some(dividend) = current_block_meta.dividend {
-                        CurrentMeta {
-                            current_ud: dividend,
-                            current_block_meta,
-                        }
-                    } else if let Some(current_meta) = upgradable_read_guard.deref() {
-                        CurrentMeta {
-                            current_ud: current_meta.current_ud,
-                            current_block_meta,
-                        }
-                    } else {
-                        CurrentMeta {
-                            current_ud: SourceAmount::ZERO,
-                            current_block_meta,
-                        }
-                    };
-                    let mut write_guard =
-                        async_rwlock::RwLockUpgradableReadGuard::upgrade(upgradable_read_guard)
-                            .await;
-                    write_guard.replace(new_current_meta);
-                }
-                GlobalBackGroundTaskMsg::GetSelfEndpoints(sender) => {
-                    let read_guard = SELF_ENDPOINTS.read().await;
-                    let _ = sender.send_async(read_guard.deref().clone()).await;
-                }
-                GlobalBackGroundTaskMsg::SetSelfPeerOld(self_peer_old) => {
-                    let mut write_guard = SELF_PEER_OLD.write().await;
-                    write_guard.replace(self_peer_old);
-                }
-            }
-        }
-    });
-}
-
-pub fn get_async_runtime() -> &'static tokio::runtime::Runtime {
-    ASYNC_RUNTIME.get_or_init(|| {
-        tokio::runtime::Builder::new_multi_thread()
-            .enable_all()
-            .build()
-            .expect("fail to build tokio runtime")
-    })
-}
-
-#[derive(Clone, Copy, Debug, Default)]
-pub struct AsyncAccessor;
-
-impl AsyncAccessor {
-    pub fn new() -> Self {
-        AsyncAccessor
-    }
-    pub async fn get_current_meta<D: 'static, F: 'static + FnOnce(&CurrentMeta) -> D>(
-        &self,
-        f: F,
-    ) -> Option<D> {
-        let read_guard = CURRENT_META.read().await;
-        if let Some(current_meta) = read_guard.deref() {
-            Some(f(current_meta))
-        } else {
-            None
-        }
-    }
-    pub async fn get_self_peer_old<
-        D: 'static,
-        F: 'static + FnOnce(&duniter_dbs::PeerCardDbV1) -> D,
-    >(
-        &self,
-        f: F,
-    ) -> Option<D> {
-        let read_guard = SELF_PEER_OLD.read().await;
-        if let Some(self_peer_old) = read_guard.deref() {
-            Some(f(self_peer_old))
-        } else {
-            None
-        }
-    }
-}
-
-#[cfg(feature = "mock")]
-mockall::mock! {
-    pub AsyncAccessor {
-        pub async fn get_current_meta<D: 'static, F: 'static + FnOnce(&CurrentMeta) -> D>(
-            &self,
-            f: F,
-        ) -> Option<D>;
-        pub async fn get_self_peer_old<
-            D: 'static,
-            F: 'static + FnOnce(&duniter_dbs::PeerCardDbV1) -> D,
-        >(
-            &self,
-            f: F,
-        ) -> Option<D>;
-    }
-}
diff --git a/rust-libs/duniter-mempools/Cargo.toml b/rust-libs/duniter-mempools/Cargo.toml
deleted file mode 100644
index 244f87ebc..000000000
--- a/rust-libs/duniter-mempools/Cargo.toml
+++ /dev/null
@@ -1,22 +0,0 @@
-[package]
-name = "duniter-mempools"
-version = "0.1.0"
-authors = ["elois <elois@duniter.org>"]
-description = "Duniter mempools"
-repository = "https://git.duniter.org/nodes/typescript/duniter"
-keywords = ["dubp", "duniter", "blockchain", "mempool"]
-license = "AGPL-3.0"
-edition = "2018"
-
-[lib]
-path = "src/lib.rs"
-
-[dependencies]
-dubp = { version = "0.51.0", features = ["duniter"] }
-duniter-dbs = { path = "../duniter-dbs" }
-duniter-bc-reader = { path = "../duniter-bc-reader" }
-duniter-dbs-write-ops = { path = "../duniter-dbs-write-ops" }
-log = "0.4.11"
-thiserror = "1.0.20"
-
-[dev-dependencies]
diff --git a/rust-libs/duniter-mempools/src/lib.rs b/rust-libs/duniter-mempools/src/lib.rs
deleted file mode 100644
index 8a8870aae..000000000
--- a/rust-libs/duniter-mempools/src/lib.rs
+++ /dev/null
@@ -1,133 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-#![deny(
-    clippy::unwrap_used,
-    missing_copy_implementations,
-    trivial_casts,
-    trivial_numeric_casts,
-    unstable_features,
-    unused_import_braces
-)]
-
-use std::borrow::Cow;
-
-use dubp::common::crypto::keys::ed25519::PublicKey;
-use dubp::documents::prelude::*;
-use dubp::documents::transaction::TransactionDocumentV10;
-use duniter_dbs::kv_typed::prelude::*;
-use duniter_dbs::{
-    databases::bc_v2::BcV2DbReadable,
-    databases::txs_mp_v2::{TxsMpV2Db, TxsMpV2DbReadable},
-};
-use thiserror::Error;
-
-#[derive(Clone, Copy, Debug, Default)]
-pub struct Mempools {
-    pub txs: TxsMempool,
-}
-
-#[derive(Debug, Error)]
-pub enum TxMpError {
-    #[error("{0}")]
-    Db(KvError),
-    #[error("Mempool full")]
-    Full,
-    #[error("Transaction already written in blockchain")]
-    TxAlreadyWritten,
-}
-
-impl From<KvError> for TxMpError {
-    fn from(e: KvError) -> Self {
-        TxMpError::Db(e)
-    }
-}
-
-#[derive(Clone, Copy, Debug, Default)]
-pub struct TxsMempool {
-    max_size: usize,
-}
-
-impl TxsMempool {
-    pub fn new(max_size: usize) -> Self {
-        TxsMempool { max_size }
-    }
-    pub fn accept_new_tx<BcDb: BcV2DbReadable, TxsMpDb: TxsMpV2DbReadable>(
-        &self,
-        bc_db_ro: &BcDb,
-        server_pubkey: PublicKey,
-        tx: TransactionDocumentV10,
-        txs_mp_db_ro: &TxsMpDb,
-    ) -> Result<(), TxMpError> {
-        if duniter_bc_reader::tx_exist(bc_db_ro, tx.get_hash())? {
-            Err(TxMpError::TxAlreadyWritten)
-        } else if tx.issuers().contains(&server_pubkey)
-            || txs_mp_db_ro.txs().count()? < self.max_size
-        {
-            Ok(())
-        } else {
-            Err(TxMpError::Full)
-        }
-    }
-
-    pub fn add_pending_tx<B: Backend, BcDb: BcV2DbReadable>(
-        &self,
-        bc_db_ro: &BcDb,
-        server_pubkey: PublicKey,
-        txs_mp_db: &TxsMpV2Db<B>,
-        tx: &TransactionDocumentV10,
-    ) -> Result<(), TxMpError> {
-        if duniter_bc_reader::tx_exist(bc_db_ro, tx.get_hash())? {
-            Err(TxMpError::TxAlreadyWritten)
-        } else if tx.issuers().contains(&server_pubkey) {
-            duniter_dbs_write_ops::txs_mp::add_pending_tx(
-                |_, _| Ok(()),
-                txs_mp_db,
-                Cow::Borrowed(tx),
-            )?;
-            Ok(())
-        } else {
-            duniter_dbs_write_ops::txs_mp::add_pending_tx(
-                |_tx, txs| {
-                    if txs.count()? >= self.max_size {
-                        Err(KvError::Custom(TxMpError::Full.into()))
-                    } else {
-                        Ok(())
-                    }
-                },
-                txs_mp_db,
-                Cow::Borrowed(tx),
-            )?;
-            Ok(())
-        }
-    }
-
-    #[doc(hidden)]
-    pub fn add_pending_tx_force<B: Backend>(
-        &self,
-        txs_mp_db: &TxsMpV2Db<B>,
-        tx: &TransactionDocumentV10,
-    ) -> KvResult<()> {
-        duniter_dbs_write_ops::txs_mp::add_pending_tx(|_, _| Ok(()), txs_mp_db, Cow::Borrowed(tx))?;
-        Ok(())
-    }
-
-    pub fn get_free_rooms<TxsMpDb: TxsMpV2DbReadable>(
-        &self,
-        txs_mp_db_ro: &TxsMpDb,
-    ) -> KvResult<usize> {
-        Ok(self.max_size - txs_mp_db_ro.txs().count()?)
-    }
-}
diff --git a/rust-libs/duniter-module/Cargo.toml b/rust-libs/duniter-module/Cargo.toml
deleted file mode 100644
index 9e1a43b99..000000000
--- a/rust-libs/duniter-module/Cargo.toml
+++ /dev/null
@@ -1,22 +0,0 @@
-[package]
-name = "duniter-module"
-version = "0.1.0"
-authors = ["librelois <elois@duniter.org>"]
-license = "AGPL-3.0"
-edition = "2018"
-
-[dependencies]
-anyhow = "1.0.34"
-async-trait = "0.1.41"
-dubp = { version = "0.51.0", features = ["duniter"] }
-duniter-conf = { path = "../duniter-conf" }
-duniter-dbs = { path = "../duniter-dbs" }
-duniter-global = { path = "../duniter-global" }
-duniter-mempools = { path = "../duniter-mempools" }
-fast-threadpool = "0.2.3"
-log = "0.4"
-
-[dev-dependencies]
-duniter-dbs = { path = "../duniter-dbs", features = ["mem"] }
-paste = "1.0.2"
-tokio = { version = "1.2", features = ["macros", "rt"] }
diff --git a/rust-libs/duniter-module/src/lib.rs b/rust-libs/duniter-module/src/lib.rs
deleted file mode 100644
index 79060eaba..000000000
--- a/rust-libs/duniter-module/src/lib.rs
+++ /dev/null
@@ -1,344 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-#![deny(
-    clippy::unwrap_used,
-    missing_copy_implementations,
-    trivial_casts,
-    trivial_numeric_casts,
-    unstable_features,
-    unused_import_braces
-)]
-
-use dubp::{
-    block::DubpBlockV10,
-    common::prelude::{BlockNumber, Blockstamp},
-    crypto::{hashs::Hash, keys::ed25519::PublicKey},
-    documents::transaction::TransactionDocumentV10,
-};
-use duniter_conf::{DuniterConf, DuniterMode};
-use duniter_dbs::{kv_typed::prelude::*, FileBackend, SharedDbs};
-use duniter_mempools::Mempools;
-use std::path::Path;
-
-pub const SOFTWARE_NAME: &str = "duniter";
-
-pub type Endpoint = String;
-
-#[async_trait::async_trait]
-pub trait DuniterModule: 'static + Sized {
-    const INDEX_BLOCKS: bool = false;
-
-    /// This function is called only if Self::INDEX_BLOCKS is true,
-    /// in this case it must be reimplemented because the default implementation panics.
-    fn apply_block(
-        _block: &DubpBlockV10,
-        _conf: &DuniterConf,
-        _profile_path_opt: Option<&Path>,
-    ) -> KvResult<()> {
-        unreachable!()
-    }
-
-    /// This function is called only if Self::INDEX_BLOCKS is true,
-    /// in this case it must be reimplemented because the default implementation panics.
-    fn revert_block(
-        _block: &DubpBlockV10,
-        _conf: &DuniterConf,
-        _profile_path_opt: Option<&Path>,
-    ) -> KvResult<()> {
-        unreachable!()
-    }
-
-    fn init(
-        conf: &DuniterConf,
-        currency: &str,
-        dbs_pool: &fast_threadpool::ThreadPoolAsyncHandler<SharedDbs<FileBackend>>,
-        mempools: Mempools,
-        mode: DuniterMode,
-        profile_path_opt: Option<&Path>,
-        software_version: &'static str,
-    ) -> anyhow::Result<(Self, Vec<Endpoint>)>;
-
-    async fn start(self) -> anyhow::Result<()>;
-
-    // Needed for BMA only, will be removed when the migration is complete.
-    #[doc(hidden)]
-    fn get_transactions_history_for_bma(
-        _dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
-        _profile_path_opt: Option<&Path>,
-        _pubkey: PublicKey,
-    ) -> KvResult<Option<TxsHistoryForBma>> {
-        Ok(None)
-    }
-    // Needed for BMA only, will be removed when the migration is complete.
-    #[doc(hidden)]
-    fn get_tx_by_hash(
-        _dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
-        _hash: Hash,
-        _profile_path_opt: Option<&Path>,
-    ) -> KvResult<Option<(TransactionDocumentV10, Option<BlockNumber>)>> {
-        Ok(None)
-    }
-}
-
-// Needed for BMA only, will be removed when the migration is complete.
-#[doc(hidden)]
-#[derive(Default)]
-pub struct TxsHistoryForBma {
-    pub sent: Vec<(TransactionDocumentV10, Blockstamp, i64)>,
-    pub received: Vec<(TransactionDocumentV10, Blockstamp, i64)>,
-    pub sending: Vec<TransactionDocumentV10>,
-    pub pending: Vec<TransactionDocumentV10>,
-}
-
-#[macro_export]
-macro_rules! plug_duniter_modules {
-    ([$($M:ty),*], $TxsHistoryForBma:ident) => {
-        paste::paste! {
-            use anyhow::Context as _;
-            #[allow(dead_code)]
-            fn apply_block_modules(
-                block: Arc<DubpBlockV10>,
-                conf: Arc<duniter_conf::DuniterConf>,
-                dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
-                profile_path_opt: Option<std::path::PathBuf>,
-            ) -> KvResult<()> {
-                $(
-                    let [<$M:snake>] = if <$M>::INDEX_BLOCKS {
-                        let block_arc_clone = Arc::clone(&block);
-                        let conf_arc_clone = Arc::clone(&conf);
-                        let profile_path_opt_clone = profile_path_opt.clone();
-                        Some(dbs_pool
-                        .launch(move |_| <$M>::apply_block(
-                            &block_arc_clone,
-                            &conf_arc_clone,
-                            profile_path_opt_clone.as_deref()
-                        ))
-                        .expect("thread pool disconnected"))
-                    } else {
-                        None
-                    };
-                )*
-                $(
-                    if let Some(join_handle) = [<$M:snake>] {
-                        join_handle.join().expect("thread pool disconnected")?;
-                    }
-                )*
-                Ok(())
-            }
-            #[allow(dead_code)]
-            fn apply_chunk_of_blocks_modules(
-                blocks: Arc<[DubpBlockV10]>,
-                conf: Arc<duniter_conf::DuniterConf>,
-                dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
-                profile_path_opt: Option<std::path::PathBuf>,
-            ) -> KvResult<()> {
-                $(
-                    let [<$M:snake>] = if <$M>::INDEX_BLOCKS {
-                        let blocks_arc_clone = Arc::clone(&blocks);
-                        let conf_arc_clone = Arc::clone(&conf);
-                        let profile_path_opt_clone = profile_path_opt.clone();
-                        Some(dbs_pool
-                            .launch(move |_| {
-                                use std::ops::Deref as _;
-                                for block in blocks_arc_clone.deref() {
-                                    <$M>::apply_block(&block, &conf_arc_clone, profile_path_opt_clone.as_deref())?;
-                                }
-                                Ok::<_, KvError>(())
-                            })
-                            .expect("thread pool disconnected"))
-                    } else {
-                        None
-                    };
-                )*
-                $(
-                    if let Some(join_handle) = [<$M:snake>] {
-                        join_handle.join().expect("thread pool disconnected")?;
-                    }
-                )*
-                Ok(())
-            }
-            #[allow(dead_code)]
-            fn revert_block_modules(
-                block: Arc<DubpBlockV10>,
-                conf: Arc<duniter_conf::DuniterConf>,
-                dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
-                profile_path_opt: Option<std::path::PathBuf>,
-            ) -> KvResult<()> {
-                $(
-                    let [<$M:snake>] = if <$M>::INDEX_BLOCKS {
-                        let block_arc_clone = Arc::clone(&block);
-                        let conf_arc_clone = Arc::clone(&conf);
-                        let profile_path_opt_clone = profile_path_opt.clone();
-                        Some(dbs_pool
-                        .launch(move |_| <$M>::revert_block(
-                            &block_arc_clone,
-                            &conf_arc_clone,
-                            profile_path_opt_clone.as_deref()
-                        ))
-                        .expect("thread pool disconnected"))
-                    } else {
-                        None
-                    };
-                )*
-                $(
-                    if let Some(join_handle) = [<$M:snake>] {
-                        join_handle.join().expect("thread pool disconnected")?;
-                    }
-                )*
-                Ok(())
-            }
-            async fn start_duniter_modules(
-                conf: &DuniterConf,
-                currency: String,
-                dbs_pool: fast_threadpool::ThreadPoolAsyncHandler<SharedDbs<FileBackend>>,
-                mempools: duniter_mempools::Mempools,
-                mode: DuniterMode,
-                profile_path_opt: Option<std::path::PathBuf>,
-                software_version: &'static str,
-            ) -> anyhow::Result<()> {
-                let mut all_endpoints = Vec::<String>::new();
-                $(
-                    let ([<$M:snake>], mut endpoints) =<$M>::init(conf, &currency, &dbs_pool, mempools, mode, profile_path_opt.as_deref(), software_version)
-                        .with_context(|| format!("Fail to init module '{}'", stringify!($M)))?;
-                    all_endpoints.append(&mut endpoints);
-                )*
-
-                log::info!("TMP DEBUG SELF_ENDPOINTS={:?}", all_endpoints);
-                duniter_global::SELF_ENDPOINTS.write().await.replace(all_endpoints);
-
-                $(
-                    let [<$M:snake _handle>] = tokio::spawn([<$M:snake>].start());
-                )*
-
-                $(
-                    [<$M:snake _handle>].await.map_err(|e| if e.is_cancelled() {
-                        anyhow::Error::msg(format!("Module '{}' cancelled", stringify!($M)))
-                    } else {
-                        anyhow::Error::msg(format!("Module '{}' panic", stringify!($M)))
-                    })?
-                    .with_context(|| format!("Error on execution of module '{}'", stringify!($M)))?;
-                )*
-
-                Ok(())
-            }
-
-            // Needed for BMA only, will be removed when the migration is complete.
-            #[allow(dead_code)]
-            #[doc(hidden)]
-            fn get_transactions_history_for_bma(
-                dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
-                profile_path_opt: Option<&Path>,
-                pubkey: PublicKey,
-            ) -> KvResult<TxsHistoryForBma> {
-                $(
-                    if let Some(txs_history) = <$M>::get_transactions_history_for_bma(dbs_pool, profile_path_opt, pubkey)? {
-                        return Ok(txs_history);
-                    }
-                )*
-                Ok(TxsHistoryForBma::default())
-            }
-            // Needed for BMA only, will be removed when the migration is complete.
-            #[allow(dead_code)]
-            #[doc(hidden)]
-            fn get_tx_by_hash(
-                dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
-                hash: Hash,
-                profile_path_opt: Option<&Path>,
-            ) -> KvResult<Option<(TransactionDocumentV10, Option<BlockNumber>)>> {
-                $(
-                    if let Some(tx_with_wb) = <$M>::get_tx_by_hash(dbs_pool, hash, profile_path_opt)? {
-                        return Ok(Some(tx_with_wb));
-                    }
-                )*
-                Ok(None)
-            }
-        }
-    };
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use duniter_mempools::TxsMempool;
-
-    struct TestMod1;
-
-    #[async_trait::async_trait]
-    impl DuniterModule for TestMod1 {
-        fn init(
-            _conf: &DuniterConf,
-            _currency: &str,
-            _dbs_pool: &fast_threadpool::ThreadPoolAsyncHandler<SharedDbs<FileBackend>>,
-            _mempools: Mempools,
-            _mode: DuniterMode,
-            profile_path_opt: Option<&Path>,
-            _software_version: &'static str,
-        ) -> anyhow::Result<(Self, Vec<Endpoint>)> {
-            if let Some(profile_path) = profile_path_opt {
-                let _file_path = profile_path.join("test_mod1.json");
-            }
-            Ok((TestMod1, vec![]))
-        }
-
-        async fn start(self) -> anyhow::Result<()> {
-            Ok(())
-        }
-    }
-
-    struct TestMod2;
-
-    #[async_trait::async_trait]
-    impl DuniterModule for TestMod2 {
-        fn init(
-            _conf: &DuniterConf,
-            _currency: &str,
-            _dbs_pool: &fast_threadpool::ThreadPoolAsyncHandler<SharedDbs<FileBackend>>,
-            _mempools: Mempools,
-            _mode: DuniterMode,
-            _profile_path_opt: Option<&Path>,
-            _software_version: &'static str,
-        ) -> anyhow::Result<(Self, Vec<Endpoint>)> {
-            Ok((TestMod2, vec![]))
-        }
-
-        async fn start(self) -> anyhow::Result<()> {
-            Ok(())
-        }
-    }
-
-    #[tokio::test]
-    async fn test_macro_plug_duniter_modules() -> anyhow::Result<()> {
-        plug_duniter_modules!([TestMod1, TestMod2], TxsHistoryForBma);
-
-        let dbs = SharedDbs::mem()?;
-        let threadpool =
-            fast_threadpool::ThreadPool::start(fast_threadpool::ThreadPoolConfig::default(), dbs);
-
-        start_duniter_modules(
-            &DuniterConf::default(),
-            "test".to_owned(),
-            threadpool.into_async_handler(),
-            Mempools {
-                txs: TxsMempool::new(0),
-            },
-            DuniterMode::Sync,
-            None,
-            "",
-        )
-        .await?;
-        Ok(())
-    }
-}
diff --git a/rust-libs/duniter-server/Cargo.toml b/rust-libs/duniter-server/Cargo.toml
index 116a2d505..3cfbc9ed7 100644
--- a/rust-libs/duniter-server/Cargo.toml
+++ b/rust-libs/duniter-server/Cargo.toml
@@ -9,14 +9,8 @@ edition = "2018"
 anyhow = "1.0.34"
 cfg-if = "1.0.0"
 dubp = { version = "0.51.0", features = ["duniter"] }
-duniter-conf = { path = "../duniter-conf" }
-duniter-bc-reader = { path = "../duniter-bc-reader" }
-duniter-dbs = { path = "../duniter-dbs" }
-duniter-dbs-write-ops = { path = "../duniter-dbs-write-ops" }
-duniter-global = { path = "../duniter-global" }
-duniter-gva = { path = "../modules/gva", optional = true }
-duniter-mempools = { path = "../duniter-mempools" }
-duniter-module = { path = "../duniter-module" }
+duniter-core = { git = "https://git.duniter.org/nodes/rust/duniter-core", features = ["bc-writer"] }
+duniter-gva = { git = "https://git.duniter.org/nodes/rust/modules/duniter-gva", optional = true }
 fast-threadpool = "0.2.3"
 flume = "0.10.0"
 log = "0.4.11"
@@ -29,4 +23,4 @@ default = ["gva"]
 gva = ["duniter-gva"]
 
 [dev-dependencies]
-duniter-dbs = { path = "../duniter-dbs", features = ["mem"] }
+duniter-core = { git = "https://git.duniter.org/nodes/rust/duniter-core", features = ["bc-writer", "mem"] }
diff --git a/rust-libs/duniter-server/src/fill_cm.rs b/rust-libs/duniter-server/src/fill_cm.rs
index 90b7aa96d..5251eafeb 100644
--- a/rust-libs/duniter-server/src/fill_cm.rs
+++ b/rust-libs/duniter-server/src/fill_cm.rs
@@ -15,8 +15,8 @@
 
 use crate::*;
 use dubp::wallet::prelude::SourceAmount;
-use duniter_dbs::databases::bc_v2::BcV2DbReadable;
-use duniter_global::{CurrentMeta, GlobalBackGroundTaskMsg};
+use duniter_core::dbs::databases::bc_v2::BcV2DbReadable;
+use duniter_core::global::{CurrentMeta, GlobalBackGroundTaskMsg};
 
 pub(super) fn fill_and_get_current_meta<BcDb: BcV2DbReadable>(
     bc_db_ro: &BcDb,
diff --git a/rust-libs/duniter-server/src/legacy/block_indexer.rs b/rust-libs/duniter-server/src/legacy/block_indexer.rs
index a50a6ab0a..bf271807d 100644
--- a/rust-libs/duniter-server/src/legacy/block_indexer.rs
+++ b/rust-libs/duniter-server/src/legacy/block_indexer.rs
@@ -20,7 +20,7 @@ impl DuniterServer {
         let block = Arc::new(
             DubpBlockV10::from_string_object(&block).map_err(|e| KvError::DeserError(e.into()))?,
         );
-        self.current = Some(duniter_dbs_write_ops::apply_block::apply_block(
+        self.current = Some(duniter_core::dbs_write_ops::apply_block::apply_block(
             &self.bc_db,
             block.clone(),
             self.current,
@@ -39,7 +39,7 @@ impl DuniterServer {
                 .collect::<Result<Vec<_>, _>>()
                 .map_err(|e| KvError::DeserError(e.into()))?,
         );
-        self.current = Some(duniter_dbs_write_ops::apply_block::apply_chunk(
+        self.current = Some(duniter_core::dbs_write_ops::apply_block::apply_chunk(
             &self.bc_db,
             self.current,
             &self.dbs_pool,
@@ -56,13 +56,13 @@ impl DuniterServer {
         let txs_mp_job_handle = self
             .dbs_pool
             .launch(move |dbs| {
-                duniter_dbs_write_ops::txs_mp::revert_block(
+                duniter_core::dbs_write_ops::txs_mp::revert_block(
                     block_arc_clone.transactions(),
                     &dbs.txs_mp_db,
                 )
             })
             .expect("dbs pool disconnected");
-        self.current = duniter_dbs_write_ops::bc::revert_block(&self.bc_db, &block)?;
+        self.current = duniter_core::dbs_write_ops::bc::revert_block(&self.bc_db, &block)?;
         txs_mp_job_handle.join().expect("dbs pool disconnected")?;
         revert_block_modules(block, Arc::new(self.conf.clone()), &self.dbs_pool, None)
     }
diff --git a/rust-libs/duniter-server/src/legacy/dunp.rs b/rust-libs/duniter-server/src/legacy/dunp.rs
index e390f9e65..d153e53b8 100644
--- a/rust-libs/duniter-server/src/legacy/dunp.rs
+++ b/rust-libs/duniter-server/src/legacy/dunp.rs
@@ -18,7 +18,10 @@ use crate::*;
 impl DuniterServer {
     pub fn receive_new_heads(
         &self,
-        heads: Vec<(duniter_dbs::DunpNodeIdV1Db, duniter_dbs::DunpHeadDbV1)>,
+        heads: Vec<(
+            duniter_core::dbs::DunpNodeIdV1Db,
+            duniter_core::dbs::DunpHeadDbV1,
+        )>,
     ) -> KvResult<()> {
         self.dbs_pool
             .execute(move |dbs| {
@@ -32,13 +35,13 @@ impl DuniterServer {
             .expect("dbs pool disconnected")
     }
     pub fn remove_all_peers(&self) -> KvResult<()> {
-        use duniter_dbs::databases::network_v1::NetworkV1DbWritable as _;
+        use duniter_core::dbs::databases::network_v1::NetworkV1DbWritable as _;
         self.dbs_pool
             .execute(move |dbs| dbs.dunp_db.peers_old_write().clear())
             .expect("dbs pool disconnected")
     }
     pub fn remove_peer_by_pubkey(&self, pubkey: PublicKey) -> KvResult<()> {
-        use duniter_dbs::databases::network_v1::NetworkV1DbWritable as _;
+        use duniter_core::dbs::databases::network_v1::NetworkV1DbWritable as _;
         self.dbs_pool
             .execute(move |dbs| dbs.dunp_db.peers_old_write().remove(PubKeyKeyV2(pubkey)))
             .expect("dbs pool disconnected")
@@ -46,12 +49,12 @@ impl DuniterServer {
     pub fn save_peer(&self, new_peer_card: PeerCardDbV1) -> anyhow::Result<()> {
         use dubp::crypto::keys::PublicKey as _;
         let pubkey = PublicKey::from_base58(&new_peer_card.pubkey)?;
-        use duniter_dbs::databases::network_v1::NetworkV1DbWritable as _;
+        use duniter_core::dbs::databases::network_v1::NetworkV1DbWritable as _;
         self.dbs_pool
             .execute(move |dbs| {
                 dbs.dunp_db.peers_old_write().upsert(
                     PubKeyKeyV2(pubkey),
-                    duniter_dbs::PeerCardDbV1 {
+                    duniter_core::dbs::PeerCardDbV1 {
                         version: new_peer_card.version,
                         currency: new_peer_card.currency,
                         pubkey: new_peer_card.pubkey,
@@ -78,8 +81,8 @@ mod tests {
         ed25519::{PublicKey, Signature},
         PublicKey as _,
     };
-    use duniter_dbs::databases::network_v1::NetworkV1DbReadable;
-    use duniter_dbs::PeerCardDbV1;
+    use duniter_core::dbs::databases::network_v1::NetworkV1DbReadable;
+    use duniter_core::dbs::PeerCardDbV1;
 
     use super::*;
 
@@ -89,12 +92,12 @@ mod tests {
         let dbs = server.get_shared_dbs();
 
         let head = (
-            duniter_dbs::DunpNodeIdV1Db::new(53, PublicKey::default()),
-            duniter_dbs::DunpHeadDbV1 {
+            duniter_core::dbs::DunpNodeIdV1Db::new(53, PublicKey::default()),
+            duniter_core::dbs::DunpHeadDbV1 {
                 api: "WS2P".to_owned(),
                 pubkey: PublicKey::default(),
                 blockstamp: Blockstamp::default(),
-                software: duniter_module::SOFTWARE_NAME.to_owned(),
+                software: duniter_core::module::SOFTWARE_NAME.to_owned(),
                 software_version: "test".to_owned(),
                 pow_prefix: 1,
                 free_member_room: 0,
@@ -113,7 +116,7 @@ mod tests {
 
     #[test]
     fn test_save_peer() -> anyhow::Result<()> {
-        use duniter_dbs::databases::network_v1::NetworkV1DbReadable as _;
+        use duniter_core::dbs::databases::network_v1::NetworkV1DbReadable as _;
         let server = DuniterServer::test(DuniterConf::default(), DuniterMode::Start)?;
         let dbs = server.get_shared_dbs();
 
diff --git a/rust-libs/duniter-server/src/legacy/txs_mempool.rs b/rust-libs/duniter-server/src/legacy/txs_mempool.rs
index be7229fe4..3a484b9a2 100644
--- a/rust-libs/duniter-server/src/legacy/txs_mempool.rs
+++ b/rust-libs/duniter-server/src/legacy/txs_mempool.rs
@@ -69,10 +69,10 @@ impl DuniterServer {
             use std::ops::Deref as _;
             for event in events.deref() {
                 match event {
-                    duniter_dbs::databases::txs_mp_v2::TxsEvent::Upsert { key, value } => {
+                    duniter_core::dbs::databases::txs_mp_v2::TxsEvent::Upsert { key, value } => {
                         new_pending_txs.insert(key.0, value.0.clone());
                     }
-                    duniter_dbs::databases::txs_mp_v2::TxsEvent::Remove { key } => {
+                    duniter_core::dbs::databases::txs_mp_v2::TxsEvent::Remove { key } => {
                         new_pending_txs.remove(&key.0);
                     }
                     _ => (),
@@ -99,21 +99,21 @@ impl DuniterServer {
     pub fn remove_all_pending_txs(&self) -> KvResult<()> {
         self.dbs_pool
             .execute(move |dbs| {
-                duniter_dbs_write_ops::txs_mp::remove_all_pending_txs(&dbs.txs_mp_db)
+                duniter_core::dbs_write_ops::txs_mp::remove_all_pending_txs(&dbs.txs_mp_db)
             })
             .expect("dbs pool disconnected")
     }
     pub fn remove_pending_tx_by_hash(&self, hash: Hash) -> KvResult<()> {
         self.dbs_pool
             .execute(move |dbs| {
-                duniter_dbs_write_ops::txs_mp::remove_pending_tx_by_hash(&dbs.txs_mp_db, hash)
+                duniter_core::dbs_write_ops::txs_mp::remove_pending_tx_by_hash(&dbs.txs_mp_db, hash)
             })
             .expect("dbs pool disconnected")
     }
     pub fn trim_expired_non_written_txs(&self, limit_time: i64) -> KvResult<()> {
         self.dbs_pool
             .execute(move |dbs| {
-                duniter_dbs_write_ops::txs_mp::trim_expired_non_written_txs(
+                duniter_core::dbs_write_ops::txs_mp::trim_expired_non_written_txs(
                     &dbs.txs_mp_db,
                     limit_time,
                 )
diff --git a/rust-libs/duniter-server/src/lib.rs b/rust-libs/duniter-server/src/lib.rs
index 210932591..0dd1cb828 100644
--- a/rust-libs/duniter-server/src/lib.rs
+++ b/rust-libs/duniter-server/src/lib.rs
@@ -25,9 +25,9 @@
 mod fill_cm;
 mod legacy;
 
-pub use duniter_conf::{gva_conf::GvaConf, DuniterConf, DuniterMode};
-use duniter_dbs::databases::network_v1::NetworkV1DbWritable;
-pub use duniter_dbs::{
+pub use duniter_core::conf::{gva_conf::GvaConf, DuniterConf, DuniterMode};
+use duniter_core::dbs::databases::network_v1::NetworkV1DbWritable;
+pub use duniter_core::dbs::{
     kv_typed::prelude::KvResult, smallvec, DunpHeadDbV1, DunpNodeIdV1Db, PeerCardDbV1,
 };
 #[cfg(feature = "gva")]
@@ -40,15 +40,15 @@ use dubp::documents::{prelude::*, transaction::TransactionDocumentV10};
 use dubp::{
     block::prelude::*, common::crypto::hashs::Hash, documents_parser::prelude::FromStringObject,
 };
-use duniter_dbs::{
+use duniter_core::dbs::{
     databases::{bc_v2::BcV2Db, txs_mp_v2::TxsMpV2DbReadable},
     kv_typed::prelude::*,
     PendingTxDbV2, PubKeyKeyV2,
 };
-use duniter_dbs::{prelude::*, BlockMetaV2, FileBackend};
-use duniter_global::{tokio, GlobalBackGroundTaskMsg};
-use duniter_mempools::{Mempools, TxMpError, TxsMempool};
-use duniter_module::{plug_duniter_modules, Endpoint, TxsHistoryForBma};
+use duniter_core::dbs::{prelude::*, BlockMetaV2, FileBackend};
+use duniter_core::global::{tokio, GlobalBackGroundTaskMsg};
+use duniter_core::mempools::{Mempools, TxMpError, TxsMempool};
+use duniter_core::module::{plug_duniter_modules, Endpoint, TxsHistoryForBma};
 use fast_threadpool::ThreadPoolConfig;
 use resiter::{filter::Filter, map::Map};
 use std::{
@@ -56,9 +56,13 @@ use std::{
     path::{Path, PathBuf},
 };
 
+// Plug duniter modules
+use duniter_core::conf as duniter_conf;
+use duniter_core::global as duniter_global;
+use duniter_core::mempools as duniter_mempools;
 cfg_if::cfg_if! {
     if #[cfg(feature = "gva")] {
-        use duniter_module::DuniterModule as _;
+        use duniter_core::module::DuniterModule as _;
         plug_duniter_modules!([GvaModule], TxsHistoryForBma);
     } else {
         plug_duniter_modules!([], TxsHistoryForBma);
@@ -72,7 +76,7 @@ pub struct DuniterServer {
     dbs_pool: fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
     global_sender: flume::Sender<GlobalBackGroundTaskMsg>,
     pending_txs_subscriber:
-        flume::Receiver<Arc<Events<duniter_dbs::databases::txs_mp_v2::TxsEvent>>>,
+        flume::Receiver<Arc<Events<duniter_core::dbs::databases::txs_mp_v2::TxsEvent>>>,
     profile_path_opt: Option<PathBuf>,
     shared_dbs: SharedDbs<FileBackend>,
     txs_mempool: TxsMempool,
@@ -94,7 +98,7 @@ impl DuniterServer {
         let txs_mempool = TxsMempool::new(conf.txs_mempool_size);
 
         log::info!("open duniter databases...");
-        let (bc_db, shared_dbs) = duniter_dbs::open_dbs(profile_path_opt)?;
+        let (bc_db, shared_dbs) = duniter_core::dbs::open_dbs(profile_path_opt)?;
         shared_dbs.dunp_db.heads_old_write().clear()?; // Clear WS2Pv1 HEADs
 
         // Create channel with global async task
@@ -127,9 +131,9 @@ impl DuniterServer {
         let profile_path_opt_clone = profile_path_opt.map(ToOwned::to_owned);
         let threadpool_async_handler = threadpool.async_handler();
         std::thread::spawn(move || {
-            duniter_global::get_async_runtime().block_on(async {
+            duniter_core::global::get_async_runtime().block_on(async {
                 // Start global background task
-                duniter_global::start_global_background_task(global_recv).await;
+                duniter_core::global::start_global_background_task(global_recv).await;
 
                 // Start duniter modules
                 if conf_clone.gva.is_some() {
@@ -171,7 +175,7 @@ impl DuniterServer {
             "test".to_owned(),
             duniter_mode,
             None,
-            duniter_module::SOFTWARE_NAME,
+            duniter_core::module::SOFTWARE_NAME,
         )
     }
 }
diff --git a/rust-libs/modules/gva/Cargo.toml b/rust-libs/modules/gva/Cargo.toml
deleted file mode 100644
index e5ed85962..000000000
--- a/rust-libs/modules/gva/Cargo.toml
+++ /dev/null
@@ -1,42 +0,0 @@
-[package]
-name = "duniter-gva"
-version = "0.1.0"
-authors = ["librelois <elois@duniter.org>"]
-license = "AGPL-3.0"
-edition = "2018"
-
-[dependencies]
-anyhow = "1.0.33"
-arrayvec = "0.5.1"
-async-graphql = "2.2.0"
-async-mutex = "1.4.0"
-async-trait = "0.1.41"
-bytes = "1.0"
-dubp = { version = "0.51.0", features = ["duniter"] }
-duniter-bca = { path = "./bca" }
-duniter-conf = { path = "../../duniter-conf" }
-duniter-dbs = { path = "../../duniter-dbs" }
-duniter-gva-db = { path = "./db" }
-duniter-gva-dbs-reader = { path = "./dbs-reader" }
-duniter-gva-indexer = { path = "./indexer" }
-duniter-gva-gql = { path = "./gql" }
-duniter-global = { path = "../../duniter-global" }
-duniter-mempools = { path = "../../duniter-mempools" }
-duniter-module = { path = "../../duniter-module" }
-fast-threadpool = "0.2.3"
-flume = "0.10.0"
-futures = "0.3.6"
-http = "0.2.1"
-log = "0.4.11"
-resiter = "0.4.0"
-serde = { version = "1.0.105", features = ["derive"] }
-serde_urlencoded = "0.7.0"
-tokio = { version = "1.2", features = ["io-util", "rt-multi-thread"] }
-warp = "0.3"
-
-[dev-dependencies]
-duniter-dbs = { path = "../../duniter-dbs", features = ["mem"] }
-mockall = "0.9.1"
-serde_json = "1.0.53"
-tokio = { version = "1.2", features = ["macros", "rt-multi-thread", "time"] }
-unwrap = "1.2.1"
diff --git a/rust-libs/modules/gva/bca/Cargo.toml b/rust-libs/modules/gva/bca/Cargo.toml
deleted file mode 100644
index 4f3713c94..000000000
--- a/rust-libs/modules/gva/bca/Cargo.toml
+++ /dev/null
@@ -1,33 +0,0 @@
-[package]
-name = "duniter-bca"
-version = "0.1.0"
-authors = ["librelois <elois@duniter.org>"]
-license = "AGPL-3.0"
-edition = "2018"
-
-[dependencies]
-anyhow = "1.0.33"
-arrayvec = { version = "0.5.1", features = ["serde"] }
-async-bincode = "0.6.1"
-async_io_stream = { version = "0.3.1", features = [ "tokio_io"] }
-bincode = "1.3"
-dubp = { version = "0.51.0", features = ["duniter"] }
-duniter-bca-types = { path = "types", features = ["duniter"] }
-duniter-dbs = { path = "../../../duniter-dbs" }
-duniter-gva-db = { path = "../db" }
-duniter-gva-dbs-reader = { path = "../dbs-reader" }
-duniter-global = { path = "../../../duniter-global" }
-duniter-mempools = { path = "../../../duniter-mempools" }
-fast-threadpool = "0.2.3"
-futures = "0.3.6"
-once_cell = "1.5"
-smallvec = { version = "1.4.0", features = ["serde", "write"] }
-tokio = { version = "1.2", features = ["macros", "rt-multi-thread"] }
-uninit = "0.4.0"
-
-[dev-dependencies]
-duniter-dbs = { path = "../../../duniter-dbs", features = ["mem"] }
-duniter-gva-dbs-reader = { path = "../dbs-reader", features = ["mock"] }
-duniter-global = { path = "../../../duniter-global", features = ["mock"] }
-tokio = { version = "1.2", features = ["macros", "rt-multi-thread", "time"] }
-mockall = "0.9.1"
diff --git a/rust-libs/modules/gva/bca/src/exec_req_type.rs b/rust-libs/modules/gva/bca/src/exec_req_type.rs
deleted file mode 100644
index 183a3e5e6..000000000
--- a/rust-libs/modules/gva/bca/src/exec_req_type.rs
+++ /dev/null
@@ -1,99 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-mod balances;
-mod current_ud;
-mod last_blockstamp_out_of_fork_window;
-mod members_count;
-mod prepare_simple_payment;
-mod send_txs;
-mod utxos;
-
-use dubp::crypto::keys::KeyPair;
-
-use crate::*;
-
-#[derive(Debug, PartialEq)]
-pub(super) struct ExecReqTypeError(pub(super) String);
-
-impl<E> From<E> for ExecReqTypeError
-where
-    E: ToString,
-{
-    fn from(e: E) -> Self {
-        Self(e.to_string())
-    }
-}
-
-pub(super) async fn execute_req_type(
-    bca_executor: &BcaExecutor,
-    req_type: BcaReqTypeV0,
-    _is_whitelisted: bool,
-) -> Result<BcaRespTypeV0, ExecReqTypeError> {
-    match req_type {
-        BcaReqTypeV0::BalancesOfPubkeys(pubkeys) => {
-            balances::exec_req_balances_of_pubkeys(bca_executor, pubkeys).await
-        }
-        BcaReqTypeV0::FirstUtxosOfPubkeys {
-            amount_target_opt,
-            pubkeys,
-        } => utxos::exec_req_first_utxos_of_pubkeys(bca_executor, amount_target_opt, pubkeys).await,
-        BcaReqTypeV0::LastBlockstampOutOfForkWindow => {
-            last_blockstamp_out_of_fork_window::exec_req_last_blockstamp_out_of_fork_window(
-                bca_executor,
-            )
-            .await
-        }
-        BcaReqTypeV0::MembersCount => members_count::exec_req_members_count(bca_executor).await,
-        BcaReqTypeV0::PrepareSimplePayment(params) => {
-            prepare_simple_payment::exec_req_prepare_simple_payment(bca_executor, params).await
-        }
-        BcaReqTypeV0::ProofServerPubkey { challenge } => Ok(BcaRespTypeV0::ProofServerPubkey {
-            challenge,
-            server_pubkey: bca_executor.self_keypair.public_key(),
-            sig: bca_executor
-                .self_keypair
-                .generate_signator()
-                .sign(&challenge),
-        }),
-        BcaReqTypeV0::Ping => Ok(BcaRespTypeV0::Pong),
-        BcaReqTypeV0::SendTxs(txs) => send_txs::send_txs(bca_executor, txs).await,
-        BcaReqTypeV0::Identities(pubkeys) => {
-            let dbs_reader = bca_executor.dbs_reader();
-            Ok(BcaRespTypeV0::Identities(
-                bca_executor
-                    .dbs_pool
-                    .execute(move |dbs| {
-                        pubkeys
-                            .into_iter()
-                            .map(|pubkey| {
-                                dbs_reader.idty(&dbs.bc_db_ro, pubkey).map(|idty_opt| {
-                                    idty_opt.map(|idty| Identity {
-                                        is_member: idty.is_member,
-                                        username: idty.username,
-                                    })
-                                })
-                            })
-                            .collect::<KvResult<ArrayVec<_>>>()
-                    })
-                    .await??,
-            ))
-        }
-        BcaReqTypeV0::CurrentUd => current_ud::exec_req_current_ud(bca_executor).await,
-        BcaReqTypeV0::BalancesOfScripts(scripts) => {
-            balances::exec_req_balances_of_scripts(bca_executor, scripts).await
-        }
-    }
-}
diff --git a/rust-libs/modules/gva/bca/src/exec_req_type/balances.rs b/rust-libs/modules/gva/bca/src/exec_req_type/balances.rs
deleted file mode 100644
index 6901a9d03..000000000
--- a/rust-libs/modules/gva/bca/src/exec_req_type/balances.rs
+++ /dev/null
@@ -1,61 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-use dubp::{crypto::keys::ed25519::PublicKey, wallet::prelude::WalletScriptV10};
-
-pub(super) async fn exec_req_balances_of_pubkeys(
-    bca_executor: &BcaExecutor,
-    pubkeys: ArrayVec<[PublicKey; 16]>,
-) -> Result<BcaRespTypeV0, ExecReqTypeError> {
-    let dbs_reader = bca_executor.dbs_reader();
-    Ok(BcaRespTypeV0::Balances(
-        bca_executor
-            .dbs_pool
-            .execute(move |_| {
-                pubkeys
-                    .into_iter()
-                    .map(|pubkey| {
-                        dbs_reader
-                            .get_account_balance(&WalletScriptV10::single_sig(pubkey))
-                            .map(|balance_opt| balance_opt.map(|balance| balance.0))
-                    })
-                    .collect::<Result<ArrayVec<_>, _>>()
-            })
-            .await??,
-    ))
-}
-
-pub(super) async fn exec_req_balances_of_scripts(
-    bca_executor: &BcaExecutor,
-    scripts: ArrayVec<[WalletScriptV10; 16]>,
-) -> Result<BcaRespTypeV0, ExecReqTypeError> {
-    let dbs_reader = bca_executor.dbs_reader();
-    Ok(BcaRespTypeV0::Balances(
-        bca_executor
-            .dbs_pool
-            .execute(move |_| {
-                scripts
-                    .into_iter()
-                    .map(|script| {
-                        dbs_reader
-                            .get_account_balance(&script)
-                            .map(|balance_opt| balance_opt.map(|balance| balance.0))
-                    })
-                    .collect::<Result<ArrayVec<_>, _>>()
-            })
-            .await??,
-    ))
-}
diff --git a/rust-libs/modules/gva/bca/src/exec_req_type/current_ud.rs b/rust-libs/modules/gva/bca/src/exec_req_type/current_ud.rs
deleted file mode 100644
index 02823dbba..000000000
--- a/rust-libs/modules/gva/bca/src/exec_req_type/current_ud.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-pub(super) async fn exec_req_current_ud(
-    bca_executor: &BcaExecutor,
-) -> Result<BcaRespTypeV0, ExecReqTypeError> {
-    if let Some(current_ud) = bca_executor
-        .cm_accessor
-        .get_current_meta(|cm| cm.current_ud)
-        .await
-    {
-        Ok(BcaRespTypeV0::CurrentUd(current_ud))
-    } else {
-        Err("no blockchain".into())
-    }
-}
diff --git a/rust-libs/modules/gva/bca/src/exec_req_type/last_blockstamp_out_of_fork_window.rs b/rust-libs/modules/gva/bca/src/exec_req_type/last_blockstamp_out_of_fork_window.rs
deleted file mode 100644
index 41529563e..000000000
--- a/rust-libs/modules/gva/bca/src/exec_req_type/last_blockstamp_out_of_fork_window.rs
+++ /dev/null
@@ -1,99 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-use dubp::common::prelude::*;
-
-pub(super) async fn exec_req_last_blockstamp_out_of_fork_window(
-    bca_executor: &BcaExecutor,
-) -> Result<BcaRespTypeV0, ExecReqTypeError> {
-    if let Some(current_block_number) = bca_executor
-        .cm_accessor
-        .get_current_meta(|cm| cm.current_block_meta.number)
-        .await
-    {
-        let dbs_reader = bca_executor.dbs_reader();
-        bca_executor
-            .dbs_pool
-            .execute(move |dbs| {
-                let block_ref_number = if current_block_number < 101 {
-                    0
-                } else {
-                    current_block_number - 101
-                };
-                let block_ref_hash = dbs_reader
-                    .block(&dbs.bc_db_ro, U32BE(block_ref_number))?
-                    .expect("unreachable")
-                    .hash;
-                Ok::<_, ExecReqTypeError>(BcaRespTypeV0::LastBlockstampOutOfForkWindow(
-                    Blockstamp {
-                        number: BlockNumber(block_ref_number),
-                        hash: BlockHash(block_ref_hash),
-                    },
-                ))
-            })
-            .await?
-    } else {
-        Err("no blockchain".into())
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use crate::tests::*;
-
-    #[tokio::test]
-    async fn test_exec_req_last_blockstamp_out_of_fork_window_no_blockchain() {
-        let mut cm_mock = MockAsyncAccessor::new();
-        cm_mock
-            .expect_get_current_meta::<u32>()
-            .times(1)
-            .returning(|_| None);
-        let dbs_reader = MockDbsReader::new();
-        let bca_executor =
-            create_bca_executor(cm_mock, dbs_reader).expect("fail to create bca executor");
-
-        let resp_res = exec_req_last_blockstamp_out_of_fork_window(&bca_executor).await;
-
-        assert_eq!(resp_res, Err(ExecReqTypeError("no blockchain".into())));
-    }
-
-    #[tokio::test]
-    async fn test_exec_req_last_blockstamp_out_of_fork_window_ok() -> Result<(), ExecReqTypeError> {
-        let mut cm_mock = MockAsyncAccessor::new();
-        cm_mock
-            .expect_get_current_meta::<u32>()
-            .times(1)
-            .returning(|f| Some(f(&CurrentMeta::default())));
-        let mut dbs_reader = MockDbsReader::new();
-        dbs_reader
-            .expect_block()
-            .times(1)
-            .returning(|_, _| Ok(Some(BlockMetaV2::default())));
-
-        let bca_executor =
-            create_bca_executor(cm_mock, dbs_reader).expect("fail to create bca executor");
-
-        let resp = exec_req_last_blockstamp_out_of_fork_window(&bca_executor).await?;
-
-        assert_eq!(
-            resp,
-            BcaRespTypeV0::LastBlockstampOutOfForkWindow(Blockstamp::default())
-        );
-
-        Ok(())
-    }
-}
diff --git a/rust-libs/modules/gva/bca/src/exec_req_type/members_count.rs b/rust-libs/modules/gva/bca/src/exec_req_type/members_count.rs
deleted file mode 100644
index 71b85c6e3..000000000
--- a/rust-libs/modules/gva/bca/src/exec_req_type/members_count.rs
+++ /dev/null
@@ -1,52 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-pub(super) async fn exec_req_members_count(
-    bca_executor: &BcaExecutor,
-) -> Result<BcaRespTypeV0, ExecReqTypeError> {
-    if let Some(members_count) = bca_executor
-        .cm_accessor
-        .get_current_meta(|cm| cm.current_block_meta.members_count)
-        .await
-    {
-        Ok(BcaRespTypeV0::MembersCount(members_count))
-    } else {
-        Err("no blockchain".into())
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use crate::tests::*;
-
-    #[tokio::test]
-    async fn test_exec_req_members_count() {
-        let mut cm_mock = MockAsyncAccessor::new();
-        cm_mock
-            .expect_get_current_meta::<u64>()
-            .times(1)
-            .returning(|f| Some(f(&CurrentMeta::default())));
-        let dbs_reader = MockDbsReader::new();
-        let bca_executor =
-            create_bca_executor(cm_mock, dbs_reader).expect("fail to create bca executor");
-
-        let resp_res = exec_req_members_count(&bca_executor).await;
-
-        assert_eq!(resp_res, Ok(BcaRespTypeV0::MembersCount(0)));
-    }
-}
diff --git a/rust-libs/modules/gva/bca/src/exec_req_type/prepare_simple_payment.rs b/rust-libs/modules/gva/bca/src/exec_req_type/prepare_simple_payment.rs
deleted file mode 100644
index a23a77650..000000000
--- a/rust-libs/modules/gva/bca/src/exec_req_type/prepare_simple_payment.rs
+++ /dev/null
@@ -1,223 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// This program is free software current_block_number: (), current_block_hash: (), inputs: (), inputs_sum: (): 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-use dubp::wallet::prelude::*;
-use duniter_bca_types::prepare_payment::{PrepareSimplePayment, PrepareSimplePaymentResp};
-
-pub(super) async fn exec_req_prepare_simple_payment(
-    bca_executor: &BcaExecutor,
-    params: PrepareSimplePayment,
-) -> Result<BcaRespTypeV0, ExecReqTypeError> {
-    let issuer = params.issuer;
-
-    if let Some(current_meta) = bca_executor.cm_accessor.get_current_meta(|cm| *cm).await {
-        let current_block_meta = current_meta.current_block_meta;
-        let current_ud = current_meta.current_ud;
-        let dbs_reader = bca_executor.dbs_reader();
-        let (amount, block_ref_number, block_ref_hash, (inputs, inputs_sum)) = bca_executor
-            .dbs_pool
-            .execute(move |dbs| {
-                let mut amount = params.amount.to_cents(current_ud);
-                let block_ref_number = if current_block_meta.number < 101 {
-                    0
-                } else {
-                    current_block_meta.number - 101
-                };
-                let block_ref_hash = dbs_reader
-                    .block(&dbs.bc_db_ro, U32BE(block_ref_number))?
-                    .expect("unreachable")
-                    .hash;
-                let current_base = current_block_meta.unit_base as i64;
-
-                if amount.base() > current_base {
-                    Err("too long base".into())
-                } else {
-                    while amount.base() < current_base {
-                        amount = amount.increment_base();
-                    }
-                    Ok::<_, ExecReqTypeError>((
-                        amount,
-                        block_ref_number,
-                        block_ref_hash,
-                        dbs_reader.find_inputs(
-                            &dbs.bc_db_ro,
-                            &dbs.txs_mp_db,
-                            amount,
-                            &WalletScriptV10::single(WalletConditionV10::Sig(issuer)),
-                            false,
-                        )?,
-                    ))
-                }
-            })
-            .await??;
-
-        if inputs_sum < amount {
-            return Err("insufficient balance".into());
-        }
-
-        Ok(BcaRespTypeV0::PrepareSimplePayment(
-            PrepareSimplePaymentResp {
-                current_block_number: block_ref_number,
-                current_block_hash: block_ref_hash,
-                current_ud,
-                inputs,
-                inputs_sum,
-            },
-        ))
-    } else {
-        Err("no blockchain".into())
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use crate::tests::*;
-
-    #[tokio::test]
-    async fn test_exec_req_prepare_simple_payment_no_blockchain() {
-        let mut mock_cm = MockAsyncAccessor::new();
-        mock_cm
-            .expect_get_current_meta::<CurrentMeta>()
-            .times(1)
-            .returning(|_| None);
-        let dbs_reader = MockDbsReader::new();
-        let bca_executor =
-            create_bca_executor(mock_cm, dbs_reader).expect("fail to create bca executor");
-
-        let resp_res = exec_req_prepare_simple_payment(
-            &bca_executor,
-            PrepareSimplePayment {
-                issuer: PublicKey::default(),
-                amount: Amount::Cents(SourceAmount::new(42, 0)),
-            },
-        )
-        .await;
-
-        assert_eq!(resp_res, Err(ExecReqTypeError("no blockchain".into())));
-    }
-
-    #[tokio::test]
-    async fn test_exec_req_prepare_simple_payment_too_long_base() {
-        let mut mock_cm = MockAsyncAccessor::new();
-        mock_cm
-            .expect_get_current_meta::<CurrentMeta>()
-            .times(1)
-            .returning(|f| Some(f(&CurrentMeta::default())));
-        let mut dbs_reader = MockDbsReader::new();
-        dbs_reader
-            .expect_block()
-            .times(1)
-            .returning(|_, _| Ok(Some(BlockMetaV2::default())));
-        let bca_executor =
-            create_bca_executor(mock_cm, dbs_reader).expect("fail to create bca executor");
-
-        let resp_res = exec_req_prepare_simple_payment(
-            &bca_executor,
-            PrepareSimplePayment {
-                issuer: PublicKey::default(),
-                amount: Amount::Cents(SourceAmount::new(42, 1)),
-            },
-        )
-        .await;
-
-        assert_eq!(resp_res, Err(ExecReqTypeError("too long base".into())));
-    }
-
-    #[tokio::test]
-    async fn test_exec_req_prepare_simple_payment_insufficient_balance() {
-        let mut mock_cm = MockAsyncAccessor::new();
-        mock_cm
-            .expect_get_current_meta::<CurrentMeta>()
-            .times(1)
-            .returning(|f| Some(f(&CurrentMeta::default())));
-        let mut dbs_reader = MockDbsReader::new();
-        dbs_reader
-            .expect_block()
-            .times(1)
-            .returning(|_, _| Ok(Some(BlockMetaV2::default())));
-        dbs_reader
-            .expect_find_inputs::<TxsMpV2Db<FileBackend>>()
-            .times(1)
-            .returning(|_, _, _, _, _| Ok((vec![], SourceAmount::default())));
-        let bca_executor =
-            create_bca_executor(mock_cm, dbs_reader).expect("fail to create bca executor");
-
-        let resp_res = exec_req_prepare_simple_payment(
-            &bca_executor,
-            PrepareSimplePayment {
-                issuer: PublicKey::default(),
-                amount: Amount::Cents(SourceAmount::new(42, 0)),
-            },
-        )
-        .await;
-
-        assert_eq!(
-            resp_res,
-            Err(ExecReqTypeError("insufficient balance".into()))
-        );
-    }
-
-    #[tokio::test]
-    async fn test_exec_req_prepare_simple_payment_ok() -> Result<(), ExecReqTypeError> {
-        let input = TransactionInputV10 {
-            amount: SourceAmount::with_base0(57),
-            id: SourceIdV10::Utxo(UtxoIdV10 {
-                tx_hash: Hash::default(),
-                output_index: 3,
-            }),
-        };
-
-        let mut mock_cm = MockAsyncAccessor::new();
-        mock_cm
-            .expect_get_current_meta::<CurrentMeta>()
-            .times(1)
-            .returning(|f| Some(f(&CurrentMeta::default())));
-        let mut dbs_reader = MockDbsReader::new();
-        dbs_reader
-            .expect_block()
-            .times(1)
-            .returning(|_, _| Ok(Some(BlockMetaV2::default())));
-        dbs_reader
-            .expect_find_inputs::<TxsMpV2Db<FileBackend>>()
-            .times(1)
-            .returning(move |_, _, _, _, _| Ok((vec![input], SourceAmount::with_base0(57))));
-        let bca_executor =
-            create_bca_executor(mock_cm, dbs_reader).expect("fail to create bca executor");
-
-        let resp = exec_req_prepare_simple_payment(
-            &bca_executor,
-            PrepareSimplePayment {
-                issuer: PublicKey::default(),
-                amount: Amount::Cents(SourceAmount::new(42, 0)),
-            },
-        )
-        .await?;
-
-        assert_eq!(
-            resp,
-            BcaRespTypeV0::PrepareSimplePayment(PrepareSimplePaymentResp {
-                current_block_number: 0,
-                current_block_hash: Hash::default(),
-                current_ud: SourceAmount::ZERO,
-                inputs: vec![input],
-                inputs_sum: SourceAmount::with_base0(57),
-            })
-        );
-
-        Ok(())
-    }
-}
diff --git a/rust-libs/modules/gva/bca/src/exec_req_type/send_txs.rs b/rust-libs/modules/gva/bca/src/exec_req_type/send_txs.rs
deleted file mode 100644
index e6a5c25c4..000000000
--- a/rust-libs/modules/gva/bca/src/exec_req_type/send_txs.rs
+++ /dev/null
@@ -1,63 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-use dubp::{crypto::keys::KeyPair, documents::transaction::TransactionDocumentTrait};
-use duniter_bca_types::{
-    rejected_tx::{RejectedTx, RejectedTxReason},
-    Txs,
-};
-
-pub(super) async fn send_txs(
-    bca_executor: &BcaExecutor,
-    txs: Txs,
-) -> Result<BcaRespTypeV0, ExecReqTypeError> {
-    let expected_currency = bca_executor.currency.clone();
-
-    let server_pubkey = bca_executor.self_keypair.public_key();
-    let txs_mempool = bca_executor.txs_mempool;
-
-    let mut rejected_txs = Vec::new();
-    for (i, tx) in txs.into_iter().enumerate() {
-        if let Err(e) = tx.verify(Some(&expected_currency)) {
-            rejected_txs.push(RejectedTx {
-                tx_index: i as u16,
-                reason: RejectedTxReason::InvalidTx(e.to_string()),
-            });
-        } else if let Err(rejected_tx) = bca_executor
-            .dbs_pool
-            .execute(move |dbs| {
-                txs_mempool
-                    .add_pending_tx(&dbs.bc_db_ro, server_pubkey, &dbs.txs_mp_db, &tx)
-                    .map_err(|e| RejectedTx {
-                        tx_index: i as u16,
-                        reason: match e {
-                            duniter_mempools::TxMpError::Db(e) => {
-                                RejectedTxReason::DbError(e.to_string())
-                            }
-                            duniter_mempools::TxMpError::Full => RejectedTxReason::MempoolFull,
-                            duniter_mempools::TxMpError::TxAlreadyWritten => {
-                                RejectedTxReason::TxAlreadyWritten
-                            }
-                        },
-                    })
-            })
-            .await?
-        {
-            rejected_txs.push(rejected_tx);
-        }
-    }
-    Ok(BcaRespTypeV0::RejectedTxs(rejected_txs))
-}
diff --git a/rust-libs/modules/gva/bca/src/exec_req_type/utxos.rs b/rust-libs/modules/gva/bca/src/exec_req_type/utxos.rs
deleted file mode 100644
index 249ff1f48..000000000
--- a/rust-libs/modules/gva/bca/src/exec_req_type/utxos.rs
+++ /dev/null
@@ -1,58 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-use dubp::{crypto::keys::ed25519::PublicKey, wallet::prelude::WalletScriptV10};
-
-pub(super) async fn exec_req_first_utxos_of_pubkeys(
-    bca_executor: &BcaExecutor,
-    amount_target_opt: Option<Amount>,
-    pubkeys: ArrayVec<[PublicKey; 16]>,
-) -> Result<BcaRespTypeV0, ExecReqTypeError> {
-    if let Some(current_ud) = bca_executor
-        .cm_accessor
-        .get_current_meta(|cm| cm.current_ud)
-        .await
-    {
-        let dbs_reader = bca_executor.dbs_reader();
-        let scripts: ArrayVec<[WalletScriptV10; 16]> = pubkeys
-            .into_iter()
-            .map(WalletScriptV10::single_sig)
-            .collect();
-        if let Some(amount_target) = amount_target_opt {
-            Ok(BcaRespTypeV0::FirstUtxosOfPubkeys(
-                bca_executor
-                    .dbs_pool
-                    .execute(move |_| {
-                        Ok::<_, ExecReqTypeError>(dbs_reader.first_scripts_utxos(
-                            Some(amount_target.to_cents(current_ud)),
-                            40,
-                            &scripts,
-                        )?)
-                    })
-                    .await??,
-            ))
-        } else {
-            Ok(BcaRespTypeV0::FirstUtxosOfPubkeys(
-                bca_executor
-                    .dbs_pool
-                    .execute(move |_| dbs_reader.first_scripts_utxos(None, 40, &scripts))
-                    .await??,
-            ))
-        }
-    } else {
-        Err("no blockchain".into())
-    }
-}
diff --git a/rust-libs/modules/gva/bca/src/lib.rs b/rust-libs/modules/gva/bca/src/lib.rs
deleted file mode 100644
index 0ac1a1c9f..000000000
--- a/rust-libs/modules/gva/bca/src/lib.rs
+++ /dev/null
@@ -1,412 +0,0 @@
-//  Copyright (C) 2020 Éloïs  req_id: (), resp_type: ()SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-#![deny(
-    clippy::unwrap_used,
-    missing_copy_implementations,
-    trivial_casts,
-    trivial_numeric_casts,
-    unstable_features,
-    unused_import_braces
-)]
-
-mod exec_req_type;
-
-const MAX_BATCH_SIZE: usize = 10;
-const RESP_MIN_SIZE: usize = 64;
-type RespBytes = SmallVec<[u8; RESP_MIN_SIZE]>;
-
-use crate::exec_req_type::ExecReqTypeError;
-#[cfg(test)]
-use crate::tests::AsyncAccessor;
-use arrayvec::ArrayVec;
-use async_bincode::AsyncBincodeReader;
-use async_io_stream::IoStream;
-use bincode::Options as _;
-use dubp::crypto::keys::{ed25519::Ed25519KeyPair, Signator};
-use duniter_bca_types::{
-    amount::Amount, bincode_opts, identity::Identity, BcaReq, BcaReqExecError, BcaReqTypeV0,
-    BcaResp, BcaRespTypeV0, BcaRespV0,
-};
-pub use duniter_dbs::kv_typed::prelude::*;
-use duniter_dbs::{FileBackend, SharedDbs};
-#[cfg(not(test))]
-use duniter_global::AsyncAccessor;
-use duniter_gva_dbs_reader::DbsReader;
-
-use futures::{prelude::stream::FuturesUnordered, StreamExt, TryStream, TryStreamExt};
-use once_cell::sync::OnceCell;
-use smallvec::SmallVec;
-use tokio::task::JoinError;
-
-#[cfg(test)]
-use crate::tests::DbsReaderImpl;
-#[cfg(not(test))]
-use duniter_gva_dbs_reader::DbsReaderImpl;
-
-static BCA_EXECUTOR: OnceCell<BcaExecutor> = OnceCell::new();
-
-pub fn set_bca_executor(
-    currency: String,
-    cm_accessor: AsyncAccessor,
-    dbs_pool: fast_threadpool::ThreadPoolAsyncHandler<SharedDbs<FileBackend>>,
-    dbs_reader: DbsReaderImpl,
-    self_keypair: Ed25519KeyPair,
-    software_version: &'static str,
-    txs_mempool: duniter_mempools::TxsMempool,
-) {
-    BCA_EXECUTOR
-        .set(BcaExecutor {
-            currency,
-            cm_accessor,
-            dbs_pool,
-            dbs_reader,
-            self_keypair,
-            software_version,
-            txs_mempool,
-        })
-        .unwrap_or_else(|_| panic!("BCA_EXECUTOR already set !"))
-}
-
-#[cfg(not(test))]
-pub async fn execute<B, S>(query_body_stream: S, is_whitelisted: bool) -> Vec<u8>
-where
-    B: AsRef<[u8]>,
-    S: 'static + TryStream<Ok = B, Error = std::io::Error> + Send + Unpin,
-{
-    unsafe {
-        BCA_EXECUTOR
-            .get_unchecked()
-            .execute(query_body_stream, is_whitelisted)
-            .await
-    }
-}
-
-#[derive(Clone)]
-struct BcaExecutor {
-    cm_accessor: AsyncAccessor,
-    currency: String,
-    dbs_pool: fast_threadpool::ThreadPoolAsyncHandler<SharedDbs<FileBackend>>,
-    dbs_reader: DbsReaderImpl,
-    self_keypair: Ed25519KeyPair,
-    software_version: &'static str,
-    txs_mempool: duniter_mempools::TxsMempool,
-}
-use uninit::extension_traits::VecCapacity;
-impl BcaExecutor {
-    pub async fn execute<B, S>(&self, query_body_stream: S, is_whitelisted: bool) -> Vec<u8>
-    where
-        B: AsRef<[u8]>,
-        S: 'static + TryStream<Ok = B, Error = std::io::Error> + Send + Unpin,
-    {
-        let async_bincode_reader =
-            AsyncBincodeReader::<IoStream<S, B>, BcaReq>::from(IoStream::new(query_body_stream));
-        self.execute_inner(async_bincode_reader, is_whitelisted)
-            .await
-            .into_iter()
-            .fold(Vec::new(), |mut vec, elem| {
-                // Write resp len
-                let out = vec.reserve_uninit(4);
-                out.copy_from_slice(&u32::to_be_bytes(elem.len() as u32)[..]);
-                unsafe {
-                    // # Safety
-                    //
-                    //   - `.copy_from_slice()` contract guarantees initialization
-                    //     of `out`, which, in turn, from `reserve_uninit`'s contract,
-                    //     leads to the `vec` extra capacity having been initialized.
-                    vec.set_len(vec.len() + 4);
-                }
-
-                // Write resp content
-                let out = vec.reserve_uninit(elem.len());
-                out.copy_from_slice(&elem[..]);
-                unsafe {
-                    // # Safety
-                    //
-                    //   - `.copy_from_slice()` contract guarantees initialization
-                    //     of `out`, which, in turn, from `reserve_uninit`'s contract,
-                    //     leads to the `vec` extra capacity having been initialized.
-                    vec.set_len(vec.len() + elem.len());
-                }
-                vec
-            })
-    }
-
-    async fn execute_inner(
-        &self,
-        stream: impl TryStream<Ok = BcaReq, Error = bincode::Error>,
-        is_whitelisted: bool,
-    ) -> Vec<RespBytes> {
-        match stream
-            .map_ok(|req| {
-                let self_clone = self.clone();
-                tokio::spawn(async move { self_clone.execute_req(req, is_whitelisted).await })
-            })
-            .take(MAX_BATCH_SIZE)
-            .try_collect::<FuturesUnordered<_>>()
-            .await
-        {
-            Ok(futures_unordered) => {
-                futures_unordered
-                    .map(|req_res: Result<BcaResp, JoinError>| {
-                        let resp = match req_res {
-                            Ok(resp) => Ok(resp),
-                            Err(e) => Err(if e.is_cancelled() {
-                                BcaReqExecError::Cancelled
-                            } else if e.is_panic() {
-                                BcaReqExecError::Panic
-                            } else {
-                                BcaReqExecError::Unknown
-                            }),
-                        };
-                        let mut resp_buffer = RespBytes::new();
-                        bincode_opts()
-                            .serialize_into(&mut resp_buffer, &resp)
-                            .expect("unreachable");
-                        resp_buffer
-                    })
-                    .collect()
-                    .await
-            }
-            Err(e) => {
-                let req_res: Result<BcaResp, BcaReqExecError> =
-                    Err(BcaReqExecError::InvalidReq(e.to_string()));
-                let mut resp_buffer = RespBytes::new();
-                bincode_opts()
-                    .serialize_into(&mut resp_buffer, &req_res)
-                    .expect("unreachable");
-                vec![resp_buffer]
-            }
-        }
-    }
-
-    #[inline(always)]
-    async fn execute_req(self, req: BcaReq, is_whitelisted: bool) -> BcaResp {
-        match req {
-            BcaReq::V0(req) => BcaResp::V0(BcaRespV0 {
-                req_id: req.req_id,
-                resp_type: match crate::exec_req_type::execute_req_type(
-                    &self,
-                    req.req_type,
-                    is_whitelisted,
-                )
-                .await
-                {
-                    Ok(resp_type) => resp_type,
-                    Err(e) => BcaRespTypeV0::Error(e.0),
-                },
-            }),
-            _ => BcaResp::UnsupportedVersion,
-        }
-    }
-}
-
-#[cfg(not(test))]
-impl BcaExecutor {
-    #[inline(always)]
-    pub fn dbs_reader(&self) -> DbsReaderImpl {
-        self.dbs_reader
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    pub use dubp::{
-        block::prelude::*,
-        crypto::{
-            hashs::Hash,
-            keys::{ed25519::PublicKey, KeyPair, Seed32},
-        },
-        documents::transaction::TransactionInputV10,
-        wallet::prelude::*,
-    };
-    pub use duniter_bca_types::BcaReqV0;
-    pub use duniter_dbs::databases::bc_v2::{BcV2DbReadable, BcV2DbRo};
-    pub use duniter_dbs::databases::cm_v1::{CmV1Db, CmV1DbReadable};
-    pub use duniter_dbs::databases::txs_mp_v2::{TxsMpV2Db, TxsMpV2DbReadable};
-    pub use duniter_dbs::BlockMetaV2;
-    pub use duniter_global::{CurrentMeta, MockAsyncAccessor};
-    pub use duniter_gva_dbs_reader::MockDbsReader;
-    pub use futures::TryStreamExt;
-
-    pub type AsyncAccessor = duniter_dbs::kv_typed::prelude::Arc<MockAsyncAccessor>;
-    pub type DbsReaderImpl = duniter_dbs::kv_typed::prelude::Arc<MockDbsReader>;
-
-    impl BcaExecutor {
-        #[inline(always)]
-        pub fn dbs_reader(&self) -> DbsReaderImpl {
-            self.dbs_reader.clone()
-        }
-    }
-
-    pub(crate) fn create_bca_executor(
-        mock_cm: MockAsyncAccessor,
-        mock_dbs_reader: MockDbsReader,
-    ) -> KvResult<BcaExecutor> {
-        let dbs = SharedDbs::mem()?;
-        let threadpool =
-            fast_threadpool::ThreadPool::start(fast_threadpool::ThreadPoolConfig::low(), dbs);
-        Ok(BcaExecutor {
-            cm_accessor: duniter_dbs::kv_typed::prelude::Arc::new(mock_cm),
-            currency: "g1".to_owned(),
-            dbs_pool: threadpool.into_async_handler(),
-            dbs_reader: duniter_dbs::kv_typed::prelude::Arc::new(mock_dbs_reader),
-            self_keypair: Ed25519KeyPair::from_seed(
-                Seed32::random().expect("fail to gen random seed"),
-            ),
-            software_version: "test",
-            txs_mempool: duniter_mempools::TxsMempool::new(10),
-        })
-    }
-
-    pub(crate) fn io_stream<B: AsRef<[u8]>>(
-        bytes: B,
-    ) -> impl TryStream<Ok = B, Error = std::io::Error> {
-        futures::stream::iter(std::iter::once(Ok(bytes)))
-    }
-
-    #[tokio::test]
-    async fn test_one_req_ok() -> Result<(), bincode::Error> {
-        let req = BcaReq::V0(BcaReqV0 {
-            req_id: 42,
-            req_type: BcaReqTypeV0::MembersCount,
-        });
-        assert_eq!(bincode_opts().serialized_size(&req)?, 3);
-        let mut bytes = [0u8; 7];
-
-        bincode_opts().serialize_into(&mut bytes[4..], &req)?;
-        bytes[3] = 3;
-
-        use bincode::Options;
-        //println!("bytes_for_bincode={:?}", &bytes[4..]);
-        assert_eq!(req, bincode_opts().deserialize(&bytes[4..])?);
-
-        let mut mock_cm = MockAsyncAccessor::new();
-        mock_cm
-            .expect_get_current_meta::<u64>()
-            .times(1)
-            .returning(|f| Some(f(&CurrentMeta::default())));
-        let bca_executor = create_bca_executor(mock_cm, MockDbsReader::new())
-            .expect("fail to create bca executor");
-
-        //println!("bytes={:?}", bytes);
-        let bytes_res = bca_executor.execute(io_stream(bytes), false).await;
-        //println!("bytes_res={:?}", bytes_res);
-        let bca_res: Vec<Result<BcaResp, BcaReqExecError>> =
-            AsyncBincodeReader::<_, Result<BcaResp, BcaReqExecError>>::from(&bytes_res[..])
-                .try_collect::<Vec<_>>()
-                .await?;
-
-        assert_eq!(
-            bca_res,
-            vec![Ok(BcaResp::V0(BcaRespV0 {
-                req_id: 42,
-                resp_type: BcaRespTypeV0::MembersCount(0)
-            }))]
-        );
-
-        Ok(())
-    }
-
-    #[tokio::test]
-    async fn test_one_req_invalid() -> Result<(), bincode::Error> {
-        let req = BcaReq::V0(BcaReqV0 {
-            req_id: 42,
-            req_type: BcaReqTypeV0::MembersCount,
-        });
-        assert_eq!(bincode_opts().serialized_size(&req)?, 3);
-        let mut bytes = [0u8; 7];
-
-        bincode_opts().serialize_into(&mut bytes[4..], &req)?;
-        bytes[3] = 2;
-
-        use bincode::Options;
-        //println!("bytes_for_bincode={:?}", &bytes[4..]);
-        assert_eq!(req, bincode_opts().deserialize(&bytes[4..])?);
-
-        let bca_executor = create_bca_executor(MockAsyncAccessor::new(), MockDbsReader::new())
-            .expect("fail to create bca executor");
-
-        //println!("bytes={:?}", bytes);
-        let bytes_res = bca_executor.execute(io_stream(bytes), false).await;
-        //println!("bytes_res={:?}", bytes_res);
-        let bca_res: Vec<Result<BcaResp, BcaReqExecError>> =
-            AsyncBincodeReader::<_, Result<BcaResp, BcaReqExecError>>::from(&bytes_res[..])
-                .try_collect::<Vec<_>>()
-                .await?;
-
-        assert_eq!(
-            bca_res,
-            vec![Err(BcaReqExecError::InvalidReq(
-                "io error: unexpected end of file".to_owned()
-            ))]
-        );
-
-        Ok(())
-    }
-
-    #[tokio::test]
-    async fn test_two_reqs_ok() -> Result<(), bincode::Error> {
-        let req1 = BcaReq::V0(BcaReqV0 {
-            req_id: 42,
-            req_type: BcaReqTypeV0::Ping,
-        });
-        assert_eq!(bincode_opts().serialized_size(&req1)?, 3);
-        let req2 = BcaReq::V0(BcaReqV0 {
-            req_id: 57,
-            req_type: BcaReqTypeV0::MembersCount,
-        });
-        assert_eq!(bincode_opts().serialized_size(&req2)?, 3);
-
-        let mut bytes = [0u8; 14];
-        bincode_opts().serialize_into(&mut bytes[4..], &req1)?;
-        bytes[3] = 3;
-        bincode_opts().serialize_into(&mut bytes[11..], &req2)?;
-        bytes[10] = 3;
-
-        let mut mock_cm = MockAsyncAccessor::new();
-        mock_cm
-            .expect_get_current_meta::<u64>()
-            .times(1)
-            .returning(|f| Some(f(&CurrentMeta::default())));
-        let bca_executor = create_bca_executor(mock_cm, MockDbsReader::new())
-            .expect("fail to create bca executor");
-
-        //println!("bytes={:?}", bytes);
-        let bytes_res = bca_executor.execute(io_stream(bytes), false).await;
-        //println!("bytes_res={:?}", bytes_res);
-        let bca_res: Vec<Result<BcaResp, BcaReqExecError>> =
-            AsyncBincodeReader::<_, Result<BcaResp, BcaReqExecError>>::from(&bytes_res[..])
-                .try_collect::<Vec<_>>()
-                .await?;
-
-        assert_eq!(
-            bca_res,
-            vec![
-                Ok(BcaResp::V0(BcaRespV0 {
-                    req_id: 42,
-                    resp_type: BcaRespTypeV0::Pong
-                })),
-                Ok(BcaResp::V0(BcaRespV0 {
-                    req_id: 57,
-                    resp_type: BcaRespTypeV0::MembersCount(0)
-                }))
-            ]
-        );
-
-        Ok(())
-    }
-}
diff --git a/rust-libs/modules/gva/bca/types/Cargo.toml b/rust-libs/modules/gva/bca/types/Cargo.toml
deleted file mode 100644
index ef4fc9023..000000000
--- a/rust-libs/modules/gva/bca/types/Cargo.toml
+++ /dev/null
@@ -1,20 +0,0 @@
-[package]
-name = "duniter-bca-types"
-version = "0.1.0"
-authors = ["librelois <elois@duniter.org>"]
-license = "AGPL-3.0"
-edition = "2018"
-
-[dependencies]
-arrayvec = { version = "0.5.1", features = ["serde"] }
-bincode = "1.3"
-dubp = { version = "0.51.0" }
-serde = { version = "1.0.105", features = ["derive"] }
-smallvec = { version = "1.4.0", features = ["serde"] }
-thiserror = "1.0.20"
-
-[features]
-default = ["duniter"]
-
-client = ["dubp/client"]
-duniter = ["dubp/duniter"]
diff --git a/rust-libs/modules/gva/bca/types/src/amount.rs b/rust-libs/modules/gva/bca/types/src/amount.rs
deleted file mode 100644
index 1682a3141..000000000
--- a/rust-libs/modules/gva/bca/types/src/amount.rs
+++ /dev/null
@@ -1,46 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
-pub enum Amount {
-    Cents(SourceAmount),
-    Uds(f64),
-}
-
-impl Default for Amount {
-    fn default() -> Self {
-        Self::Cents(SourceAmount::ZERO)
-    }
-}
-
-impl Amount {
-    pub fn to_cents(self, ud_amount: SourceAmount) -> SourceAmount {
-        match self {
-            Amount::Cents(sa) => sa,
-            Amount::Uds(f64_) => {
-                if !f64_.is_finite() || f64_ <= 0f64 {
-                    SourceAmount::ZERO
-                } else {
-                    SourceAmount::new(
-                        f64::round(ud_amount.amount() as f64 * f64_) as i64,
-                        ud_amount.base(),
-                    )
-                }
-            }
-        }
-    }
-}
diff --git a/rust-libs/modules/gva/bca/types/src/identity.rs b/rust-libs/modules/gva/bca/types/src/identity.rs
deleted file mode 100644
index e2302a9bf..000000000
--- a/rust-libs/modules/gva/bca/types/src/identity.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
-pub struct Identity {
-    pub is_member: bool,
-    pub username: String,
-}
diff --git a/rust-libs/modules/gva/bca/types/src/lib.rs b/rust-libs/modules/gva/bca/types/src/lib.rs
deleted file mode 100644
index a9b987ba3..000000000
--- a/rust-libs/modules/gva/bca/types/src/lib.rs
+++ /dev/null
@@ -1,144 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-#![deny(
-    clippy::unwrap_used,
-    missing_copy_implementations,
-    trivial_casts,
-    trivial_numeric_casts,
-    unstable_features,
-    unused_import_braces
-)]
-
-pub mod amount;
-pub mod identity;
-pub mod prepare_payment;
-pub mod rejected_tx;
-pub mod utxo;
-
-use crate::amount::Amount;
-use crate::identity::Identity;
-use crate::prepare_payment::{PrepareSimplePayment, PrepareSimplePaymentResp};
-use crate::utxo::Utxo;
-
-use arrayvec::ArrayVec;
-use bincode::Options as _;
-use dubp::crypto::keys::ed25519::{PublicKey, Signature};
-use dubp::wallet::prelude::*;
-use dubp::{common::prelude::Blockstamp, crypto::hashs::Hash};
-use serde::{Deserialize, Serialize};
-use smallvec::SmallVec;
-use thiserror::Error;
-
-// Constants
-
-pub const MAX_FIRST_UTXOS: usize = 40;
-
-// Request
-
-#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
-pub enum BcaReq {
-    V0(BcaReqV0),
-    _V1,
-}
-
-#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
-pub struct BcaReqV0 {
-    pub req_id: usize,
-    pub req_type: BcaReqTypeV0,
-}
-
-#[allow(clippy::large_enum_variant)]
-#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
-pub enum BcaReqTypeV0 {
-    BalancesOfPubkeys(ArrayVec<[PublicKey; 16]>),
-    FirstUtxosOfPubkeys {
-        amount_target_opt: Option<Amount>,
-        pubkeys: ArrayVec<[PublicKey; 16]>,
-    },
-    LastBlockstampOutOfForkWindow,
-    MembersCount,
-    PrepareSimplePayment(PrepareSimplePayment),
-    ProofServerPubkey {
-        challenge: [u8; 16],
-    },
-    Ping,
-    SendTxs(Txs),
-    Identities(ArrayVec<[PublicKey; 16]>),
-    CurrentUd,
-    BalancesOfScripts(ArrayVec<[WalletScriptV10; 16]>),
-}
-
-// Request types helpers
-
-pub type Txs = SmallVec<[dubp::documents::transaction::TransactionDocumentV10; 1]>;
-
-// Response
-
-#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
-pub enum BcaResp {
-    V0(BcaRespV0),
-    UnsupportedVersion,
-}
-
-#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
-pub struct BcaRespV0 {
-    pub req_id: usize,
-    pub resp_type: BcaRespTypeV0,
-}
-
-#[allow(clippy::large_enum_variant)]
-#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
-pub enum BcaRespTypeV0 {
-    Error(String),
-    Balances(ArrayVec<[Option<SourceAmount>; 16]>),
-    FirstUtxosOfPubkeys(Vec<ArrayVec<[Utxo; MAX_FIRST_UTXOS]>>),
-    ProofServerPubkey {
-        challenge: [u8; 16],
-        server_pubkey: PublicKey,
-        sig: Signature,
-    },
-    LastBlockstampOutOfForkWindow(Blockstamp),
-    MembersCount(u64),
-    PrepareSimplePayment(PrepareSimplePaymentResp),
-    Pong,
-    RejectedTxs(Vec<rejected_tx::RejectedTx>),
-    Identities(ArrayVec<[Option<Identity>; 16]>),
-    CurrentUd(SourceAmount),
-}
-
-// Result and error
-
-pub type BcaResult = Result<BcaResp, BcaReqExecError>;
-
-#[derive(Clone, Debug, Deserialize, Error, PartialEq, Eq, Serialize)]
-pub enum BcaReqExecError {
-    #[error("task cancelled")]
-    Cancelled,
-    #[error("Invalid request: {0}")]
-    InvalidReq(String),
-    #[error("task panicked")]
-    Panic,
-    #[error("Unknown error")]
-    Unknown,
-}
-
-// Bincode configuration
-
-pub fn bincode_opts() -> impl bincode::Options {
-    bincode::options()
-        .with_limit(u32::max_value() as u64)
-        .allow_trailing_bytes()
-}
diff --git a/rust-libs/modules/gva/bca/types/src/prepare_payment.rs b/rust-libs/modules/gva/bca/types/src/prepare_payment.rs
deleted file mode 100644
index 2de5d621a..000000000
--- a/rust-libs/modules/gva/bca/types/src/prepare_payment.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-use dubp::documents::transaction::TransactionInputV10;
-
-#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
-pub struct PrepareSimplePayment {
-    pub issuer: PublicKey,
-    pub amount: Amount,
-}
-
-#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
-pub struct PrepareSimplePaymentResp {
-    pub current_block_number: u32,
-    pub current_block_hash: Hash,
-    pub current_ud: SourceAmount,
-    pub inputs: Vec<TransactionInputV10>,
-    pub inputs_sum: SourceAmount,
-}
diff --git a/rust-libs/modules/gva/bca/types/src/rejected_tx.rs b/rust-libs/modules/gva/bca/types/src/rejected_tx.rs
deleted file mode 100644
index 14b06e52b..000000000
--- a/rust-libs/modules/gva/bca/types/src/rejected_tx.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
-pub struct RejectedTx {
-    pub tx_index: u16,
-    pub reason: RejectedTxReason,
-}
-
-#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
-pub enum RejectedTxReason {
-    DbError(String),
-    InvalidTx(String),
-    MempoolFull,
-    TxAlreadyWritten,
-}
diff --git a/rust-libs/modules/gva/bca/types/src/utxo.rs b/rust-libs/modules/gva/bca/types/src/utxo.rs
deleted file mode 100644
index d7716a808..000000000
--- a/rust-libs/modules/gva/bca/types/src/utxo.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Eq, Serialize)]
-pub struct Utxo {
-    pub amount: SourceAmount,
-    pub tx_hash: Hash,
-    pub output_index: u8,
-}
diff --git a/rust-libs/modules/gva/db/Cargo.toml b/rust-libs/modules/gva/db/Cargo.toml
deleted file mode 100644
index a74d1af8f..000000000
--- a/rust-libs/modules/gva/db/Cargo.toml
+++ /dev/null
@@ -1,32 +0,0 @@
-[package]
-name = "duniter-gva-db"
-version = "0.1.0"
-authors = ["elois <elois@duniter.org>"]
-description = "Duniter GVA DB"
-repository = "https://git.duniter.org/nodes/typescript/duniter"
-license = "AGPL-3.0"
-edition = "2018"
-
-[lib]
-path = "src/lib.rs"
-
-[dependencies]
-bincode = "1.2.1"
-chrono = { version = "0.4.15", optional = true }
-duniter-dbs = { path = "../../../duniter-dbs" }
-dubp = { version = "0.51.0", features = ["duniter"] }
-kv_typed = { path = "../../../tools/kv_typed", default-features = false, features = ["sled_backend"] }
-parking_lot = "0.11.0"
-paste = "1.0.2"
-serde = { version = "1.0.105", features = ["derive"] }
-serde_json = "1.0.53"
-uninit = "0.4.0"
-zerocopy = "0.3.0"
-
-[dev-dependencies]
-
-[features]
-#default = ["explorer"]
-
-explorer = ["chrono", "duniter-dbs/explorer", "kv_typed/explorer"]
-leveldb_backend = ["kv_typed/leveldb_backend"]
diff --git a/rust-libs/modules/gva/db/src/keys.rs b/rust-libs/modules/gva/db/src/keys.rs
deleted file mode 100644
index ced890746..000000000
--- a/rust-libs/modules/gva/db/src/keys.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-pub mod gva_utxo_id;
-pub mod wallet_hash_with_bn;
diff --git a/rust-libs/modules/gva/db/src/keys/gva_utxo_id.rs b/rust-libs/modules/gva/db/src/keys/gva_utxo_id.rs
deleted file mode 100644
index 1f624a872..000000000
--- a/rust-libs/modules/gva/db/src/keys/gva_utxo_id.rs
+++ /dev/null
@@ -1,166 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-use uninit::prelude::*;
-
-#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
-pub struct GvaUtxoIdDbV1([u8; 69]); // script hash ++ block_number ++ tx_hash ++ output_index
-
-impl Default for GvaUtxoIdDbV1 {
-    fn default() -> Self {
-        GvaUtxoIdDbV1([0u8; 69])
-    }
-}
-
-impl std::fmt::Display for GvaUtxoIdDbV1 {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(
-            f,
-            "{}:{}:{}:{}",
-            self.get_script_hash(),
-            self.get_block_number(),
-            self.get_tx_hash(),
-            self.get_output_index()
-        )
-    }
-}
-
-impl GvaUtxoIdDbV1 {
-    pub fn get_script_hash(&self) -> Hash {
-        let mut buffer = uninit_array![u8; 32];
-
-        buffer.as_out().copy_from_slice(&self.0[..32]);
-
-        Hash(unsafe { std::mem::transmute(buffer) })
-    }
-    pub fn get_block_number(&self) -> u32 {
-        let mut buffer = uninit_array![u8; 4];
-
-        buffer.as_out().copy_from_slice(&self.0[32..36]);
-
-        u32::from_be_bytes(unsafe { std::mem::transmute(buffer) })
-    }
-    pub fn get_tx_hash(&self) -> Hash {
-        let mut buffer = uninit_array![u8; 32];
-
-        buffer.as_out().copy_from_slice(&self.0[36..68]);
-
-        Hash(unsafe { std::mem::transmute(buffer) })
-    }
-    pub fn get_output_index(&self) -> u8 {
-        self.0[68]
-    }
-    pub fn new(
-        script: WalletScriptV10,
-        block_number: u32,
-        tx_hash: Hash,
-        output_index: u8,
-    ) -> Self {
-        let script_hash = Hash::compute(script.to_string().as_bytes());
-        Self::new_(script_hash, block_number, tx_hash, output_index)
-    }
-    pub fn new_(script_hash: Hash, block_number: u32, tx_hash: Hash, output_index: u8) -> Self {
-        // TODO uncomment when feature const_generics became stable !
-        /*let mut buffer = uninit_array![u8; 69];
-        let (hash_buffer, rest_buffer) = buffer.as_out().split_at_out(32);
-        let (bn_buffer, rest_buffer) = rest_buffer.split_at_out(4);
-        let (tx_hash_buffer, output_index_buffer) = rest_buffer.split_at_out(32);
-        hash_buffer.copy_from_slice(script_hash.as_ref());
-        bn_buffer.copy_from_slice(&block_number.to_be_bytes()[..]);
-        tx_hash_buffer.copy_from_slice(tx_hash.as_ref());
-        output_index_buffer.copy_from_slice(&[output_index]);
-
-        Self(unsafe { std::mem::transmute(buffer) })*/
-        let mut buffer = [0u8; 69];
-        buffer[..32].copy_from_slice(script_hash.as_ref());
-        buffer[32..36].copy_from_slice(&block_number.to_be_bytes()[..]);
-        buffer[36..68].copy_from_slice(tx_hash.as_ref());
-        buffer[68] = output_index;
-        Self(buffer)
-    }
-    pub fn script_interval(script_hash: Hash) -> (Self, Self) {
-        let mut buffer = [0; 69];
-        buffer[..32].copy_from_slice(script_hash.as_ref());
-        let min = Self(buffer);
-        let mut buffer = [255; 69];
-        buffer[..32].copy_from_slice(script_hash.as_ref());
-        let max = Self(buffer);
-
-        (min, max)
-    }
-    pub fn script_block_interval(
-        script_hash: Hash,
-        block_number_start: u32,
-        block_number_end: u32,
-    ) -> (Self, Self) {
-        (
-            Self::new_(script_hash, block_number_start, Hash::default(), 0),
-            Self::new_(script_hash, block_number_end, Hash::max(), u8::MAX),
-        )
-    }
-}
-
-impl AsBytes for GvaUtxoIdDbV1 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        f(&self.0[..])
-    }
-}
-
-impl FromBytes for GvaUtxoIdDbV1 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        if bytes.len() == 69 {
-            // TODO uncomment when feature const_generics became stable !
-            /*let mut buffer = uninit_array![u8; 69];
-            buffer.as_out().copy_from_slice(bytes);
-            Ok(Self(unsafe { std::mem::transmute(buffer) }))*/
-            let mut buffer = [0u8; 69];
-            buffer.copy_from_slice(bytes);
-            Ok(Self(buffer))
-        } else {
-            Err(CorruptedBytes("db corrupted".to_owned()))
-        }
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableKey for GvaUtxoIdDbV1 {
-    fn from_explorer_str(_: &str) -> std::result::Result<Self, FromExplorerKeyErr> {
-        unimplemented!()
-    }
-    fn to_explorer_string(&self) -> KvResult<String> {
-        Ok(self.to_string())
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn utxo_gva_id_new() {
-        let script = WalletScriptV10::single(WalletConditionV10::Csv(86_400));
-        let script_hash = Hash::compute(script.to_string().as_bytes());
-        let tx_hash = Hash::default();
-        let utxo_gva_id = GvaUtxoIdDbV1::new(script, 42, tx_hash, 3);
-
-        assert_eq!(utxo_gva_id.get_script_hash(), script_hash);
-        assert_eq!(utxo_gva_id.get_block_number(), 42);
-        assert_eq!(utxo_gva_id.get_tx_hash(), tx_hash);
-        assert_eq!(utxo_gva_id.get_output_index(), 3);
-    }
-}
diff --git a/rust-libs/modules/gva/db/src/keys/wallet_hash_with_bn.rs b/rust-libs/modules/gva/db/src/keys/wallet_hash_with_bn.rs
deleted file mode 100644
index bb5c767c1..000000000
--- a/rust-libs/modules/gva/db/src/keys/wallet_hash_with_bn.rs
+++ /dev/null
@@ -1,119 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-use std::fmt::Display;
-use uninit::prelude::*;
-
-#[derive(
-    Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, zerocopy::AsBytes, zerocopy::FromBytes,
-)]
-#[repr(transparent)]
-pub struct WalletHashWithBnV1Db([u8; 36]); // wallet_hash ++ block_number
-
-impl WalletHashWithBnV1Db {
-    pub fn new(hash: Hash, block_number: BlockNumber) -> Self {
-        let mut buffer = uninit_array![u8; 36];
-        let (hash_buffer, bn_buffer) = buffer.as_out().split_at_out(32);
-
-        hash_buffer.copy_from_slice(hash.as_ref());
-        bn_buffer.copy_from_slice(&block_number.0.to_be_bytes()[..]);
-
-        Self(unsafe { std::mem::transmute(buffer) })
-    }
-    pub fn get_wallet_hash(&self) -> Hash {
-        let mut buffer = uninit_array![u8; 32];
-
-        buffer.as_out().copy_from_slice(&self.0[..32]);
-        let bytes: [u8; 32] = unsafe { std::mem::transmute(buffer) };
-
-        Hash(bytes)
-    }
-    pub fn get_block_number(&self) -> u32 {
-        let mut buffer = uninit_array![u8; 4];
-
-        buffer.as_out().copy_from_slice(&self.0[32..]);
-
-        u32::from_be_bytes(unsafe { std::mem::transmute(buffer) })
-    }
-    pub fn wallet_hash_interval(wallet_hash: Hash) -> (Self, Self) {
-        (
-            Self::new(wallet_hash, BlockNumber(0)),
-            Self::new(wallet_hash, BlockNumber(u32::MAX)),
-        )
-    }
-}
-
-impl Default for WalletHashWithBnV1Db {
-    fn default() -> Self {
-        WalletHashWithBnV1Db([0u8; 36])
-    }
-}
-
-impl Display for WalletHashWithBnV1Db {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(f, "{}:{}", self.get_wallet_hash(), self.get_block_number())
-    }
-}
-
-impl AsBytes for WalletHashWithBnV1Db {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        f(self.0.as_ref())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for WalletHashWithBnV1Db {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        let layout = zerocopy::LayoutVerified::<_, WalletHashWithBnV1Db>::new(bytes)
-            .ok_or_else(|| CorruptedBytes("corrupted db".to_owned()))?;
-        Ok(*layout)
-    }
-}
-
-impl KeyZc for WalletHashWithBnV1Db {
-    type Ref = Self;
-}
-
-impl ToDumpString for WalletHashWithBnV1Db {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableKey for WalletHashWithBnV1Db {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerKeyErr> {
-        let mut source = source.split(':');
-        let hash_str = source
-            .next()
-            .ok_or_else(|| FromExplorerKeyErr("missing hash".into()))?;
-        let bn_str = source
-            .next()
-            .ok_or_else(|| FromExplorerKeyErr("missing block number".into()))?;
-
-        let hash = Hash::from_hex(hash_str).map_err(|e| FromExplorerKeyErr(e.into()))?;
-        let block_number = bn_str
-            .parse()
-            .map_err(|e: std::num::ParseIntError| FromExplorerKeyErr(e.into()))?;
-
-        Ok(WalletHashWithBnV1Db::new(hash, block_number))
-    }
-    fn to_explorer_string(&self) -> KvResult<String> {
-        Ok(self.to_string())
-    }
-}
diff --git a/rust-libs/modules/gva/db/src/lib.rs b/rust-libs/modules/gva/db/src/lib.rs
deleted file mode 100644
index d19cb94e9..000000000
--- a/rust-libs/modules/gva/db/src/lib.rs
+++ /dev/null
@@ -1,71 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-#![deny(
-    clippy::unwrap_used,
-    missing_copy_implementations,
-    trivial_casts,
-    trivial_numeric_casts,
-    unstable_features,
-    unused_import_braces
-)]
-
-mod keys;
-mod values;
-
-pub use keys::gva_utxo_id::GvaUtxoIdDbV1;
-pub use keys::wallet_hash_with_bn::WalletHashWithBnV1Db;
-pub use values::gva_idty_db::GvaIdtyDbV1;
-pub use values::gva_tx::GvaTxDbV1;
-pub use values::wallet_script_array::WalletScriptArrayV2;
-
-pub(crate) use dubp::common::prelude::*;
-pub(crate) use dubp::crypto::hashs::Hash;
-pub(crate) use dubp::wallet::prelude::*;
-pub(crate) use duniter_dbs::smallvec::SmallVec;
-pub(crate) use duniter_dbs::{
-    CorruptedBytes, HashKeyV2, PubKeyKeyV2, SourceAmountValV2, ToDumpString, WalletConditionsV2,
-};
-pub(crate) use kv_typed::db_schema;
-pub(crate) use kv_typed::prelude::*;
-pub(crate) use serde::{Deserialize, Serialize};
-pub(crate) use std::collections::BTreeSet;
-
-db_schema!(
-    GvaV1,
-    [
-        ["blocks_by_common_time", BlocksByCommonTime, U64BE, u32],
-        ["blocks_with_ud", BlocksWithUd, U32BE, ()],
-        ["blockchain_time", BlockchainTime, U32BE, u64],
-        ["txs", Txs, HashKeyV2, GvaTxDbV1],
-        ["txs_by_block", TxsByBlock, U32BE, Vec<Hash>],
-        ["txs_by_issuer", TxsByIssuer, WalletHashWithBnV1Db, BTreeSet<Hash>],
-        ["txs_by_recipient", TxsByRecipient, WalletHashWithBnV1Db, BTreeSet<Hash>],
-        [
-            "scripts_by_pubkey",
-            ScriptsByPubkey,
-            PubKeyKeyV2,
-            WalletScriptArrayV2
-        ],
-        [
-            "gva_utxos",
-            GvaUtxos,
-            GvaUtxoIdDbV1,
-            SourceAmountValV2
-        ],
-        ["balances", Balances, WalletConditionsV2, SourceAmountValV2],
-        ["gva_identities", GvaIdentities, PubKeyKeyV2, GvaIdtyDbV1],
-    ]
-);
diff --git a/rust-libs/modules/gva/db/src/values.rs b/rust-libs/modules/gva/db/src/values.rs
deleted file mode 100644
index ed42095fa..000000000
--- a/rust-libs/modules/gva/db/src/values.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-pub mod gva_idty_db;
-pub mod gva_tx;
-pub mod wallet_script_array;
diff --git a/rust-libs/modules/gva/db/src/values/gva_idty_db.rs b/rust-libs/modules/gva/db/src/values/gva_idty_db.rs
deleted file mode 100644
index 9bb918af8..000000000
--- a/rust-libs/modules/gva/db/src/values/gva_idty_db.rs
+++ /dev/null
@@ -1,54 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
-pub struct GvaIdtyDbV1 {
-    pub is_member: bool,
-    pub joins: SmallVec<[BlockNumber; 2]>,
-    pub leaves: BTreeSet<BlockNumber>,
-    pub first_ud: Option<BlockNumber>,
-}
-
-impl AsBytes for GvaIdtyDbV1 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        f(&bincode::serialize(&self).unwrap_or_else(|_| unreachable!()))
-    }
-}
-
-impl kv_typed::prelude::FromBytes for GvaIdtyDbV1 {
-    type Err = bincode::Error;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        bincode::deserialize(bytes)
-    }
-}
-
-impl ToDumpString for GvaIdtyDbV1 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableValue for GvaIdtyDbV1 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerValueErr> {
-        serde_json::from_str(source).map_err(|e| FromExplorerValueErr(e.into()))
-    }
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        serde_json::to_value(&self).map_err(|e| KvError::DeserError(e.into()))
-    }
-}
diff --git a/rust-libs/modules/gva/db/src/values/gva_tx.rs b/rust-libs/modules/gva/db/src/values/gva_tx.rs
deleted file mode 100644
index 258fae77c..000000000
--- a/rust-libs/modules/gva/db/src/values/gva_tx.rs
+++ /dev/null
@@ -1,56 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-use dubp::documents::transaction::TransactionDocumentV10;
-
-#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
-pub struct GvaTxDbV1 {
-    pub tx: TransactionDocumentV10,
-    pub written_block: Blockstamp,
-    pub written_time: i64,
-}
-
-impl AsBytes for GvaTxDbV1 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        let bytes = bincode::serialize(self).unwrap_or_else(|_| unreachable!());
-        f(bytes.as_ref())
-    }
-}
-
-impl kv_typed::prelude::FromBytes for GvaTxDbV1 {
-    type Err = CorruptedBytes;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        bincode::deserialize(&bytes).map_err(|e| CorruptedBytes(format!("{}: '{:?}'", e, bytes)))
-    }
-}
-
-impl ToDumpString for GvaTxDbV1 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableValue for GvaTxDbV1 {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerValueErr> {
-        Self::from_bytes(source.as_bytes()).map_err(|e| FromExplorerValueErr(e.0.into()))
-    }
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        serde_json::to_value(self).map_err(|e| KvError::DeserError(e.into()))
-    }
-}
diff --git a/rust-libs/modules/gva/db/src/values/wallet_script_array.rs b/rust-libs/modules/gva/db/src/values/wallet_script_array.rs
deleted file mode 100644
index d0b4fa932..000000000
--- a/rust-libs/modules/gva/db/src/values/wallet_script_array.rs
+++ /dev/null
@@ -1,53 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-#[derive(Debug, Default, PartialEq)]
-pub struct WalletScriptArrayV2(pub std::collections::HashSet<WalletScriptV10>);
-
-impl AsBytes for WalletScriptArrayV2 {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        f(&bincode::serialize(&self.0).unwrap_or_else(|_| unreachable!()))
-    }
-}
-
-impl kv_typed::prelude::FromBytes for WalletScriptArrayV2 {
-    type Err = bincode::Error;
-
-    fn from_bytes(bytes: &[u8]) -> std::result::Result<Self, Self::Err> {
-        Ok(Self(bincode::deserialize(bytes)?))
-    }
-}
-
-impl ToDumpString for WalletScriptArrayV2 {
-    fn to_dump_string(&self) -> String {
-        todo!()
-    }
-}
-
-#[cfg(feature = "explorer")]
-impl ExplorableValue for WalletScriptArrayV2 {
-    fn from_explorer_str(_: &str) -> std::result::Result<Self, FromExplorerValueErr> {
-        unimplemented!()
-    }
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        Ok(serde_json::Value::Array(
-            self.0
-                .iter()
-                .map(|script| serde_json::Value::String(script.to_string()))
-                .collect(),
-        ))
-    }
-}
diff --git a/rust-libs/modules/gva/dbs-reader/Cargo.toml b/rust-libs/modules/gva/dbs-reader/Cargo.toml
deleted file mode 100644
index 5236284f2..000000000
--- a/rust-libs/modules/gva/dbs-reader/Cargo.toml
+++ /dev/null
@@ -1,31 +0,0 @@
-[package]
-name = "duniter-gva-dbs-reader"
-version = "0.1.0"
-authors = ["elois <elois@duniter.org>"]
-description = "Duniter GVA DBs read operations"
-repository = "https://git.duniter.org/nodes/typescript/duniter"
-keywords = ["dubp", "duniter", "blockchain", "database"]
-license = "AGPL-3.0"
-edition = "2018"
-
-[lib]
-path = "src/lib.rs"
-
-[features]
-mock = ["mockall"]
-
-[dependencies]
-anyhow = "1.0.34"
-arrayvec = "0.5.1"
-duniter-bca-types = { path = "../bca/types" }
-duniter-dbs = { path = "../../../duniter-dbs" }
-duniter-gva-db = { path = "../db" }
-dubp = { version = "0.51.0", features = ["duniter"] }
-mockall = { version = "0.9.1", optional = true }
-resiter = "0.4.0"
-
-[dev-dependencies]
-duniter-dbs = { path = "../../../duniter-dbs", features = ["mem"] }
-maplit = "1.0.2"
-smallvec = { version = "1.4.0", features = ["serde", "write"] }
-unwrap = "1.2.1"
diff --git a/rust-libs/modules/gva/dbs-reader/src/block.rs b/rust-libs/modules/gva/dbs-reader/src/block.rs
deleted file mode 100644
index c4704b4c9..000000000
--- a/rust-libs/modules/gva/dbs-reader/src/block.rs
+++ /dev/null
@@ -1,228 +0,0 @@
-//  Copyright (C) 2021 Pascal Engélibert
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Clone, Copy, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
-pub struct BlockCursor {
-    pub number: BlockNumber,
-}
-impl std::fmt::Display for BlockCursor {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(f, "{}", self.number)
-    }
-}
-
-impl FromStr for BlockCursor {
-    type Err = WrongCursor;
-
-    fn from_str(s: &str) -> Result<Self, Self::Err> {
-        Ok(Self {
-            number: s.parse().map_err(|_| WrongCursor)?,
-        })
-    }
-}
-
-impl DbsReaderImpl {
-    pub(super) fn block_(
-        &self,
-        bc_db: &BcV2DbRo<FileBackend>,
-        number: U32BE,
-    ) -> KvResult<Option<duniter_dbs::BlockMetaV2>> {
-        bc_db.blocks_meta().get(&number)
-    }
-
-    pub(super) fn blocks_(
-        &self,
-        bc_db: &BcV2DbRo<FileBackend>,
-        page_info: PageInfo<BlockCursor>,
-    ) -> KvResult<PagedData<Vec<(BlockCursor, duniter_dbs::BlockMetaV2)>>> {
-        let last_block_number = bc_db
-            .blocks_meta()
-            .iter_rev(.., |it| it.values().next_res())?
-            .ok_or_else(|| KvError::Custom("Empty blockchain".into()))?
-            .number;
-
-        let first_cursor_opt = if page_info.not_all() {
-            Some(BlockCursor {
-                number: BlockNumber(0),
-            })
-        } else {
-            None
-        };
-
-        let last_cursor_opt = if page_info.not_all() {
-            Some(BlockCursor {
-                number: BlockNumber(last_block_number),
-            })
-        } else {
-            None
-        };
-
-        let k_min = U32BE(if page_info.order {
-            page_info.pos.map_or_else(|| 0, |pos| pos.number.0)
-        } else {
-            page_info.limit_opt.map_or_else(
-                || 0,
-                |limit| {
-                    page_info
-                        .pos
-                        .map_or_else(|| last_block_number + 1, |pos| pos.number.0)
-                        .saturating_sub(limit.get() as u32 - 1)
-                },
-            )
-        });
-        let k_max = U32BE(if page_info.order {
-            page_info.limit_opt.map_or_else(
-                || last_block_number + 1,
-                |limit| {
-                    page_info.pos.map_or_else(
-                        || limit.get() as u32,
-                        |pos| pos.number.0.saturating_add(limit.get() as u32),
-                    )
-                },
-            )
-        } else {
-            page_info.pos.map_or_else(
-                || last_block_number + 1,
-                |pos| pos.number.0.saturating_add(1),
-            )
-        });
-
-        let blocks: Vec<(BlockCursor, duniter_dbs::BlockMetaV2)> = if page_info.order {
-            bc_db.blocks_meta().iter(k_min..k_max, blocks_inner)?
-        } else {
-            bc_db.blocks_meta().iter_rev(k_min..k_max, blocks_inner)?
-        };
-
-        Ok(PagedData {
-            has_next_page: has_next_page(
-                blocks
-                    .iter()
-                    .map(|(block_cursor, _block)| block_cursor.into()),
-                last_cursor_opt,
-                page_info,
-                page_info.order,
-            ),
-            has_previous_page: has_previous_page(
-                blocks
-                    .iter()
-                    .map(|(block_cursor, _block)| block_cursor.into()),
-                first_cursor_opt,
-                page_info,
-                page_info.order,
-            ),
-            data: blocks,
-        })
-    }
-}
-
-fn blocks_inner<I>(blocks_iter: I) -> KvResult<Vec<(BlockCursor, duniter_dbs::BlockMetaV2)>>
-where
-    I: Iterator<Item = KvResult<(U32BE, BlockMetaV2)>>,
-{
-    blocks_iter
-        .map(|block_res| {
-            block_res.map(|block| {
-                (
-                    BlockCursor {
-                        number: BlockNumber(block.0 .0),
-                    },
-                    block.1,
-                )
-            })
-        })
-        .collect()
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use duniter_dbs::databases::bc_v2::BcV2DbWritable;
-    use std::num::NonZeroUsize;
-
-    #[test]
-    fn test_block() -> KvResult<()> {
-        let bc_db = duniter_dbs::databases::bc_v2::BcV2Db::<Mem>::open(MemConf::default())?;
-        let bc_db_ro = bc_db.get_ro_handler();
-        let db_reader = DbsReaderImpl::mem();
-
-        bc_db
-            .blocks_meta_write()
-            .upsert(U32BE(0), duniter_dbs::BlockMetaV2::default())?;
-
-        assert_eq!(
-            db_reader.block(&bc_db_ro, U32BE(0))?,
-            Some(duniter_dbs::BlockMetaV2::default())
-        );
-
-        Ok(())
-    }
-
-    #[test]
-    fn test_blocks() -> KvResult<()> {
-        let bc_db = duniter_dbs::databases::bc_v2::BcV2Db::<Mem>::open(MemConf::default())?;
-        let bc_db_ro = bc_db.get_ro_handler();
-        let db_reader = DbsReaderImpl::mem();
-
-        for i in 0..20 {
-            bc_db.blocks_meta_write().upsert(
-                U32BE(i),
-                duniter_dbs::BlockMetaV2 {
-                    number: i,
-                    ..Default::default()
-                },
-            )?;
-        }
-
-        let blocks = db_reader.blocks(
-            &bc_db_ro,
-            PageInfo {
-                pos: Some(BlockCursor {
-                    number: BlockNumber(10),
-                }),
-                order: true,
-                limit_opt: NonZeroUsize::new(3),
-            },
-        )?;
-
-        assert_eq!(blocks.data.len(), 3);
-        assert_eq!(blocks.data[0].1.number, 10);
-        assert_eq!(blocks.data[1].1.number, 11);
-        assert_eq!(blocks.data[2].1.number, 12);
-        assert!(blocks.has_previous_page);
-        assert!(blocks.has_next_page);
-
-        let blocks = db_reader.blocks(
-            &bc_db_ro,
-            PageInfo {
-                pos: Some(BlockCursor {
-                    number: BlockNumber(10),
-                }),
-                order: false,
-                limit_opt: NonZeroUsize::new(3),
-            },
-        )?;
-
-        assert_eq!(blocks.data.len(), 3);
-        assert_eq!(blocks.data[0].1.number, 10);
-        assert_eq!(blocks.data[1].1.number, 9);
-        assert_eq!(blocks.data[2].1.number, 8);
-        assert!(blocks.has_previous_page);
-        assert!(blocks.has_next_page);
-
-        Ok(())
-    }
-}
diff --git a/rust-libs/modules/gva/dbs-reader/src/current_frame.rs b/rust-libs/modules/gva/dbs-reader/src/current_frame.rs
deleted file mode 100644
index 4ca4c48dc..000000000
--- a/rust-libs/modules/gva/dbs-reader/src/current_frame.rs
+++ /dev/null
@@ -1,33 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use duniter_dbs::BlockMetaV2;
-
-use crate::*;
-
-impl DbsReaderImpl {
-    pub(super) fn get_current_frame_<BcDb: 'static + BcV2DbReadable>(
-        &self,
-        bc_db: &BcDb,
-        current_block_meta: &BlockMetaV2,
-    ) -> anyhow::Result<Vec<BlockMetaV2>> {
-        let issuers_frame = current_block_meta.issuers_frame;
-        let start = U32BE(current_block_meta.number + 1 - issuers_frame as u32);
-        bc_db
-            .blocks_meta()
-            .iter_rev(start.., |it| it.values().collect::<KvResult<_>>())
-            .map_err(Into::into)
-    }
-}
diff --git a/rust-libs/modules/gva/dbs-reader/src/find_inputs.rs b/rust-libs/modules/gva/dbs-reader/src/find_inputs.rs
deleted file mode 100644
index a896ed579..000000000
--- a/rust-libs/modules/gva/dbs-reader/src/find_inputs.rs
+++ /dev/null
@@ -1,241 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::{
-    uds_of_pubkey::UdsWithSum,
-    utxos::{UtxoCursor, UtxosWithSum},
-    *,
-};
-use dubp::{documents::transaction::TransactionInputV10, wallet::prelude::*};
-
-pub(super) const MIN_AMOUNT: i64 = 100;
-
-impl DbsReaderImpl {
-    pub(super) fn find_inputs_<TxsMpDb: 'static + TxsMpV2DbReadable>(
-        &self,
-        bc_db: &BcV2DbRo<FileBackend>,
-        txs_mp_db: &TxsMpDb,
-        amount: SourceAmount,
-        script: &WalletScriptV10,
-        use_mempool_sources: bool,
-    ) -> anyhow::Result<(Vec<TransactionInputV10>, SourceAmount)> {
-        // Pending UTXOs
-        let (mut inputs, mut inputs_sum) = if use_mempool_sources {
-            txs_mp_db
-                .outputs_by_script()
-                .get_ref_slice(duniter_dbs::WalletConditionsV2::from_ref(script), |utxos| {
-                    let mut sum = SourceAmount::ZERO;
-                    let inputs = utxos
-                        .iter()
-                        .filter(|utxo| {
-                            !txs_mp_db
-                                .utxos_ids()
-                                .contains_key(&UtxoIdDbV2(*utxo.tx_hash(), utxo.output_index()))
-                                .unwrap_or(true)
-                        })
-                        .copied()
-                        .map(|utxo| {
-                            let amount = *utxo.amount();
-                            sum = sum + amount;
-                            TransactionInputV10 {
-                                amount,
-                                id: SourceIdV10::Utxo(UtxoIdV10 {
-                                    tx_hash: *utxo.tx_hash(),
-                                    output_index: utxo.output_index() as usize,
-                                }),
-                            }
-                        })
-                        .collect();
-
-                    Ok((inputs, sum))
-                })?
-                .unwrap_or((Vec::with_capacity(500), SourceAmount::ZERO))
-        } else {
-            (Vec::with_capacity(500), SourceAmount::ZERO)
-        };
-        // UDs
-        if script.nodes.is_empty() {
-            if let WalletSubScriptV10::Single(WalletConditionV10::Sig(issuer)) = script.root {
-                let pending_uds_bn = txs_mp_db.uds_ids().iter(.., |it| {
-                    it.keys()
-                        .map_ok(|duniter_dbs::UdIdV2(_pk, bn)| bn)
-                        .collect::<KvResult<_>>()
-                })?;
-
-                let PagedData {
-                    data: UdsWithSum { uds, sum: uds_sum },
-                    ..
-                } = self.unspent_uds_of_pubkey(
-                    bc_db,
-                    issuer,
-                    PageInfo::default(),
-                    Some(pending_uds_bn),
-                    Some(amount - inputs_sum),
-                )?;
-                inputs.extend(uds.into_iter().map(|(block_number, source_amount)| {
-                    TransactionInputV10 {
-                        amount: source_amount,
-                        id: SourceIdV10::Ud(UdSourceIdV10 {
-                            issuer,
-                            block_number,
-                        }),
-                    }
-                }));
-                inputs_sum = inputs_sum + uds_sum;
-            }
-        }
-        if inputs_sum < amount {
-            // Written UTXOs
-            let PagedData {
-                data:
-                    UtxosWithSum {
-                        utxos: written_utxos,
-                        sum: written_utxos_sum,
-                    },
-                ..
-            } = self.find_script_utxos(
-                txs_mp_db,
-                Some(amount - inputs_sum),
-                PageInfo::default(),
-                &script,
-            )?;
-            inputs.extend(written_utxos.into_iter().map(
-                |(
-                    UtxoCursor {
-                        tx_hash,
-                        output_index,
-                        ..
-                    },
-                    source_amount,
-                )| TransactionInputV10 {
-                    amount: source_amount,
-                    id: SourceIdV10::Utxo(UtxoIdV10 {
-                        tx_hash,
-                        output_index: output_index as usize,
-                    }),
-                },
-            ));
-
-            Ok((inputs, inputs_sum + written_utxos_sum))
-        } else {
-            Ok((inputs, inputs_sum))
-        }
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use duniter_dbs::{
-        databases::{bc_v2::BcV2DbWritable, txs_mp_v2::TxsMpV2DbWritable},
-        BlockMetaV2, SourceAmountValV2, UdIdV2, UtxoIdDbV2, UtxoValV2, WalletConditionsV2,
-    };
-    use duniter_gva_db::{GvaUtxoIdDbV1, GvaV1DbWritable};
-
-    const UD0: i64 = 100;
-
-    #[test]
-    fn test_find_inputs() -> anyhow::Result<()> {
-        let bc_db = duniter_dbs::databases::bc_v2::BcV2Db::<Mem>::open(MemConf::default())?;
-        let bc_db_ro = bc_db.get_ro_handler();
-        let gva_db = duniter_gva_db::GvaV1Db::<Mem>::open(MemConf::default())?;
-        let db_reader = create_dbs_reader(unsafe { std::mem::transmute(&gva_db.get_ro_handler()) });
-        let txs_mp_db =
-            duniter_dbs::databases::txs_mp_v2::TxsMpV2Db::<Mem>::open(MemConf::default())?;
-
-        let b0 = BlockMetaV2 {
-            dividend: Some(SourceAmount::with_base0(UD0)),
-            ..Default::default()
-        };
-        let pk = PublicKey::default();
-        let script = WalletScriptV10::single(WalletConditionV10::Sig(pk));
-        let mut pending_utxos = BTreeSet::new();
-        pending_utxos.insert(UtxoValV2::new(
-            SourceAmount::with_base0(900),
-            Hash::default(),
-            10,
-        ));
-
-        bc_db.blocks_meta_write().upsert(U32BE(0), b0)?;
-        bc_db
-            .uds_reval_write()
-            .upsert(U32BE(0), SourceAmountValV2(SourceAmount::with_base0(UD0)))?;
-        bc_db
-            .uds_write()
-            .upsert(UdIdV2(PublicKey::default(), BlockNumber(0)), ())?;
-        gva_db
-            .blockchain_time_write()
-            .upsert(U32BE(0), b0.median_time)?;
-        gva_db.gva_utxos_write().upsert(
-            GvaUtxoIdDbV1::new(script.clone(), 0, Hash::default(), 0),
-            SourceAmountValV2(SourceAmount::with_base0(500)),
-        )?;
-        gva_db.gva_utxos_write().upsert(
-            GvaUtxoIdDbV1::new(script.clone(), 0, Hash::default(), 1),
-            SourceAmountValV2(SourceAmount::with_base0(800)),
-        )?;
-        txs_mp_db
-            .outputs_by_script_write()
-            .upsert(WalletConditionsV2(script.clone()), pending_utxos)?;
-
-        // Gen tx1
-        let (inputs, inputs_sum) = db_reader.find_inputs(
-            &bc_db_ro,
-            &txs_mp_db,
-            SourceAmount::with_base0(550),
-            &script,
-            false,
-        )?;
-        assert_eq!(inputs.len(), 2);
-        assert_eq!(inputs_sum, SourceAmount::with_base0(600));
-
-        // Insert tx1 inputs in mempool
-        txs_mp_db
-            .uds_ids_write()
-            .upsert(UdIdV2(pk, BlockNumber(0)), ())?;
-        txs_mp_db
-            .utxos_ids_write()
-            .upsert(UtxoIdDbV2(Hash::default(), 0), ())?;
-
-        // Gen tx2
-        let (inputs, inputs_sum) = db_reader.find_inputs(
-            &bc_db_ro,
-            &txs_mp_db,
-            SourceAmount::with_base0(550),
-            &script,
-            false,
-        )?;
-        assert_eq!(inputs.len(), 1);
-        assert_eq!(inputs_sum, SourceAmount::with_base0(800));
-
-        // Insert tx2 inputs in mempool
-        txs_mp_db
-            .utxos_ids_write()
-            .upsert(UtxoIdDbV2(Hash::default(), 1), ())?;
-
-        // Gen tx3 (use pending utxo)
-        let (inputs, inputs_sum) = db_reader.find_inputs(
-            &bc_db_ro,
-            &txs_mp_db,
-            SourceAmount::with_base0(750),
-            &script,
-            true,
-        )?;
-        assert_eq!(inputs.len(), 1);
-        assert_eq!(inputs_sum, SourceAmount::with_base0(900));
-
-        Ok(())
-    }
-}
diff --git a/rust-libs/modules/gva/dbs-reader/src/idty.rs b/rust-libs/modules/gva/dbs-reader/src/idty.rs
deleted file mode 100644
index 4925f9a59..000000000
--- a/rust-libs/modules/gva/dbs-reader/src/idty.rs
+++ /dev/null
@@ -1,70 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-impl DbsReaderImpl {
-    pub(super) fn idty_(
-        &self,
-        bc_db: &BcV2DbRo<FileBackend>,
-        pubkey: PublicKey,
-    ) -> KvResult<Option<duniter_dbs::IdtyDbV2>> {
-        bc_db.identities().get(
-            &duniter_dbs::PubKeyKeyV2::from_bytes(pubkey.as_ref())
-                .map_err(|e| KvError::DeserError(Box::new(e)))?,
-        )
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use duniter_dbs::databases::bc_v2::BcV2DbWritable;
-
-    #[test]
-    fn test_idty() -> KvResult<()> {
-        let bc_db = duniter_dbs::databases::bc_v2::BcV2Db::<Mem>::open(MemConf::default())?;
-        let bc_db_ro = bc_db.get_ro_handler();
-        let db_reader = DbsReaderImpl::mem();
-        let pk = PublicKey::default();
-
-        bc_db
-            .identities_write()
-            .upsert(PubKeyKeyV2(pk), duniter_dbs::IdtyDbV2::default())?;
-
-        assert_eq!(
-            db_reader.idty(&bc_db_ro, pk)?,
-            Some(duniter_dbs::IdtyDbV2::default())
-        );
-
-        bc_db.identities_write().upsert(
-            PubKeyKeyV2(pk),
-            duniter_dbs::IdtyDbV2 {
-                is_member: true,
-                username: String::from("JohnDoe"),
-            },
-        )?;
-
-        assert_eq!(
-            db_reader.idty(&bc_db_ro, pk)?,
-            Some(duniter_dbs::IdtyDbV2 {
-                is_member: true,
-                username: String::from("JohnDoe"),
-            })
-        );
-
-        Ok(())
-    }
-}
diff --git a/rust-libs/modules/gva/dbs-reader/src/lib.rs b/rust-libs/modules/gva/dbs-reader/src/lib.rs
deleted file mode 100644
index 8e9cdb33a..000000000
--- a/rust-libs/modules/gva/dbs-reader/src/lib.rs
+++ /dev/null
@@ -1,341 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-#![deny(
-    clippy::unwrap_used,
-    missing_copy_implementations,
-    trivial_casts,
-    trivial_numeric_casts,
-    unstable_features,
-    unused_import_braces
-)]
-
-pub mod block;
-pub mod current_frame;
-pub mod find_inputs;
-pub mod idty;
-pub mod network;
-pub mod pagination;
-pub mod txs_history;
-pub mod uds_of_pubkey;
-pub mod utxos;
-
-pub use crate::pagination::{PageInfo, PagedData};
-pub use duniter_bca_types::MAX_FIRST_UTXOS;
-
-use crate::pagination::{has_next_page, has_previous_page};
-use arrayvec::ArrayVec;
-use dubp::common::crypto::keys::ed25519::PublicKey;
-use dubp::documents::transaction::TransactionDocumentV10;
-use dubp::{block::DubpBlockV10, common::crypto::hashs::Hash};
-use dubp::{common::prelude::BlockNumber, wallet::prelude::*};
-use duniter_bca_types::utxo::Utxo;
-use duniter_dbs::{databases::network_v1::NetworkV1DbReadable, FileBackend};
-use duniter_dbs::{
-    databases::{
-        bc_v2::{BcV2DbReadable, BcV2DbRo},
-        cm_v1::CmV1DbReadable,
-        txs_mp_v2::TxsMpV2DbReadable,
-    },
-    BlockMetaV2,
-};
-use duniter_dbs::{kv_typed::prelude::*, HashKeyV2, PubKeyKeyV2, SourceAmountValV2, UtxoIdDbV2};
-use duniter_gva_db::{GvaIdtyDbV1, GvaTxDbV1, GvaUtxoIdDbV1, GvaV1DbReadable, GvaV1DbRo};
-use resiter::filter::Filter;
-use resiter::filter_map::FilterMap;
-use resiter::flatten::Flatten;
-use resiter::map::Map;
-use std::{
-    collections::{BTreeSet, VecDeque},
-    num::NonZeroUsize,
-    str::FromStr,
-};
-
-#[derive(Clone, Copy, Debug)]
-pub struct WrongCursor;
-impl std::fmt::Display for WrongCursor {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(f, "wrong cursor")
-    }
-}
-impl std::error::Error for WrongCursor {}
-
-#[cfg_attr(feature = "mock", mockall::automock)]
-pub trait DbsReader {
-    fn all_uds_of_pubkey(
-        &self,
-        bc_db: &BcV2DbRo<FileBackend>,
-        pubkey: PublicKey,
-        page_info: PageInfo<BlockNumber>,
-    ) -> KvResult<PagedData<uds_of_pubkey::UdsWithSum>>;
-    fn block(&self, bc_db: &BcV2DbRo<FileBackend>, number: U32BE) -> KvResult<Option<BlockMetaV2>>;
-    fn blocks(
-        &self,
-        bc_db: &BcV2DbRo<FileBackend>,
-        page_info: PageInfo<block::BlockCursor>,
-    ) -> KvResult<PagedData<Vec<(block::BlockCursor, BlockMetaV2)>>>;
-    fn endpoints<Db: 'static + NetworkV1DbReadable>(
-        &self,
-        network_db: &Db,
-        api_list: Vec<String>,
-    ) -> KvResult<Vec<String>>;
-    fn find_inputs<TxsMpDb: 'static + TxsMpV2DbReadable>(
-        &self,
-        bc_db: &BcV2DbRo<FileBackend>,
-        txs_mp_db: &TxsMpDb,
-        amount: SourceAmount,
-        script: &WalletScriptV10,
-        use_mempool_sources: bool,
-    ) -> anyhow::Result<(
-        Vec<dubp::documents::transaction::TransactionInputV10>,
-        SourceAmount,
-    )>;
-    fn find_script_utxos<TxsMpDb: 'static + TxsMpV2DbReadable>(
-        &self,
-        txs_mp_db_ro: &TxsMpDb,
-        amount_target_opt: Option<SourceAmount>,
-        page_info: PageInfo<utxos::UtxoCursor>,
-        script: &WalletScriptV10,
-    ) -> anyhow::Result<PagedData<utxos::UtxosWithSum>>;
-    fn first_scripts_utxos(
-        &self,
-        amount_target_opt: Option<SourceAmount>,
-        first: usize,
-        scripts: &[WalletScriptV10],
-    ) -> anyhow::Result<Vec<arrayvec::ArrayVec<[Utxo; MAX_FIRST_UTXOS]>>>;
-    fn get_account_balance(
-        &self,
-        account_script: &WalletScriptV10,
-    ) -> KvResult<Option<SourceAmountValV2>>;
-    fn get_blockchain_time(&self, block_number: BlockNumber) -> anyhow::Result<u64>;
-    fn get_current_block<CmDb: 'static + CmV1DbReadable>(
-        &self,
-        cm_db: &CmDb,
-    ) -> KvResult<Option<DubpBlockV10>>;
-    fn get_current_frame<BcDb: 'static + BcV2DbReadable>(
-        &self,
-        bc_db: &BcDb,
-        current_block_meta: &BlockMetaV2,
-    ) -> anyhow::Result<Vec<BlockMetaV2>>;
-    fn get_txs_history_bc_received(
-        &self,
-        from: Option<u64>,
-        page_info: PageInfo<txs_history::TxBcCursor>,
-        script_hash: Hash,
-        to: Option<u64>,
-    ) -> KvResult<PagedData<VecDeque<duniter_gva_db::GvaTxDbV1>>>;
-    fn get_txs_history_bc_sent(
-        &self,
-        from: Option<u64>,
-        page_info: PageInfo<txs_history::TxBcCursor>,
-        script_hash: Hash,
-        to: Option<u64>,
-    ) -> KvResult<PagedData<VecDeque<duniter_gva_db::GvaTxDbV1>>>;
-    fn get_txs_history_mempool<TxsMpDb: 'static + TxsMpV2DbReadable>(
-        &self,
-        txs_mp_db_ro: &TxsMpDb,
-        pubkey: PublicKey,
-    ) -> KvResult<(Vec<TransactionDocumentV10>, Vec<TransactionDocumentV10>)>;
-    fn idty(
-        &self,
-        bc_db: &BcV2DbRo<FileBackend>,
-        pubkey: PublicKey,
-    ) -> KvResult<Option<duniter_dbs::IdtyDbV2>>;
-    fn peers_and_heads<DB: 'static + NetworkV1DbReadable>(
-        &self,
-        dunp_db: &DB,
-    ) -> KvResult<Vec<(duniter_dbs::PeerCardDbV1, Vec<duniter_dbs::DunpHeadDbV1>)>>;
-    fn unspent_uds_of_pubkey(
-        &self,
-        bc_db: &BcV2DbRo<FileBackend>,
-        pubkey: PublicKey,
-        page_info: PageInfo<BlockNumber>,
-        bn_to_exclude_opt: Option<std::collections::BTreeSet<BlockNumber>>,
-        amount_target_opt: Option<SourceAmount>,
-    ) -> KvResult<PagedData<uds_of_pubkey::UdsWithSum>>;
-}
-
-#[derive(Clone, Copy, Debug)]
-pub struct DbsReaderImpl(&'static GvaV1DbRo<FileBackend>);
-
-pub fn create_dbs_reader(gva_db_ro: &'static GvaV1DbRo<FileBackend>) -> DbsReaderImpl {
-    DbsReaderImpl(gva_db_ro)
-}
-
-impl DbsReader for DbsReaderImpl {
-    fn all_uds_of_pubkey(
-        &self,
-        bc_db: &BcV2DbRo<FileBackend>,
-        pubkey: PublicKey,
-        page_info: PageInfo<BlockNumber>,
-    ) -> KvResult<PagedData<uds_of_pubkey::UdsWithSum>> {
-        self.all_uds_of_pubkey_(bc_db, pubkey, page_info)
-    }
-
-    fn block(&self, bc_db: &BcV2DbRo<FileBackend>, number: U32BE) -> KvResult<Option<BlockMetaV2>> {
-        self.block_(bc_db, number)
-    }
-
-    fn blocks(
-        &self,
-        bc_db: &BcV2DbRo<FileBackend>,
-        page_info: PageInfo<block::BlockCursor>,
-    ) -> KvResult<PagedData<Vec<(block::BlockCursor, BlockMetaV2)>>> {
-        self.blocks_(bc_db, page_info)
-    }
-
-    fn endpoints<Db: 'static + NetworkV1DbReadable>(
-        &self,
-        network_db: &Db,
-        api_list: Vec<String>,
-    ) -> KvResult<Vec<String>> {
-        self.endpoints_(network_db, api_list)
-    }
-
-    fn find_inputs<TxsMpDb: 'static + TxsMpV2DbReadable>(
-        &self,
-        bc_db: &BcV2DbRo<FileBackend>,
-        txs_mp_db: &TxsMpDb,
-        amount: SourceAmount,
-        script: &WalletScriptV10,
-        use_mempool_sources: bool,
-    ) -> anyhow::Result<(
-        Vec<dubp::documents::transaction::TransactionInputV10>,
-        SourceAmount,
-    )> {
-        self.find_inputs_(bc_db, txs_mp_db, amount, script, use_mempool_sources)
-    }
-
-    fn find_script_utxos<TxsMpDb: 'static + TxsMpV2DbReadable>(
-        &self,
-        txs_mp_db_ro: &TxsMpDb,
-        amount_target_opt: Option<SourceAmount>,
-        page_info: PageInfo<utxos::UtxoCursor>,
-        script: &WalletScriptV10,
-    ) -> anyhow::Result<PagedData<utxos::UtxosWithSum>> {
-        self.find_script_utxos_(txs_mp_db_ro, amount_target_opt, page_info, script)
-    }
-
-    fn first_scripts_utxos(
-        &self,
-        amount_target_opt: Option<SourceAmount>,
-        first: usize,
-        scripts: &[WalletScriptV10],
-    ) -> anyhow::Result<Vec<ArrayVec<[Utxo; MAX_FIRST_UTXOS]>>> {
-        self.first_scripts_utxos_(amount_target_opt, first, scripts)
-    }
-
-    fn get_account_balance(
-        &self,
-        account_script: &WalletScriptV10,
-    ) -> KvResult<Option<SourceAmountValV2>> {
-        self.0
-            .balances()
-            .get(duniter_dbs::WalletConditionsV2::from_ref(account_script))
-    }
-
-    fn get_blockchain_time(&self, block_number: BlockNumber) -> anyhow::Result<u64> {
-        Ok(self
-            .0
-            .blockchain_time()
-            .get(&U32BE(block_number.0))?
-            .unwrap_or_else(|| unreachable!()))
-    }
-
-    fn get_current_block<CmDb: CmV1DbReadable>(
-        &self,
-        cm_db: &CmDb,
-    ) -> KvResult<Option<DubpBlockV10>> {
-        Ok(cm_db.current_block().get(&())?.map(|db_block| db_block.0))
-    }
-
-    fn get_current_frame<BcDb: 'static + BcV2DbReadable>(
-        &self,
-        bc_db: &BcDb,
-        current_block_meta: &BlockMetaV2,
-    ) -> anyhow::Result<Vec<BlockMetaV2>> {
-        self.get_current_frame_(bc_db, current_block_meta)
-    }
-
-    fn get_txs_history_bc_received(
-        &self,
-        from: Option<u64>,
-        page_info: PageInfo<txs_history::TxBcCursor>,
-        script_hash: Hash,
-        to: Option<u64>,
-    ) -> KvResult<PagedData<VecDeque<GvaTxDbV1>>> {
-        self.get_txs_history_bc_received_(from, page_info, script_hash, to)
-    }
-
-    fn get_txs_history_bc_sent(
-        &self,
-        from: Option<u64>,
-        page_info: PageInfo<txs_history::TxBcCursor>,
-        script_hash: Hash,
-        to: Option<u64>,
-    ) -> KvResult<PagedData<VecDeque<GvaTxDbV1>>> {
-        self.get_txs_history_bc_sent_(from, page_info, script_hash, to)
-    }
-
-    fn get_txs_history_mempool<TxsMpDb: 'static + TxsMpV2DbReadable>(
-        &self,
-        txs_mp_db_ro: &TxsMpDb,
-        pubkey: PublicKey,
-    ) -> KvResult<(Vec<TransactionDocumentV10>, Vec<TransactionDocumentV10>)> {
-        self.get_txs_history_mempool_(txs_mp_db_ro, pubkey)
-    }
-
-    fn idty(
-        &self,
-        bc_db: &BcV2DbRo<FileBackend>,
-        pubkey: PublicKey,
-    ) -> KvResult<Option<duniter_dbs::IdtyDbV2>> {
-        self.idty_(bc_db, pubkey)
-    }
-
-    fn peers_and_heads<DB: 'static + NetworkV1DbReadable>(
-        &self,
-        dunp_db: &DB,
-    ) -> KvResult<Vec<(duniter_dbs::PeerCardDbV1, Vec<duniter_dbs::DunpHeadDbV1>)>> {
-        self.peers_and_heads_(dunp_db)
-    }
-
-    fn unspent_uds_of_pubkey(
-        &self,
-        bc_db: &BcV2DbRo<FileBackend>,
-        pubkey: PublicKey,
-        page_info: PageInfo<BlockNumber>,
-        bn_to_exclude_opt: Option<BTreeSet<BlockNumber>>,
-        amount_target_opt: Option<SourceAmount>,
-    ) -> KvResult<PagedData<uds_of_pubkey::UdsWithSum>> {
-        self.unspent_uds_of_pubkey_(
-            bc_db,
-            pubkey,
-            page_info,
-            bn_to_exclude_opt.as_ref(),
-            amount_target_opt,
-        )
-    }
-}
-
-#[cfg(test)]
-impl DbsReaderImpl {
-    pub(crate) fn mem() -> Self {
-        use duniter_gva_db::GvaV1DbWritable;
-        let gva_db = duniter_gva_db::GvaV1Db::<Mem>::open(MemConf::default())
-            .expect("fail to create memory gva db");
-        create_dbs_reader(unsafe { std::mem::transmute(&gva_db.get_ro_handler()) })
-    }
-}
diff --git a/rust-libs/modules/gva/dbs-reader/src/network.rs b/rust-libs/modules/gva/dbs-reader/src/network.rs
deleted file mode 100644
index 2ec530aa6..000000000
--- a/rust-libs/modules/gva/dbs-reader/src/network.rs
+++ /dev/null
@@ -1,200 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-use dubp::crypto::keys::PublicKey as _;
-use duniter_dbs::{databases::network_v1::NetworkV1DbReadable, DunpHeadDbV1, PeerCardDbV1};
-
-#[allow(clippy::unnecessary_wraps)]
-impl DbsReaderImpl {
-    pub(super) fn endpoints_<DB: NetworkV1DbReadable>(
-        &self,
-        network_db: &DB,
-        mut api_list: Vec<String>,
-    ) -> KvResult<Vec<String>> {
-        if api_list.is_empty() {
-            return Ok(vec![]);
-        }
-        for api in &mut api_list {
-            api.push(' ');
-        }
-        network_db.peers_old().iter(.., |it| {
-            it.values()
-                .map_ok(|peer| {
-                    peer.endpoints.into_iter().filter(|endpoint| {
-                        api_list
-                            .iter()
-                            .any(|api| endpoint.starts_with(api.as_str()))
-                    })
-                })
-                .flatten_ok()
-                .collect::<Result<Vec<String>, _>>()
-        })
-    }
-    pub(super) fn peers_and_heads_<DB: NetworkV1DbReadable>(
-        &self,
-        dunp_db: &DB,
-    ) -> KvResult<Vec<(PeerCardDbV1, Vec<DunpHeadDbV1>)>> {
-        Ok(dunp_db.peers_old().iter(.., |it| {
-            it.values()
-                .filter_map(|peer_res| {
-                    if let Ok(peer) = peer_res {
-                        if let Ok(pubkey) = PublicKey::from_base58(&peer.pubkey) {
-                            let k_min = duniter_dbs::DunpNodeIdV1Db::new(0, pubkey);
-                            let k_max = duniter_dbs::DunpNodeIdV1Db::new(u32::MAX, pubkey);
-                            Some((
-                                peer,
-                                dunp_db.heads_old().iter(k_min..k_max, |it| {
-                                    it.values().filter_map(|head| head.ok()).collect()
-                                }),
-                            ))
-                        } else {
-                            None
-                        }
-                    } else {
-                        None
-                    }
-                })
-                .collect()
-        }))
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use duniter_dbs::databases::network_v1::NetworkV1DbWritable;
-    use duniter_dbs::PeerCardDbV1;
-
-    #[test]
-    fn test_empty_endpoints() -> KvResult<()> {
-        // Populate DB
-        let dunp_db =
-            duniter_dbs::databases::network_v1::NetworkV1Db::<Mem>::open(MemConf::default())?;
-        let db_reader = DbsReaderImpl::mem();
-        let pk = PublicKey::default();
-
-        dunp_db
-            .peers_old_write()
-            .upsert(PubKeyKeyV2(pk), PeerCardDbV1::default())?;
-
-        // Request Data
-        let api_list = vec!["GVA".to_owned()];
-        assert_eq!(
-            db_reader.endpoints_(&dunp_db, api_list)?,
-            Vec::<String>::new()
-        );
-
-        Ok(())
-    }
-    #[test]
-    fn test_endpoints_with_empty_api_list() -> KvResult<()> {
-        let dummy_endpoint = "GVA S domain.tld 443 gva";
-
-        // Populate DB
-        let dunp_db =
-            duniter_dbs::databases::network_v1::NetworkV1Db::<Mem>::open(MemConf::default())?;
-        let db_reader = DbsReaderImpl::mem();
-        let pk = PublicKey::default();
-        let peer = PeerCardDbV1 {
-            endpoints: vec![dummy_endpoint.to_owned()],
-            ..Default::default()
-        };
-
-        dunp_db.peers_old_write().upsert(PubKeyKeyV2(pk), peer)?;
-
-        // Request Data
-        let api_list = vec![];
-        assert_eq!(
-            db_reader.endpoints_(&dunp_db, api_list)?,
-            Vec::<String>::new()
-        );
-
-        Ok(())
-    }
-    #[test]
-    fn test_single_peer_endpoints() -> KvResult<()> {
-        let dummy_endpoint = "GVA S domain.tld 443 gva";
-
-        // Populate DB
-        let dunp_db =
-            duniter_dbs::databases::network_v1::NetworkV1Db::<Mem>::open(MemConf::default())?;
-        let db_reader = DbsReaderImpl::mem();
-        let pk = PublicKey::default();
-        let peer = PeerCardDbV1 {
-            endpoints: vec![dummy_endpoint.to_owned()],
-            ..Default::default()
-        };
-
-        dunp_db.peers_old_write().upsert(PubKeyKeyV2(pk), peer)?;
-
-        // Request Data
-        let api_list = vec!["GVA".to_owned()];
-        assert_eq!(
-            db_reader.endpoints_(&dunp_db, api_list)?,
-            vec![dummy_endpoint.to_owned()]
-        );
-
-        Ok(())
-    }
-
-    #[test]
-    fn test_peers_and_heads() -> KvResult<()> {
-        let dunp_db =
-            duniter_dbs::databases::network_v1::NetworkV1Db::<Mem>::open(MemConf::default())?;
-        let db_reader = DbsReaderImpl::mem();
-        let pk = PublicKey::default();
-
-        dunp_db.peers_old_write().upsert(
-            PubKeyKeyV2(pk),
-            PeerCardDbV1 {
-                pubkey: pk.to_string(),
-                ..Default::default()
-            },
-        )?;
-        dunp_db.heads_old_write().upsert(
-            duniter_dbs::DunpNodeIdV1Db::new(42, pk),
-            DunpHeadDbV1::default(),
-        )?;
-        dunp_db.heads_old_write().upsert(
-            duniter_dbs::DunpNodeIdV1Db::new(43, pk),
-            DunpHeadDbV1 {
-                pubkey: PublicKey::from_base58("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
-                    .expect("invalid pubkey"),
-                ..Default::default()
-            },
-        )?;
-
-        assert_eq!(
-            db_reader.peers_and_heads(&dunp_db)?,
-            vec![(
-                PeerCardDbV1 {
-                    pubkey: pk.to_string(),
-                    ..Default::default()
-                },
-                vec![
-                    DunpHeadDbV1::default(),
-                    DunpHeadDbV1 {
-                        pubkey: PublicKey::from_base58("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
-                            .expect("invalid pubkey"),
-                        ..Default::default()
-                    }
-                ]
-            )]
-        );
-
-        Ok(())
-    }
-}
diff --git a/rust-libs/modules/gva/dbs-reader/src/pagination.rs b/rust-libs/modules/gva/dbs-reader/src/pagination.rs
deleted file mode 100644
index 48d80bbc5..000000000
--- a/rust-libs/modules/gva/dbs-reader/src/pagination.rs
+++ /dev/null
@@ -1,144 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Debug)]
-pub struct PagedData<D: std::fmt::Debug> {
-    pub data: D,
-    pub has_previous_page: bool,
-    pub has_next_page: bool,
-}
-impl<D: std::fmt::Debug + Default> PagedData<D> {
-    pub fn empty() -> Self {
-        PagedData {
-            data: D::default(),
-            has_previous_page: false,
-            has_next_page: false,
-        }
-    }
-}
-
-#[derive(Debug)]
-pub struct PageInfo<T> {
-    pub(crate) pos: Option<T>,
-    /// Order: true for ASC, false for DESC
-    pub(crate) order: bool,
-    pub(crate) limit_opt: Option<NonZeroUsize>,
-}
-impl<T> PageInfo<T> {
-    pub fn new(pos: Option<T>, order: bool, limit_opt: Option<NonZeroUsize>) -> Self {
-        PageInfo {
-            pos,
-            order,
-            limit_opt,
-        }
-    }
-    pub fn limit_opt(&self) -> Option<NonZeroUsize> {
-        self.limit_opt
-    }
-    pub fn not_all(&self) -> bool {
-        self.limit_opt.is_some() || self.pos.is_some()
-    }
-    pub fn order(&self) -> bool {
-        self.order
-    }
-    pub fn pos(&self) -> Option<&T> {
-        self.pos.as_ref()
-    }
-}
-impl<T> Default for PageInfo<T> {
-    fn default() -> Self {
-        PageInfo {
-            pos: None,
-            order: true,
-            limit_opt: None,
-        }
-    }
-}
-impl<T> Clone for PageInfo<T>
-where
-    T: Clone,
-{
-    fn clone(&self) -> Self {
-        Self {
-            pos: self.pos.clone(),
-            order: self.order,
-            limit_opt: self.limit_opt,
-        }
-    }
-}
-impl<T> Copy for PageInfo<T> where T: Copy {}
-
-pub(crate) fn has_next_page<
-    'i,
-    C: 'static + std::fmt::Debug + Default + Ord,
-    I: DoubleEndedIterator<Item = OwnedOrRef<'i, C>>,
->(
-    mut page_cursors: I,
-    last_cursor_opt: Option<C>,
-    page_info: PageInfo<C>,
-    page_not_reversed: bool,
-) -> bool {
-    if page_info.not_all() {
-        if let Some(last_cursor) = last_cursor_opt {
-            //println!("TMP last_cursor={:?}", last_cursor);
-            if let Some(page_end_cursor) = if page_not_reversed {
-                page_cursors.next_back()
-            } else {
-                page_cursors.next()
-            } {
-                //println!("TMP page_end_cursor={:?}", page_end_cursor);
-                page_end_cursor.as_ref() != &last_cursor
-            } else {
-                page_info.pos.unwrap_or_default() < last_cursor
-            }
-        } else {
-            false
-        }
-    } else {
-        false
-    }
-}
-
-pub(crate) fn has_previous_page<
-    'i,
-    C: 'static + std::fmt::Debug + Default + Ord,
-    I: DoubleEndedIterator<Item = OwnedOrRef<'i, C>>,
->(
-    mut page_cursors: I,
-    first_cursor_opt: Option<C>,
-    page_info: PageInfo<C>,
-    page_not_reversed: bool,
-) -> bool {
-    if page_info.not_all() {
-        if let Some(first_cursor) = first_cursor_opt {
-            //println!("TMP first_cursor={:?}", first_cursor);
-            if let Some(page_start_cursor) = if page_not_reversed {
-                page_cursors.next()
-            } else {
-                page_cursors.next_back()
-            } {
-                page_start_cursor.as_ref() != &first_cursor
-            } else {
-                page_info.pos.unwrap_or_default() > first_cursor
-            }
-        } else {
-            false
-        }
-    } else {
-        false
-    }
-}
diff --git a/rust-libs/modules/gva/dbs-reader/src/txs_history.rs b/rust-libs/modules/gva/dbs-reader/src/txs_history.rs
deleted file mode 100644
index 3a4e3c52a..000000000
--- a/rust-libs/modules/gva/dbs-reader/src/txs_history.rs
+++ /dev/null
@@ -1,836 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-use duniter_dbs::smallvec::SmallVec;
-use duniter_gva_db::WalletHashWithBnV1Db;
-
-#[derive(Clone, Copy, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
-pub struct TxBcCursor {
-    pub block_number: BlockNumber,
-    pub tx_hash: Hash,
-}
-impl std::fmt::Display for TxBcCursor {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(f, "{}:{}", self.block_number, self.tx_hash,)
-    }
-}
-
-impl FromStr for TxBcCursor {
-    type Err = WrongCursor;
-
-    fn from_str(s: &str) -> Result<Self, Self::Err> {
-        let mut s = s.split(':');
-        let block_number = s
-            .next()
-            .ok_or(WrongCursor)?
-            .parse()
-            .map_err(|_| WrongCursor)?;
-        let tx_hash = Hash::from_hex(s.next().ok_or(WrongCursor)?).map_err(|_| WrongCursor)?;
-        Ok(Self {
-            block_number,
-            tx_hash,
-        })
-    }
-}
-
-impl DbsReaderImpl {
-    pub(super) fn get_txs_history_bc_received_(
-        &self,
-        from: Option<u64>,
-        page_info: PageInfo<TxBcCursor>,
-        script_hash: Hash,
-        to: Option<u64>,
-    ) -> KvResult<PagedData<VecDeque<GvaTxDbV1>>> {
-        let mut start_k = WalletHashWithBnV1Db::new(
-            script_hash,
-            BlockNumber(if let Some(from) = from {
-                self.0
-                    .blocks_by_common_time()
-                    .iter(U64BE(from).., |it| it)
-                    .values()
-                    .next_res()?
-                    .unwrap_or(u32::MAX)
-            } else {
-                0
-            }),
-        );
-        let mut end_k = WalletHashWithBnV1Db::new(
-            script_hash,
-            BlockNumber(if let Some(to) = to {
-                self.0
-                    .blocks_by_common_time()
-                    .iter_rev(..U64BE(to), |it| it)
-                    .values()
-                    .next_res()?
-                    .unwrap_or(0)
-            } else {
-                u32::MAX
-            }),
-        );
-        let first_cursor_opt = if page_info.not_all() {
-            self.0
-                .txs_by_recipient()
-                .iter_ref_slice(start_k..=end_k, |k, hashs| {
-                    Ok(TxBcCursor {
-                        block_number: BlockNumber(k.get_block_number()),
-                        tx_hash: hashs[0],
-                    })
-                })
-                .next_res()?
-        } else {
-            None
-        };
-        let last_cursor_opt = if page_info.not_all() {
-            self.0
-                .txs_by_recipient()
-                .iter_ref_slice_rev(start_k..=end_k, |k, hashs| {
-                    Ok(TxBcCursor {
-                        block_number: BlockNumber(k.get_block_number()),
-                        tx_hash: hashs[hashs.len() - 1],
-                    })
-                })
-                .next_res()?
-        } else {
-            None
-        };
-        let first_hashs_opt = if let Some(TxBcCursor {
-            block_number,
-            tx_hash: hash_limit,
-        }) = page_info.pos
-        {
-            if page_info.order {
-                let hashs = self.0.txs_by_recipient().get_ref_slice(
-                    &WalletHashWithBnV1Db::new(script_hash, block_number),
-                    |hashs| {
-                        Ok(hashs
-                            .iter()
-                            .rev()
-                            .take_while(|hash| *hash != &hash_limit)
-                            .copied()
-                            .collect::<SmallVec<[Hash; 8]>>())
-                    },
-                )?;
-                start_k = WalletHashWithBnV1Db::new(script_hash, BlockNumber(block_number.0 + 1));
-                hashs
-            } else {
-                let hashs = self.0.txs_by_recipient().get_ref_slice(
-                    &WalletHashWithBnV1Db::new(script_hash, block_number),
-                    |hashs| {
-                        Ok(hashs
-                            .iter()
-                            .take_while(|hash| *hash != &hash_limit)
-                            .copied()
-                            .collect::<SmallVec<[Hash; 8]>>())
-                    },
-                )?;
-                if block_number == BlockNumber(0) {
-                    return Ok(PagedData::empty());
-                }
-                end_k = WalletHashWithBnV1Db::new(script_hash, BlockNumber(block_number.0 - 1));
-                hashs
-            }
-        } else {
-            None
-        };
-
-        if page_info.order {
-            let txs_iter = self
-                .0
-                .txs_by_recipient()
-                .iter_ref_slice(start_k..=end_k, |_k, hashs| {
-                    let mut sent = SmallVec::<[GvaTxDbV1; 8]>::new();
-                    for hash in hashs {
-                        if let Some(tx_db) = self.0.txs().get(HashKeyV2::from_ref(hash))? {
-                            sent.push(tx_db);
-                        }
-                    }
-                    Ok(sent)
-                })
-                .flatten_ok();
-            txs_history_bc_collect(
-                *self,
-                first_cursor_opt,
-                first_hashs_opt,
-                last_cursor_opt,
-                page_info,
-                txs_iter,
-            )
-        } else {
-            let txs_iter = self
-                .0
-                .txs_by_recipient()
-                .iter_ref_slice_rev(start_k..=end_k, |_k, hashs| {
-                    let mut sent = SmallVec::<[GvaTxDbV1; 8]>::new();
-                    for hash in hashs.iter().rev() {
-                        if let Some(tx_db) = self.0.txs().get(HashKeyV2::from_ref(hash))? {
-                            sent.push(tx_db);
-                        }
-                    }
-                    Ok(sent)
-                })
-                .flatten_ok();
-            txs_history_bc_collect(
-                *self,
-                first_cursor_opt,
-                first_hashs_opt,
-                last_cursor_opt,
-                page_info,
-                txs_iter,
-            )
-        }
-    }
-    pub(super) fn get_txs_history_bc_sent_(
-        &self,
-        from: Option<u64>,
-        page_info: PageInfo<TxBcCursor>,
-        script_hash: Hash,
-        to: Option<u64>,
-    ) -> KvResult<PagedData<VecDeque<GvaTxDbV1>>> {
-        let mut start_k = WalletHashWithBnV1Db::new(
-            script_hash,
-            BlockNumber(if let Some(from) = from {
-                self.0
-                    .blocks_by_common_time()
-                    .iter(U64BE(from).., |it| it)
-                    .values()
-                    .next_res()?
-                    .unwrap_or(u32::MAX)
-            } else {
-                0
-            }),
-        );
-        let mut end_k = WalletHashWithBnV1Db::new(
-            script_hash,
-            BlockNumber(if let Some(to) = to {
-                self.0
-                    .blocks_by_common_time()
-                    .iter_rev(..U64BE(to), |it| it)
-                    .values()
-                    .next_res()?
-                    .unwrap_or(0)
-            } else {
-                u32::MAX
-            }),
-        );
-        let first_cursor_opt = if page_info.not_all() {
-            self.0
-                .txs_by_issuer()
-                .iter_ref_slice(start_k..=end_k, |k, hashs| {
-                    Ok(TxBcCursor {
-                        block_number: BlockNumber(k.get_block_number()),
-                        tx_hash: hashs[0],
-                    })
-                })
-                .next_res()?
-        } else {
-            None
-        };
-        let last_cursor_opt = if page_info.not_all() {
-            self.0
-                .txs_by_issuer()
-                .iter_ref_slice_rev(start_k..=end_k, |k, hashs| {
-                    Ok(TxBcCursor {
-                        block_number: BlockNumber(k.get_block_number()),
-                        tx_hash: hashs[hashs.len() - 1],
-                    })
-                })
-                .next_res()?
-        } else {
-            None
-        };
-        let first_hashs_opt = if let Some(TxBcCursor {
-            block_number,
-            tx_hash: hash_limit,
-        }) = page_info.pos
-        {
-            if page_info.order {
-                let hashs = self.0.txs_by_issuer().get_ref_slice(
-                    &WalletHashWithBnV1Db::new(script_hash, block_number),
-                    |hashs| {
-                        Ok(hashs
-                            .iter()
-                            .rev()
-                            .take_while(|hash| *hash != &hash_limit)
-                            .copied()
-                            .collect::<SmallVec<[Hash; 8]>>())
-                    },
-                )?;
-                start_k = WalletHashWithBnV1Db::new(script_hash, BlockNumber(block_number.0 + 1));
-                hashs
-            } else {
-                let hashs = self.0.txs_by_issuer().get_ref_slice(
-                    &WalletHashWithBnV1Db::new(script_hash, block_number),
-                    |hashs| {
-                        Ok(hashs
-                            .iter()
-                            .take_while(|hash| *hash != &hash_limit)
-                            .copied()
-                            .collect::<SmallVec<[Hash; 8]>>())
-                    },
-                )?;
-                if block_number == BlockNumber(0) {
-                    return Ok(PagedData::empty());
-                }
-                end_k = WalletHashWithBnV1Db::new(script_hash, BlockNumber(block_number.0 - 1));
-                hashs
-            }
-        } else {
-            None
-        };
-
-        if page_info.order {
-            let txs_iter = self
-                .0
-                .txs_by_issuer()
-                .iter_ref_slice(start_k..=end_k, |_k, hashs| {
-                    let mut sent = SmallVec::<[GvaTxDbV1; 8]>::new();
-                    for hash in hashs {
-                        if let Some(tx_db) = self.0.txs().get(HashKeyV2::from_ref(hash))? {
-                            sent.push(tx_db);
-                        }
-                    }
-                    Ok(sent)
-                })
-                .flatten_ok();
-            txs_history_bc_collect(
-                *self,
-                first_cursor_opt,
-                first_hashs_opt,
-                last_cursor_opt,
-                page_info,
-                txs_iter,
-            )
-        } else {
-            let txs_iter = self
-                .0
-                .txs_by_issuer()
-                .iter_ref_slice_rev(start_k..=end_k, |_k, hashs| {
-                    let mut sent = SmallVec::<[GvaTxDbV1; 8]>::new();
-                    for hash in hashs.iter().rev() {
-                        if let Some(tx_db) = self.0.txs().get(HashKeyV2::from_ref(hash))? {
-                            sent.push(tx_db);
-                        }
-                    }
-                    Ok(sent)
-                })
-                .flatten_ok();
-            txs_history_bc_collect(
-                *self,
-                first_cursor_opt,
-                first_hashs_opt,
-                last_cursor_opt,
-                page_info,
-                txs_iter,
-            )
-        }
-    }
-    pub(super) fn get_txs_history_mempool_<TxsMpDb: 'static + TxsMpV2DbReadable>(
-        &self,
-        txs_mp_db_ro: &TxsMpDb,
-        pubkey: PublicKey,
-    ) -> KvResult<(Vec<TransactionDocumentV10>, Vec<TransactionDocumentV10>)> {
-        let sending = txs_mp_db_ro
-            .txs_by_issuer()
-            .get_ref_slice(&PubKeyKeyV2(pubkey), |hashs| {
-                let mut sent = Vec::with_capacity(hashs.len());
-                for hash in hashs {
-                    if let Some(tx_db) = txs_mp_db_ro.txs().get(HashKeyV2::from_ref(hash))? {
-                        sent.push(tx_db.0);
-                    }
-                }
-                Ok(sent)
-            })?
-            .unwrap_or_default();
-        let pending = txs_mp_db_ro
-            .txs_by_recipient()
-            .get_ref_slice(&PubKeyKeyV2(pubkey), |hashs| {
-                let mut pending = Vec::with_capacity(hashs.len());
-                for hash in hashs {
-                    if let Some(tx_db) = txs_mp_db_ro.txs().get(HashKeyV2::from_ref(hash))? {
-                        pending.push(tx_db.0);
-                    }
-                }
-                Ok(pending)
-            })?
-            .unwrap_or_default();
-        Ok((sending, pending))
-    }
-}
-
-fn txs_history_bc_collect<I: Iterator<Item = KvResult<GvaTxDbV1>>>(
-    dbs_reader: DbsReaderImpl,
-    first_cursor_opt: Option<TxBcCursor>,
-    first_hashs_opt: Option<SmallVec<[Hash; 8]>>,
-    last_cursor_opt: Option<TxBcCursor>,
-    page_info: PageInfo<TxBcCursor>,
-    txs_iter: I,
-) -> KvResult<PagedData<VecDeque<GvaTxDbV1>>> {
-    let mut txs = if let Some(limit) = page_info.limit_opt {
-        txs_iter
-            .take(limit.get())
-            .collect::<KvResult<VecDeque<_>>>()?
-    } else {
-        txs_iter.collect::<KvResult<VecDeque<_>>>()?
-    };
-
-    if let Some(first_hashs) = first_hashs_opt {
-        for hash in first_hashs.into_iter() {
-            if let Some(tx_db) = dbs_reader.0.txs().get(&HashKeyV2(hash))? {
-                txs.push_front(tx_db);
-            }
-        }
-    }
-
-    Ok(PagedData {
-        has_next_page: if page_info.order {
-            has_next_page(
-                txs.iter().map(|tx_db| {
-                    TxBcCursor {
-                        block_number: tx_db.written_block.number,
-                        tx_hash: tx_db.tx.get_hash(),
-                    }
-                    .into()
-                }),
-                last_cursor_opt,
-                page_info,
-                page_info.order,
-            )
-        } else {
-            // Server can't efficiently determine hasNextPage in DESC order
-            false
-        },
-        has_previous_page: if page_info.order {
-            // Server can't efficiently determine hasPreviousPage in ASC order
-            false
-        } else {
-            has_previous_page(
-                txs.iter().map(|tx_db| {
-                    TxBcCursor {
-                        block_number: tx_db.written_block.number,
-                        tx_hash: tx_db.tx.get_hash(),
-                    }
-                    .into()
-                }),
-                first_cursor_opt,
-                page_info,
-                page_info.order,
-            )
-        },
-        data: txs,
-    })
-}
-
-// Needed for BMA only
-pub struct TxsHistory {
-    pub sent: Vec<GvaTxDbV1>,
-    pub received: Vec<GvaTxDbV1>,
-    pub sending: Vec<TransactionDocumentV10>,
-    pub pending: Vec<TransactionDocumentV10>,
-}
-
-// Needed for BMA only
-pub fn get_transactions_history_for_bma<GvaDb: GvaV1DbReadable, TxsMpDb: TxsMpV2DbReadable>(
-    gva_db_ro: &GvaDb,
-    txs_mp_db_ro: &TxsMpDb,
-    pubkey: PublicKey,
-) -> KvResult<TxsHistory> {
-    let script_hash = Hash::compute(WalletScriptV10::single_sig(pubkey).to_string().as_bytes());
-    let start_k = WalletHashWithBnV1Db::new(script_hash, BlockNumber(0));
-    let end_k = WalletHashWithBnV1Db::new(script_hash, BlockNumber(u32::MAX));
-
-    let sent = gva_db_ro
-        .txs_by_issuer()
-        .iter_ref_slice(start_k..end_k, |_k, hashs| {
-            let mut sent = SmallVec::<[GvaTxDbV1; 2]>::new();
-            for hash in hashs {
-                if let Some(tx_db) = gva_db_ro.txs().get(HashKeyV2::from_ref(hash))? {
-                    sent.push(tx_db);
-                }
-            }
-            Ok(sent)
-        })
-        .flatten_ok()
-        .collect::<KvResult<Vec<_>>>()?;
-
-    let received = gva_db_ro
-        .txs_by_recipient()
-        .iter_ref_slice(start_k..end_k, |_k, hashs| {
-            let mut sent = SmallVec::<[GvaTxDbV1; 2]>::new();
-            for hash in hashs {
-                if let Some(tx_db) = gva_db_ro.txs().get(HashKeyV2::from_ref(hash))? {
-                    sent.push(tx_db);
-                }
-            }
-            Ok(sent)
-        })
-        .flatten_ok()
-        .collect::<KvResult<Vec<_>>>()?;
-    let sending = txs_mp_db_ro
-        .txs_by_issuer()
-        .get_ref_slice(&PubKeyKeyV2(pubkey), |hashs| {
-            let mut sent = Vec::with_capacity(hashs.len());
-            for hash in hashs {
-                if let Some(tx_db) = txs_mp_db_ro.txs().get(HashKeyV2::from_ref(hash))? {
-                    sent.push(tx_db.0);
-                }
-            }
-            Ok(sent)
-        })?
-        .unwrap_or_default();
-    let pending = txs_mp_db_ro
-        .txs_by_recipient()
-        .get_ref_slice(&PubKeyKeyV2(pubkey), |hashs| {
-            let mut pending = Vec::with_capacity(hashs.len());
-            for hash in hashs {
-                if let Some(tx_db) = txs_mp_db_ro.txs().get(HashKeyV2::from_ref(hash))? {
-                    pending.push(tx_db.0);
-                }
-            }
-            Ok(pending)
-        })?
-        .unwrap_or_default();
-    Ok(TxsHistory {
-        sent,
-        received,
-        sending,
-        pending,
-    })
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use dubp::{
-        common::prelude::{BlockHash, Blockstamp},
-        crypto::keys::ed25519::PublicKey,
-        documents::transaction::{TransactionDocumentV10, TransactionDocumentV10Stringified},
-        documents_parser::prelude::FromStringObject,
-    };
-    use duniter_gva_db::GvaV1DbWritable;
-    use maplit::btreeset;
-    use unwrap::unwrap;
-
-    fn gen_tx(hash: Hash, written_block_number: BlockNumber) -> GvaTxDbV1 {
-        GvaTxDbV1 {
-            tx: unwrap!(TransactionDocumentV10::from_string_object(
-                &TransactionDocumentV10Stringified {
-                    currency: "test".to_owned(),
-                    blockstamp:
-                        "1-0000000000000000000000000000000000000000000000000000000000000000"
-                            .to_owned(),
-                    locktime: 0,
-                    issuers: vec![],
-                    inputs: vec![],
-                    unlocks: vec![],
-                    outputs: vec![],
-                    comment: "".to_owned(),
-                    signatures: vec![],
-                    hash: Some(hash.to_hex()),
-                }
-            )),
-            written_block: Blockstamp {
-                number: written_block_number,
-                hash: BlockHash(Hash::default()),
-            },
-            written_time: 1,
-        }
-    }
-
-    #[test]
-    fn test_get_txs_history_bc_received() -> KvResult<()> {
-        let gva_db = duniter_gva_db::GvaV1Db::<Mem>::open(MemConf::default())?;
-        let db_reader = create_dbs_reader(unsafe { std::mem::transmute(&gva_db.get_ro_handler()) });
-
-        let s1 = WalletScriptV10::single_sig(PublicKey::default());
-        let s1_hash = Hash::compute(&s1.to_string().as_bytes());
-
-        gva_db.txs_write().upsert(
-            HashKeyV2(Hash::default()),
-            gen_tx(Hash::default(), BlockNumber(1)),
-        )?;
-        gva_db.txs_write().upsert(
-            HashKeyV2(Hash([1; 32])),
-            gen_tx(Hash([1; 32]), BlockNumber(1)),
-        )?;
-        gva_db.txs_write().upsert(
-            HashKeyV2(Hash([2; 32])),
-            gen_tx(Hash([2; 32]), BlockNumber(1)),
-        )?;
-        gva_db.txs_write().upsert(
-            HashKeyV2(Hash([3; 32])),
-            gen_tx(Hash([3; 32]), BlockNumber(1)),
-        )?;
-        gva_db.txs_by_recipient_write().upsert(
-            WalletHashWithBnV1Db::new(s1_hash, BlockNumber(1)),
-            btreeset![Hash::default(), Hash([1; 32]), Hash([2; 32]), Hash([3; 32])],
-        )?;
-        gva_db.blocks_by_common_time_write().upsert(U64BE(1), 1)?;
-        gva_db.txs_write().upsert(
-            HashKeyV2(Hash([4; 32])),
-            gen_tx(Hash([4; 32]), BlockNumber(2)),
-        )?;
-        gva_db.txs_write().upsert(
-            HashKeyV2(Hash([5; 32])),
-            gen_tx(Hash([5; 32]), BlockNumber(2)),
-        )?;
-        gva_db.txs_by_recipient_write().upsert(
-            WalletHashWithBnV1Db::new(s1_hash, BlockNumber(2)),
-            btreeset![Hash([4; 32]), Hash([5; 32])],
-        )?;
-        gva_db.blocks_by_common_time_write().upsert(U64BE(2), 2)?;
-        gva_db.txs_write().upsert(
-            HashKeyV2(Hash([6; 32])),
-            gen_tx(Hash([6; 32]), BlockNumber(3)),
-        )?;
-        gva_db.txs_by_recipient_write().upsert(
-            WalletHashWithBnV1Db::new(s1_hash, BlockNumber(3)),
-            btreeset![Hash([6; 32])],
-        )?;
-        gva_db.blocks_by_common_time_write().upsert(U64BE(3), 3)?;
-        gva_db.txs_write().upsert(
-            HashKeyV2(Hash([7; 32])),
-            gen_tx(Hash([7; 32]), BlockNumber(4)),
-        )?;
-        gva_db.txs_by_recipient_write().upsert(
-            WalletHashWithBnV1Db::new(s1_hash, BlockNumber(4)),
-            btreeset![Hash([7; 32])],
-        )?;
-        gva_db.blocks_by_common_time_write().upsert(U64BE(4), 4)?;
-        gva_db.txs_write().upsert(
-            HashKeyV2(Hash([8; 32])),
-            gen_tx(Hash([8; 32]), BlockNumber(5)),
-        )?;
-        gva_db.txs_by_recipient_write().upsert(
-            WalletHashWithBnV1Db::new(s1_hash, BlockNumber(5)),
-            btreeset![Hash([8; 32])],
-        )?;
-        gva_db.blocks_by_common_time_write().upsert(U64BE(5), 5)?;
-
-        /*let received = db_reader.get_txs_history_bc_received(
-            PageInfo {
-                order: true,
-                limit_opt: None,
-                pos: Some(TxBcCursor {
-                    tx_hash: Hash([1; 32]),
-                    block_number: BlockNumber(1),
-                }),
-            },
-            s1_hash,
-        )?;
-        assert_eq!(
-            received.data
-                .into_iter()
-                .map(|tx_db| tx_db.tx.get_hash())
-                .collect::<Vec<_>>(),
-            vec![Hash([2; 32]), Hash([3; 32]), Hash([4; 32]), Hash([5; 32])],
-        );
-        assert!(!received.has_next_page);
-        assert!(!received.has_previous_page);
-
-        let received = db_reader.get_txs_history_bc_received(
-            PageInfo {
-                order: false,
-                limit_opt: None,
-                pos: Some(TxBcCursor {
-                    tx_hash: Hash([1; 32]),
-                    block_number: BlockNumber(1),
-                }),
-            },
-            s1_hash,
-        )?;
-        assert_eq!(
-            received.data
-                .into_iter()
-                .map(|tx_db| tx_db.tx.get_hash())
-                .collect::<Vec<_>>(),
-            vec![Hash([0; 32])],
-        );
-        assert!(!received.has_next_page);
-        assert!(!received.has_previous_page);*/
-
-        let received = db_reader.get_txs_history_bc_received(
-            None,
-            PageInfo {
-                order: false,
-                limit_opt: None,
-                pos: Some(TxBcCursor {
-                    tx_hash: Hash([5; 32]),
-                    block_number: BlockNumber(2),
-                }),
-            },
-            s1_hash,
-            None,
-        )?;
-        assert_eq!(
-            received
-                .data
-                .into_iter()
-                .map(|tx_db| tx_db.tx.get_hash())
-                .collect::<Vec<_>>(),
-            vec![
-                Hash([4; 32]),
-                Hash([3; 32]),
-                Hash([2; 32]),
-                Hash([1; 32]),
-                Hash([0; 32]),
-            ],
-        );
-        assert!(!received.has_next_page);
-        assert!(!received.has_previous_page);
-
-        let received = db_reader.get_txs_history_bc_received(
-            Some(2),
-            PageInfo {
-                order: true,
-                limit_opt: None,
-                pos: None,
-            },
-            s1_hash,
-            Some(5),
-        )?;
-        assert_eq!(
-            received
-                .data
-                .into_iter()
-                .map(|tx_db| tx_db.tx.get_hash())
-                .collect::<Vec<_>>(),
-            vec![Hash([4; 32]), Hash([5; 32]), Hash([6; 32]), Hash([7; 32])],
-        );
-        assert!(!received.has_next_page);
-        assert!(!received.has_previous_page);
-
-        Ok(())
-    }
-
-    #[test]
-    fn test_get_txs_history_bc_sent() -> KvResult<()> {
-        let gva_db = duniter_gva_db::GvaV1Db::<Mem>::open(MemConf::default())?;
-        let db_reader = create_dbs_reader(unsafe { std::mem::transmute(&gva_db.get_ro_handler()) });
-
-        let s1 = WalletScriptV10::single_sig(PublicKey::default());
-        let s1_hash = Hash::compute(&s1.to_string().as_bytes());
-
-        gva_db.txs_write().upsert(
-            HashKeyV2(Hash::default()),
-            gen_tx(Hash::default(), BlockNumber(1)),
-        )?;
-        gva_db.txs_write().upsert(
-            HashKeyV2(Hash([1; 32])),
-            gen_tx(Hash([1; 32]), BlockNumber(1)),
-        )?;
-        gva_db.txs_write().upsert(
-            HashKeyV2(Hash([2; 32])),
-            gen_tx(Hash([2; 32]), BlockNumber(1)),
-        )?;
-        gva_db.txs_write().upsert(
-            HashKeyV2(Hash([3; 32])),
-            gen_tx(Hash([3; 32]), BlockNumber(1)),
-        )?;
-        gva_db.txs_by_issuer_write().upsert(
-            WalletHashWithBnV1Db::new(s1_hash, BlockNumber(1)),
-            btreeset![Hash::default(), Hash([1; 32]), Hash([2; 32]), Hash([3; 32])],
-        )?;
-        gva_db.txs_write().upsert(
-            HashKeyV2(Hash([4; 32])),
-            gen_tx(Hash([4; 32]), BlockNumber(2)),
-        )?;
-        gva_db.txs_write().upsert(
-            HashKeyV2(Hash([5; 32])),
-            gen_tx(Hash([5; 32]), BlockNumber(2)),
-        )?;
-        gva_db.txs_by_issuer_write().upsert(
-            WalletHashWithBnV1Db::new(s1_hash, BlockNumber(2)),
-            btreeset![Hash([4; 32]), Hash([5; 32])],
-        )?;
-
-        let sent = db_reader.get_txs_history_bc_sent(
-            None,
-            PageInfo {
-                order: true,
-                limit_opt: None,
-                pos: Some(TxBcCursor {
-                    tx_hash: Hash([1; 32]),
-                    block_number: BlockNumber(1),
-                }),
-            },
-            s1_hash,
-            None,
-        )?;
-        assert_eq!(
-            sent.data
-                .into_iter()
-                .map(|tx_db| tx_db.tx.get_hash())
-                .collect::<Vec<_>>(),
-            vec![Hash([2; 32]), Hash([3; 32]), Hash([4; 32]), Hash([5; 32])],
-        );
-        assert!(!sent.has_next_page);
-        assert!(!sent.has_previous_page);
-
-        let sent = db_reader.get_txs_history_bc_sent(
-            None,
-            PageInfo {
-                order: false,
-                limit_opt: None,
-                pos: Some(TxBcCursor {
-                    tx_hash: Hash([1; 32]),
-                    block_number: BlockNumber(1),
-                }),
-            },
-            s1_hash,
-            None,
-        )?;
-        assert_eq!(
-            sent.data
-                .into_iter()
-                .map(|tx_db| tx_db.tx.get_hash())
-                .collect::<Vec<_>>(),
-            vec![Hash([0; 32])],
-        );
-        assert!(!sent.has_next_page);
-        assert!(!sent.has_previous_page);
-
-        let sent = db_reader.get_txs_history_bc_sent(
-            None,
-            PageInfo {
-                order: false,
-                limit_opt: None,
-                pos: Some(TxBcCursor {
-                    tx_hash: Hash([5; 32]),
-                    block_number: BlockNumber(2),
-                }),
-            },
-            s1_hash,
-            None,
-        )?;
-        assert_eq!(
-            sent.data
-                .into_iter()
-                .map(|tx_db| tx_db.tx.get_hash())
-                .collect::<Vec<_>>(),
-            vec![
-                Hash([4; 32]),
-                Hash([3; 32]),
-                Hash([2; 32]),
-                Hash([1; 32]),
-                Hash([0; 32]),
-            ],
-        );
-        assert!(!sent.has_next_page);
-        assert!(!sent.has_previous_page);
-
-        Ok(())
-    }
-}
diff --git a/rust-libs/modules/gva/dbs-reader/src/uds_of_pubkey.rs b/rust-libs/modules/gva/dbs-reader/src/uds_of_pubkey.rs
deleted file mode 100644
index 8ae09a58d..000000000
--- a/rust-libs/modules/gva/dbs-reader/src/uds_of_pubkey.rs
+++ /dev/null
@@ -1,829 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-use duniter_dbs::smallvec::SmallVec;
-use duniter_dbs::{
-    databases::bc_v2::{UdsEvent, UdsRevalEvent},
-    UdIdV2,
-};
-
-#[derive(Debug, Default)]
-pub struct UdsWithSum {
-    pub uds: Vec<(BlockNumber, SourceAmount)>,
-    pub sum: SourceAmount,
-}
-
-impl DbsReaderImpl {
-    pub(super) fn all_uds_of_pubkey_(
-        &self,
-        bc_db: &BcV2DbRo<FileBackend>,
-        pubkey: PublicKey,
-        page_info: PageInfo<BlockNumber>,
-    ) -> KvResult<PagedData<UdsWithSum>> {
-        (
-            bc_db.uds_reval(),
-            self.0.blocks_with_ud(),
-            self.0.gva_identities(),
-        )
-            .read(|(uds_reval, blocks_with_ud, gva_identities)| {
-                if let Some(gva_idty) = gva_identities.get(&PubKeyKeyV2(pubkey))? {
-                    match page_info.pos {
-                        None => {
-                            if page_info.order {
-                                blocks_with_ud.iter(.., move |it| {
-                                    all_uds_of_pubkey_inner::<FileBackend, _>(
-                                        gva_idty,
-                                        page_info,
-                                        it.keys().map_ok(|bn| BlockNumber(bn.0)),
-                                        uds_reval,
-                                        None,
-                                    )
-                                })
-                            } else {
-                                let last_ud_opt =
-                                    blocks_with_ud.iter_rev(.., |it| it.keys().next_res())?;
-                                blocks_with_ud.iter_rev(.., move |it| {
-                                    all_uds_of_pubkey_inner::<FileBackend, _>(
-                                        gva_idty,
-                                        page_info,
-                                        it.keys().map_ok(|bn| BlockNumber(bn.0)),
-                                        uds_reval,
-                                        last_ud_opt.map(|bn| BlockNumber(bn.0)),
-                                    )
-                                })
-                            }
-                        }
-                        Some(pos) => {
-                            if page_info.order {
-                                blocks_with_ud.iter(U32BE(pos.0).., move |it| {
-                                    all_uds_of_pubkey_inner::<FileBackend, _>(
-                                        gva_idty,
-                                        page_info,
-                                        it.keys().map_ok(|bn| BlockNumber(bn.0)),
-                                        uds_reval,
-                                        None,
-                                    )
-                                })
-                            } else {
-                                let last_ud_opt =
-                                    blocks_with_ud.iter_rev(.., |it| it.keys().next_res())?;
-                                blocks_with_ud.iter_rev(..=U32BE(pos.0), move |it| {
-                                    all_uds_of_pubkey_inner::<FileBackend, _>(
-                                        gva_idty,
-                                        page_info,
-                                        it.keys().map_ok(|bn| BlockNumber(bn.0)),
-                                        uds_reval,
-                                        last_ud_opt.map(|bn| BlockNumber(bn.0)),
-                                    )
-                                })
-                            }
-                        }
-                    }
-                } else {
-                    Ok(PagedData::empty())
-                }
-            })
-    }
-
-    pub(super) fn unspent_uds_of_pubkey_(
-        &self,
-        bc_db: &BcV2DbRo<FileBackend>,
-        pubkey: PublicKey,
-        page_info: PageInfo<BlockNumber>,
-        bn_to_exclude_opt: Option<&BTreeSet<BlockNumber>>,
-        amount_target_opt: Option<SourceAmount>,
-    ) -> KvResult<PagedData<UdsWithSum>> {
-        (bc_db.uds(), bc_db.uds_reval()).read(|(uds, uds_reval)| {
-            let (first_ud_opt, last_ud_opt) = if page_info.not_all() {
-                get_first_and_last_unspent_ud(&uds, pubkey, bn_to_exclude_opt)?
-            } else {
-                (None, None)
-            };
-            let mut blocks_numbers = if let Some(pos) = page_info.pos {
-                if page_info.order {
-                    uds.iter(
-                        UdIdV2(pubkey, pos)..UdIdV2(pubkey, BlockNumber(u32::MAX)),
-                        |it| {
-                            let it = it.keys().map_ok(|UdIdV2(_p, bn)| bn);
-                            if let Some(bn_to_exclude) = bn_to_exclude_opt {
-                                it.filter_ok(|bn| !bn_to_exclude.contains(&bn))
-                                    .collect::<KvResult<Vec<_>>>()
-                            } else {
-                                it.collect::<KvResult<Vec<_>>>()
-                            }
-                        },
-                    )?
-                } else {
-                    uds.iter_rev(UdIdV2(pubkey, BlockNumber(0))..=UdIdV2(pubkey, pos), |it| {
-                        let it = it.keys().map_ok(|UdIdV2(_p, bn)| bn);
-                        if let Some(bn_to_exclude) = bn_to_exclude_opt {
-                            it.filter_ok(|bn| !bn_to_exclude.contains(&bn))
-                                .collect::<KvResult<Vec<_>>>()
-                        } else {
-                            it.collect::<KvResult<Vec<_>>>()
-                        }
-                    })?
-                }
-            } else if page_info.order {
-                uds.iter(
-                    UdIdV2(pubkey, BlockNumber(0))..UdIdV2(pubkey, BlockNumber(u32::MAX)),
-                    |it| {
-                        let it = it.keys().map_ok(|UdIdV2(_p, bn)| bn);
-                        if let Some(bn_to_exclude) = bn_to_exclude_opt {
-                            it.filter_ok(|bn| !bn_to_exclude.contains(&bn))
-                                .collect::<KvResult<Vec<_>>>()
-                        } else {
-                            it.collect::<KvResult<Vec<_>>>()
-                        }
-                    },
-                )?
-            } else {
-                uds.iter_rev(
-                    UdIdV2(pubkey, BlockNumber(0))..UdIdV2(pubkey, BlockNumber(u32::MAX)),
-                    |it| {
-                        let it = it.keys().map_ok(|UdIdV2(_p, bn)| bn);
-                        if let Some(bn_to_exclude) = bn_to_exclude_opt {
-                            it.filter_ok(|bn| !bn_to_exclude.contains(&bn))
-                                .collect::<KvResult<Vec<_>>>()
-                        } else {
-                            it.collect::<KvResult<Vec<_>>>()
-                        }
-                    },
-                )?
-            };
-
-            if blocks_numbers.is_empty() {
-                Ok(PagedData::empty())
-            } else {
-                if let Some(limit) = page_info.limit_opt {
-                    blocks_numbers.truncate(limit.get());
-                }
-                let first_block_number = if page_info.order {
-                    blocks_numbers[0]
-                } else {
-                    blocks_numbers[blocks_numbers.len() - 1]
-                };
-                let first_reval = uds_reval
-                    .iter_rev(..=U32BE(first_block_number.0), |it| it.keys().next_res())?
-                    .expect("corrupted db");
-                let blocks_numbers_len = blocks_numbers.len();
-                let blocks_numbers = blocks_numbers.into_iter();
-                let uds_with_sum = if page_info.order {
-                    collect_uds(
-                        blocks_numbers,
-                        blocks_numbers_len,
-                        first_reval,
-                        uds_reval,
-                        amount_target_opt,
-                    )?
-                } else {
-                    collect_uds(
-                        blocks_numbers.rev(),
-                        blocks_numbers_len,
-                        first_reval,
-                        uds_reval,
-                        amount_target_opt,
-                    )?
-                };
-                Ok(PagedData {
-                    has_previous_page: has_previous_page(
-                        uds_with_sum.uds.iter().map(|(bn, _sa)| bn.into()),
-                        first_ud_opt,
-                        page_info,
-                        true,
-                    ),
-                    has_next_page: has_next_page(
-                        uds_with_sum.uds.iter().map(|(bn, _sa)| bn.into()),
-                        last_ud_opt,
-                        page_info,
-                        true,
-                    ),
-                    data: uds_with_sum,
-                })
-            }
-        })
-    }
-}
-
-fn all_uds_of_pubkey_inner<B, I>(
-    gva_idty: GvaIdtyDbV1,
-    page_info: PageInfo<BlockNumber>,
-    blocks_with_ud: I,
-    uds_reval: TxColRo<B::Col, UdsRevalEvent>,
-    last_ud_opt: Option<BlockNumber>,
-) -> KvResult<PagedData<UdsWithSum>>
-where
-    B: Backend,
-    I: Iterator<Item = KvResult<BlockNumber>>,
-{
-    let first_ud = gva_idty.first_ud;
-    let mut blocks_numbers = filter_blocks_numbers(gva_idty, page_info, blocks_with_ud)?;
-
-    if blocks_numbers.is_empty() {
-        return Ok(PagedData::empty());
-    }
-
-    let not_reach_end = if page_info.order {
-        if let Some(limit) = page_info.limit_opt {
-            if blocks_numbers.len() <= limit.get() {
-                false
-            } else {
-                blocks_numbers.pop();
-                true
-            }
-        } else {
-            false
-        }
-    } else if let Some(last_ud) = last_ud_opt {
-        blocks_numbers[0] != last_ud
-    } else {
-        false
-    };
-    let blocks_numbers_len = blocks_numbers.len();
-
-    let first_block_number = if page_info.order {
-        blocks_numbers[0]
-    } else {
-        blocks_numbers[blocks_numbers_len - 1]
-    };
-
-    let first_reval = uds_reval
-        .iter_rev(..=U32BE(first_block_number.0), |it| it.keys().next_res())?
-        .expect("corrupted db");
-
-    let uds_with_sum = if page_info.order {
-        collect_uds(
-            blocks_numbers.into_iter(),
-            blocks_numbers_len,
-            first_reval,
-            uds_reval,
-            None,
-        )?
-    } else {
-        collect_uds(
-            blocks_numbers.into_iter().rev(),
-            blocks_numbers_len,
-            first_reval,
-            uds_reval,
-            None,
-        )?
-    };
-
-    Ok(PagedData {
-        has_previous_page: has_previous_page(
-            uds_with_sum.uds.iter().map(|(bn, _sa)| bn.into()),
-            first_ud,
-            page_info,
-            true,
-        ),
-        has_next_page: not_reach_end,
-        data: uds_with_sum,
-    })
-}
-
-fn filter_blocks_numbers<I: Iterator<Item = KvResult<BlockNumber>>>(
-    gva_idty: GvaIdtyDbV1,
-    page_info: PageInfo<BlockNumber>,
-    blocks_with_ud: I,
-) -> KvResult<Vec<BlockNumber>> {
-    let mut is_member_changes = SmallVec::<[BlockNumber; 4]>::new();
-    for (join, leave) in gva_idty.joins.iter().zip(gva_idty.leaves.iter()) {
-        is_member_changes.push(*join);
-        is_member_changes.push(*leave);
-    }
-    if gva_idty.joins.len() > gva_idty.leaves.len() {
-        is_member_changes.push(*gva_idty.joins.last().unwrap_or_else(|| unreachable!()));
-    }
-
-    if page_info.order {
-        let mut i = 0;
-        let mut is_member = false;
-        if let Some(limit) = page_info.limit_opt {
-            blocks_with_ud
-                .filter_ok(|bn| {
-                    while i < is_member_changes.len() && *bn >= is_member_changes[i] {
-                        is_member = !is_member;
-                        i += 1;
-                    }
-                    is_member
-                })
-                .take(limit.get() + 1)
-                .collect::<KvResult<Vec<_>>>()
-        } else {
-            blocks_with_ud
-                .filter_ok(|bn| {
-                    while i < is_member_changes.len() && *bn >= is_member_changes[i] {
-                        is_member = !is_member;
-                        i += 1;
-                    }
-                    is_member
-                })
-                .collect::<KvResult<Vec<_>>>()
-        }
-    } else {
-        let is_member_changes: SmallVec<[BlockNumber; 4]> =
-            is_member_changes.into_iter().rev().collect();
-        let mut i = 0;
-        let mut is_member = gva_idty.is_member;
-        if let Some(limit) = page_info.limit_opt {
-            blocks_with_ud
-                .filter_ok(|bn| {
-                    /*println!(
-                        "TMP (bn, is_member_changes[{}])=({}, {})",
-                        i, bn, is_member_changes[i]
-                    );*/
-                    while i < is_member_changes.len() && *bn < is_member_changes[i] {
-                        is_member = !is_member;
-                        i += 1;
-                    }
-                    is_member
-                })
-                .take(limit.get())
-                .collect::<KvResult<Vec<_>>>()
-        } else {
-            blocks_with_ud
-                .filter_ok(|bn| {
-                    while i < is_member_changes.len() && *bn < is_member_changes[i] {
-                        is_member = !is_member;
-                        i += 1;
-                    }
-                    is_member
-                })
-                .collect::<KvResult<Vec<_>>>()
-        }
-    }
-}
-
-fn get_first_and_last_unspent_ud<BC: BackendCol>(
-    uds: &TxColRo<BC, UdsEvent>,
-    pubkey: PublicKey,
-    bn_to_exclude_opt: Option<&BTreeSet<BlockNumber>>,
-) -> KvResult<(Option<BlockNumber>, Option<BlockNumber>)> {
-    if let Some(bn_to_exclude) = bn_to_exclude_opt {
-        Ok((
-            uds.iter(
-                UdIdV2(pubkey, BlockNumber(0))..UdIdV2(pubkey, BlockNumber(u32::MAX)),
-                |it| {
-                    it.keys()
-                        .filter_map_ok(|UdIdV2(_p, bn)| {
-                            if !bn_to_exclude.contains(&bn) {
-                                Some(bn)
-                            } else {
-                                None
-                            }
-                        })
-                        .next_res()
-                },
-            )?,
-            uds.iter_rev(
-                UdIdV2(pubkey, BlockNumber(0))..UdIdV2(pubkey, BlockNumber(u32::MAX)),
-                |it| {
-                    it.keys()
-                        .filter_map_ok(|UdIdV2(_p, bn)| {
-                            if !bn_to_exclude.contains(&bn) {
-                                Some(bn)
-                            } else {
-                                None
-                            }
-                        })
-                        .next_res()
-                },
-            )?,
-        ))
-    } else {
-        Ok((
-            uds.iter(
-                UdIdV2(pubkey, BlockNumber(0))..UdIdV2(pubkey, BlockNumber(u32::MAX)),
-                |it| it.keys().map_ok(|UdIdV2(_p, bn)| bn).next_res(),
-            )?,
-            uds.iter_rev(
-                UdIdV2(pubkey, BlockNumber(0))..UdIdV2(pubkey, BlockNumber(u32::MAX)),
-                |it| it.keys().map_ok(|UdIdV2(_p, bn)| bn).next_res(),
-            )?,
-        ))
-    }
-}
-
-macro_rules! collect_one_ud {
-    ($block_number:ident, $current_ud:ident, $uds:ident, $sum:ident, $amount_target_opt:ident) => {
-        $uds.push(($block_number, $current_ud));
-        $sum = $sum + $current_ud;
-        if let Some(amount_target) = $amount_target_opt {
-            if $sum >= amount_target {
-                return Ok(UdsWithSum { $uds, $sum });
-            }
-        }
-    };
-}
-
-fn collect_uds<BC: BackendCol, I: Iterator<Item = BlockNumber>>(
-    mut blocks_numbers: I,
-    blocks_numbers_len: usize,
-    first_reval: U32BE,
-    uds_reval: TxColRo<BC, UdsRevalEvent>,
-    amount_opt: Option<SourceAmount>,
-) -> KvResult<UdsWithSum> {
-    let uds_revals = uds_reval.iter(first_reval.., |it| it.collect::<KvResult<Vec<_>>>())?;
-
-    if uds_revals.is_empty() {
-        Ok(UdsWithSum::default())
-    } else {
-        let mut current_ud = (uds_revals[0].1).0;
-        let mut uds = Vec::with_capacity(blocks_numbers_len);
-        let mut sum = SourceAmount::ZERO;
-
-        // Uds before last reval
-        for (block_reval, amount_reval) in &uds_revals[1..] {
-            'blocks_numbers: while let Some(block_number) = blocks_numbers.next() {
-                if block_number.0 >= block_reval.0 {
-                    current_ud = amount_reval.0;
-                    collect_one_ud!(block_number, current_ud, uds, sum, amount_opt);
-                    break 'blocks_numbers;
-                } else {
-                    collect_one_ud!(block_number, current_ud, uds, sum, amount_opt);
-                }
-            }
-        }
-
-        // Uds after last reval
-        for block_number in blocks_numbers {
-            collect_one_ud!(block_number, current_ud, uds, sum, amount_opt);
-        }
-
-        Ok(UdsWithSum { uds, sum })
-    }
-}
-
-#[cfg(test)]
-mod tests {
-
-    use super::*;
-    use duniter_dbs::smallvec::smallvec as svec;
-    use duniter_dbs::{databases::bc_v2::BcV2DbWritable, SourceAmountValV2, UdIdV2};
-    use duniter_gva_db::GvaV1DbWritable;
-
-    #[test]
-    fn test_filter_blocks_numbers() -> KvResult<()> {
-        let idty = GvaIdtyDbV1 {
-            is_member: true,
-            joins: svec![BlockNumber(26), BlockNumber(51)],
-            leaves: [BlockNumber(32)].iter().copied().collect(),
-            first_ud: Some(BlockNumber(29)),
-        };
-        let blocks_with_ud = vec![
-            BlockNumber(3),
-            BlockNumber(9),
-            BlockNumber(15),
-            BlockNumber(22),
-            BlockNumber(29),
-            BlockNumber(35),
-            BlockNumber(42),
-            BlockNumber(48),
-            BlockNumber(54),
-            BlockNumber(60),
-        ];
-
-        assert_eq!(
-            filter_blocks_numbers(
-                idty.clone(),
-                PageInfo {
-                    pos: None,
-                    order: true,
-                    limit_opt: NonZeroUsize::new(1),
-                },
-                blocks_with_ud.iter().copied().map(Ok),
-            )?,
-            vec![BlockNumber(29), BlockNumber(54)]
-        );
-        assert_eq!(
-            filter_blocks_numbers(
-                idty,
-                PageInfo {
-                    pos: None,
-                    order: false,
-                    limit_opt: None,
-                },
-                blocks_with_ud.into_iter().rev().map(Ok),
-            )?,
-            vec![BlockNumber(60), BlockNumber(54), BlockNumber(29)]
-        );
-        Ok(())
-    }
-
-    #[test]
-    fn test_all_uds_of_pubkey() -> KvResult<()> {
-        let pk = PublicKey::default();
-        let idty = GvaIdtyDbV1 {
-            is_member: true,
-            joins: svec![BlockNumber(26), BlockNumber(51)],
-            leaves: [BlockNumber(32)].iter().copied().collect(),
-            first_ud: Some(BlockNumber(29)),
-        };
-
-        let bc_db = duniter_dbs::databases::bc_v2::BcV2Db::<Mem>::open(MemConf::default())?;
-        let bc_db_ro = bc_db.get_ro_handler();
-        let gva_db = duniter_gva_db::GvaV1Db::<Mem>::open(MemConf::default())?;
-        let db_reader = create_dbs_reader(unsafe { std::mem::transmute(&gva_db.get_ro_handler()) });
-        bc_db
-            .uds_reval_write()
-            .upsert(U32BE(0), SourceAmountValV2(SourceAmount::with_base0(10)))?;
-        bc_db
-            .uds_reval_write()
-            .upsert(U32BE(40), SourceAmountValV2(SourceAmount::with_base0(12)))?;
-        gva_db
-            .gva_identities_write()
-            .upsert(PubKeyKeyV2(pk), idty)?;
-        gva_db.blocks_with_ud_write().upsert(U32BE(22), ())?;
-        gva_db.blocks_with_ud_write().upsert(U32BE(29), ())?;
-        gva_db.blocks_with_ud_write().upsert(U32BE(35), ())?;
-        gva_db.blocks_with_ud_write().upsert(U32BE(42), ())?;
-        gva_db.blocks_with_ud_write().upsert(U32BE(48), ())?;
-        gva_db.blocks_with_ud_write().upsert(U32BE(54), ())?;
-        gva_db.blocks_with_ud_write().upsert(U32BE(60), ())?;
-
-        // Get all uds
-        let PagedData {
-            data: UdsWithSum { uds, sum },
-            has_previous_page,
-            has_next_page,
-        } = db_reader.all_uds_of_pubkey(&bc_db_ro, pk, PageInfo::default())?;
-        assert_eq!(
-            uds,
-            vec![
-                (BlockNumber(29), SourceAmount::with_base0(10)),
-                (BlockNumber(54), SourceAmount::with_base0(12)),
-                (BlockNumber(60), SourceAmount::with_base0(12)),
-            ]
-        );
-        assert_eq!(sum, SourceAmount::with_base0(34));
-        assert!(!has_previous_page);
-        assert!(!has_next_page);
-
-        // Get all uds with limit
-        let PagedData {
-            data: UdsWithSum { uds, sum },
-            has_previous_page,
-            has_next_page,
-        } = db_reader.all_uds_of_pubkey(
-            &bc_db_ro,
-            pk,
-            PageInfo {
-                limit_opt: NonZeroUsize::new(2),
-                ..Default::default()
-            },
-        )?;
-        assert_eq!(
-            uds,
-            vec![
-                (BlockNumber(29), SourceAmount::with_base0(10)),
-                (BlockNumber(54), SourceAmount::with_base0(12)),
-            ]
-        );
-        assert_eq!(sum, SourceAmount::with_base0(22));
-        assert!(!has_previous_page);
-        assert!(has_next_page);
-
-        // Get all uds from particular position
-        let PagedData {
-            data: UdsWithSum { uds, sum },
-            has_previous_page,
-            has_next_page,
-        } = db_reader.all_uds_of_pubkey(
-            &bc_db_ro,
-            pk,
-            PageInfo {
-                pos: Some(BlockNumber(50)),
-                ..Default::default()
-            },
-        )?;
-        assert_eq!(
-            uds,
-            vec![
-                (BlockNumber(54), SourceAmount::with_base0(12)),
-                (BlockNumber(60), SourceAmount::with_base0(12)),
-            ]
-        );
-        assert_eq!(sum, SourceAmount::with_base0(24));
-        assert!(has_previous_page);
-        assert!(!has_next_page);
-
-        // Get all uds on DESC order
-        let PagedData {
-            data: UdsWithSum { uds, sum },
-            has_previous_page,
-            has_next_page,
-        } = db_reader.all_uds_of_pubkey(
-            &bc_db_ro,
-            pk,
-            PageInfo {
-                order: false,
-                ..Default::default()
-            },
-        )?;
-        assert_eq!(
-            uds,
-            vec![
-                (BlockNumber(29), SourceAmount::with_base0(10)),
-                (BlockNumber(54), SourceAmount::with_base0(12)),
-                (BlockNumber(60), SourceAmount::with_base0(12)),
-            ]
-        );
-        assert_eq!(sum, SourceAmount::with_base0(34));
-        assert!(!has_previous_page);
-        assert!(!has_next_page);
-
-        // Get all uds on DESC order with limit
-        let PagedData {
-            data: UdsWithSum { uds, sum },
-            has_previous_page,
-            has_next_page,
-        } = db_reader.all_uds_of_pubkey(
-            &bc_db_ro,
-            pk,
-            PageInfo {
-                order: false,
-                limit_opt: NonZeroUsize::new(2),
-                ..Default::default()
-            },
-        )?;
-        assert_eq!(
-            uds,
-            vec![
-                (BlockNumber(54), SourceAmount::with_base0(12)),
-                (BlockNumber(60), SourceAmount::with_base0(12)),
-            ]
-        );
-        assert_eq!(sum, SourceAmount::with_base0(24));
-        assert!(has_previous_page);
-        assert!(!has_next_page);
-
-        // Get all uds on DESC order from particular position
-        let PagedData {
-            data: UdsWithSum { uds, sum },
-            has_previous_page,
-            has_next_page,
-        } = db_reader.all_uds_of_pubkey(
-            &bc_db_ro,
-            pk,
-            PageInfo {
-                pos: Some(BlockNumber(55)),
-                order: false,
-                ..Default::default()
-            },
-        )?;
-        assert_eq!(
-            uds,
-            vec![
-                (BlockNumber(29), SourceAmount::with_base0(10)),
-                (BlockNumber(54), SourceAmount::with_base0(12)),
-            ]
-        );
-        assert_eq!(sum, SourceAmount::with_base0(22));
-        assert!(!has_previous_page);
-        assert!(has_next_page);
-
-        Ok(())
-    }
-
-    #[test]
-    fn test_unspent_uds_of_pubkey() -> KvResult<()> {
-        let pk = PublicKey::default();
-        let bc_db = duniter_dbs::databases::bc_v2::BcV2Db::<Mem>::open(MemConf::default())?;
-        let bc_db_ro = bc_db.get_ro_handler();
-        let dbs_reader = DbsReaderImpl::mem();
-
-        bc_db
-            .uds_reval_write()
-            .upsert(U32BE(0), SourceAmountValV2(SourceAmount::with_base0(10)))?;
-        bc_db
-            .uds_reval_write()
-            .upsert(U32BE(40), SourceAmountValV2(SourceAmount::with_base0(12)))?;
-
-        bc_db.uds_write().upsert(UdIdV2(pk, BlockNumber(0)), ())?;
-        bc_db.uds_write().upsert(UdIdV2(pk, BlockNumber(10)), ())?;
-        bc_db.uds_write().upsert(UdIdV2(pk, BlockNumber(20)), ())?;
-        bc_db.uds_write().upsert(UdIdV2(pk, BlockNumber(30)), ())?;
-        bc_db.uds_write().upsert(UdIdV2(pk, BlockNumber(40)), ())?;
-        bc_db.uds_write().upsert(UdIdV2(pk, BlockNumber(50)), ())?;
-        bc_db.uds_write().upsert(UdIdV2(pk, BlockNumber(60)), ())?;
-
-        // Get unspent uds
-        let PagedData {
-            data: UdsWithSum { uds, sum },
-            has_previous_page,
-            has_next_page,
-        } = dbs_reader.unspent_uds_of_pubkey(&bc_db_ro, pk, PageInfo::default(), None, None)?;
-        assert_eq!(uds.len(), 7);
-        assert_eq!(
-            uds.first(),
-            Some(&(BlockNumber(0), SourceAmount::with_base0(10)))
-        );
-        assert_eq!(
-            uds.last(),
-            Some(&(BlockNumber(60), SourceAmount::with_base0(12)))
-        );
-        assert_eq!(sum, SourceAmount::with_base0(76));
-        assert!(!has_previous_page);
-        assert!(!has_next_page);
-
-        // Get unspent uds from particular position
-        let PagedData {
-            data: UdsWithSum { uds, sum },
-            has_previous_page,
-            has_next_page,
-        } = dbs_reader.unspent_uds_of_pubkey(
-            &bc_db_ro,
-            pk,
-            PageInfo {
-                pos: Some(BlockNumber(30)),
-                ..Default::default()
-            },
-            None,
-            None,
-        )?;
-        assert_eq!(uds.len(), 4);
-        assert_eq!(
-            uds.first(),
-            Some(&(BlockNumber(30), SourceAmount::with_base0(10)))
-        );
-        assert_eq!(
-            uds.last(),
-            Some(&(BlockNumber(60), SourceAmount::with_base0(12)))
-        );
-        assert_eq!(sum, SourceAmount::with_base0(46));
-        assert!(has_previous_page);
-        assert!(!has_next_page);
-
-        // Get unspent uds in order DESC
-        let PagedData {
-            data: UdsWithSum { uds, sum },
-            has_previous_page,
-            has_next_page,
-        } = dbs_reader.unspent_uds_of_pubkey(
-            &bc_db_ro,
-            pk,
-            PageInfo {
-                order: false,
-                ..Default::default()
-            },
-            None,
-            None,
-        )?;
-        assert_eq!(uds.len(), 7);
-        assert_eq!(
-            uds.first(),
-            Some(&(BlockNumber(0), SourceAmount::with_base0(10)))
-        );
-        assert_eq!(
-            uds.last(),
-            Some(&(BlockNumber(60), SourceAmount::with_base0(12)))
-        );
-        assert_eq!(sum, SourceAmount::with_base0(76));
-        assert!(!has_previous_page);
-        assert!(!has_next_page);
-
-        // Get unspent uds in order DESC from particular position
-        let PagedData {
-            data: UdsWithSum { uds, sum },
-            has_previous_page,
-            has_next_page,
-        } = dbs_reader.unspent_uds_of_pubkey(
-            &bc_db_ro,
-            pk,
-            PageInfo {
-                pos: Some(BlockNumber(40)),
-                order: false,
-                ..Default::default()
-            },
-            None,
-            None,
-        )?;
-        assert_eq!(uds.len(), 5);
-        assert_eq!(
-            uds.first(),
-            Some(&(BlockNumber(0), SourceAmount::with_base0(10)))
-        );
-        assert_eq!(
-            uds.last(),
-            Some(&(BlockNumber(40), SourceAmount::with_base0(12)))
-        );
-        assert_eq!(sum, SourceAmount::with_base0(52));
-        assert!(!has_previous_page);
-        assert!(has_next_page);
-
-        Ok(())
-    }
-}
diff --git a/rust-libs/modules/gva/dbs-reader/src/utxos.rs b/rust-libs/modules/gva/dbs-reader/src/utxos.rs
deleted file mode 100644
index ab19edcc6..000000000
--- a/rust-libs/modules/gva/dbs-reader/src/utxos.rs
+++ /dev/null
@@ -1,500 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use dubp::documents::dubp_wallet::prelude::*;
-use duniter_dbs::SourceAmountValV2;
-
-use crate::*;
-
-#[derive(Clone, Copy, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
-pub struct UtxoCursor {
-    pub block_number: BlockNumber,
-    pub tx_hash: Hash,
-    pub output_index: u8,
-}
-impl std::fmt::Display for UtxoCursor {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(
-            f,
-            "{}:{}:{}",
-            self.block_number, self.tx_hash, self.output_index,
-        )
-    }
-}
-
-impl FromStr for UtxoCursor {
-    type Err = WrongCursor;
-
-    fn from_str(s: &str) -> Result<Self, Self::Err> {
-        let mut s = s.split(':');
-        let block_number = s
-            .next()
-            .ok_or(WrongCursor)?
-            .parse()
-            .map_err(|_| WrongCursor)?;
-        let tx_hash = Hash::from_hex(s.next().ok_or(WrongCursor)?).map_err(|_| WrongCursor)?;
-        let output_index = s
-            .next()
-            .ok_or(WrongCursor)?
-            .parse()
-            .map_err(|_| WrongCursor)?;
-        Ok(Self {
-            block_number,
-            tx_hash,
-            output_index,
-        })
-    }
-}
-
-#[derive(Debug, Default)]
-pub struct UtxosWithSum {
-    pub utxos: Vec<(UtxoCursor, SourceAmount)>,
-    pub sum: SourceAmount,
-}
-
-impl DbsReaderImpl {
-    pub(super) fn find_script_utxos_<TxsMpDb: 'static + TxsMpV2DbReadable>(
-        &self,
-        txs_mp_db_ro: &TxsMpDb,
-        amount_target_opt: Option<SourceAmount>,
-        page_info: PageInfo<UtxoCursor>,
-        script: &WalletScriptV10,
-    ) -> anyhow::Result<PagedData<UtxosWithSum>> {
-        let mempool_filter = |k_res: KvResult<GvaUtxoIdDbV1>| match k_res {
-            Ok(gva_utxo_id) => {
-                match txs_mp_db_ro.utxos_ids().contains_key(&UtxoIdDbV2(
-                    gva_utxo_id.get_tx_hash(),
-                    gva_utxo_id.get_output_index() as u32,
-                )) {
-                    Ok(false) => Some(Ok(gva_utxo_id)),
-                    Ok(true) => None,
-                    Err(e) => Some(Err(e)),
-                }
-            }
-            Err(e) => Some(Err(e)),
-        };
-
-        let script_hash = Hash::compute(script.to_string().as_bytes());
-        let (mut k_min, mut k_max) = GvaUtxoIdDbV1::script_interval(script_hash);
-        let first_cursor_opt = if page_info.not_all() {
-            self.0
-                .gva_utxos()
-                .iter(k_min..k_max, |it| {
-                    it.keys().filter_map(mempool_filter).next_res()
-                })?
-                .map(|gva_utxo_id| UtxoCursor {
-                    block_number: BlockNumber(gva_utxo_id.get_block_number()),
-                    tx_hash: gva_utxo_id.get_tx_hash(),
-                    output_index: gva_utxo_id.get_output_index(),
-                })
-        } else {
-            None
-        };
-        let last_cursor_opt = if page_info.not_all() {
-            self.0
-                .gva_utxos()
-                .iter_rev(k_min..k_max, |it| {
-                    it.keys().filter_map(mempool_filter).next_res()
-                })?
-                .map(|gva_utxo_id| UtxoCursor {
-                    block_number: BlockNumber(gva_utxo_id.get_block_number()),
-                    tx_hash: gva_utxo_id.get_tx_hash(),
-                    output_index: gva_utxo_id.get_output_index(),
-                })
-        } else {
-            None
-        };
-        if let Some(ref pos) = page_info.pos {
-            if page_info.order {
-                k_min = GvaUtxoIdDbV1::new_(
-                    script_hash,
-                    pos.block_number.0,
-                    pos.tx_hash,
-                    pos.output_index,
-                );
-            } else {
-                k_max = GvaUtxoIdDbV1::new_(
-                    script_hash,
-                    pos.block_number.0,
-                    pos.tx_hash,
-                    pos.output_index,
-                );
-            }
-        }
-        let UtxosWithSum { utxos, mut sum } = if page_info.order {
-            self.0.gva_utxos().iter(k_min..k_max, |it| {
-                find_script_utxos_inner(txs_mp_db_ro, amount_target_opt, page_info, it)
-            })?
-        } else {
-            self.0.gva_utxos().iter_rev(k_min..k_max, |it| {
-                find_script_utxos_inner(txs_mp_db_ro, amount_target_opt, page_info, it)
-            })?
-        };
-
-        if amount_target_opt.is_none() {
-            sum = utxos.iter().map(|(_utxo_id_with_bn, sa)| *sa).sum();
-        }
-
-        let order = page_info.order;
-
-        Ok(PagedData {
-            has_next_page: has_next_page(
-                utxos
-                    .iter()
-                    .map(|(utxo_id_with_bn, _sa)| utxo_id_with_bn.into()),
-                last_cursor_opt,
-                page_info,
-                order,
-            ),
-            has_previous_page: has_previous_page(
-                utxos
-                    .iter()
-                    .map(|(utxo_id_with_bn, _sa)| utxo_id_with_bn.into()),
-                first_cursor_opt,
-                page_info,
-                order,
-            ),
-            data: UtxosWithSum { utxos, sum },
-        })
-    }
-    pub(super) fn first_scripts_utxos_(
-        &self,
-        amount_target_opt: Option<SourceAmount>,
-        first: usize,
-        scripts: &[WalletScriptV10],
-    ) -> anyhow::Result<Vec<ArrayVec<[Utxo; MAX_FIRST_UTXOS]>>> {
-        let iter = scripts.iter().map(|script| {
-            let (k_min, k_max) =
-                GvaUtxoIdDbV1::script_interval(Hash::compute(script.to_string().as_bytes()));
-            self.0.gva_utxos().iter(k_min..k_max, |it| {
-                it.take(first)
-                    .map_ok(|(k, v)| Utxo {
-                        amount: v.0,
-                        tx_hash: k.get_tx_hash(),
-                        output_index: k.get_output_index(),
-                    })
-                    .collect::<KvResult<_>>()
-            })
-        });
-        if let Some(amount_target) = amount_target_opt {
-            let mut sum = SourceAmount::ZERO;
-            Ok(iter
-                .take_while(|utxos_res: &KvResult<ArrayVec<[Utxo; MAX_FIRST_UTXOS]>>| {
-                    if let Ok(utxos) = utxos_res {
-                        sum = sum + utxos.iter().map(|utxo| utxo.amount).sum();
-                        sum <= amount_target
-                    } else {
-                        true
-                    }
-                })
-                .collect::<KvResult<Vec<_>>>()?)
-        } else {
-            Ok(iter.collect::<KvResult<Vec<_>>>()?)
-        }
-    }
-}
-
-fn find_script_utxos_inner<TxsMpDb, I>(
-    txs_mp_db_ro: &TxsMpDb,
-    amount_target_opt: Option<SourceAmount>,
-    page_info: PageInfo<UtxoCursor>,
-    utxos_iter: I,
-) -> KvResult<UtxosWithSum>
-where
-    TxsMpDb: TxsMpV2DbReadable,
-    I: Iterator<Item = KvResult<(GvaUtxoIdDbV1, SourceAmountValV2)>>,
-{
-    let mut sum = SourceAmount::ZERO;
-
-    let it = utxos_iter.filter_map(|entry_res| match entry_res {
-        Ok((gva_utxo_id, SourceAmountValV2(utxo_amount))) => {
-            if utxo_amount.amount() < super::find_inputs::MIN_AMOUNT {
-                None
-            } else {
-                let tx_hash = gva_utxo_id.get_tx_hash();
-                let output_index = gva_utxo_id.get_output_index();
-                match txs_mp_db_ro
-                    .utxos_ids()
-                    .contains_key(&UtxoIdDbV2(tx_hash, output_index as u32))
-                {
-                    Ok(false) => Some(Ok((
-                        UtxoCursor {
-                            tx_hash,
-                            output_index,
-                            block_number: BlockNumber(gva_utxo_id.get_block_number()),
-                        },
-                        utxo_amount,
-                    ))),
-                    Ok(true) => None,
-                    Err(e) => Some(Err(e)),
-                }
-            }
-        }
-        Err(e) => Some(Err(e)),
-    });
-    let utxos = if let Some(limit) = page_info.limit_opt {
-        if let Some(total_target) = amount_target_opt {
-            it.take(limit.get())
-                .take_while(|res| match res {
-                    Ok((_, utxo_amount)) => {
-                        if sum < total_target {
-                            sum = sum + *utxo_amount;
-                            true
-                        } else {
-                            false
-                        }
-                    }
-                    Err(_) => true,
-                })
-                .collect::<KvResult<Vec<_>>>()?
-        } else {
-            it.take(limit.get()).collect::<KvResult<Vec<_>>>()?
-        }
-    } else if let Some(total_target) = amount_target_opt {
-        it.take_while(|res| match res {
-            Ok((_, utxo_amount)) => {
-                if sum < total_target {
-                    sum = sum + *utxo_amount;
-                    true
-                } else {
-                    false
-                }
-            }
-            Err(_) => true,
-        })
-        .collect::<KvResult<Vec<_>>>()?
-    } else {
-        it.collect::<KvResult<Vec<_>>>()?
-    };
-
-    Ok(UtxosWithSum { utxos, sum })
-}
-
-#[cfg(test)]
-mod tests {
-
-    use super::*;
-    use dubp::crypto::keys::PublicKey as _;
-    use duniter_dbs::databases::txs_mp_v2::TxsMpV2DbWritable;
-    use duniter_gva_db::GvaV1DbWritable;
-    use unwrap::unwrap;
-
-    #[test]
-    fn test_first_scripts_utxos() -> anyhow::Result<()> {
-        let script = WalletScriptV10::single_sig(PublicKey::default());
-        let script2 = WalletScriptV10::single_sig(unwrap!(PublicKey::from_base58(
-            "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
-        )));
-
-        let gva_db = duniter_gva_db::GvaV1Db::<Mem>::open(MemConf::default())?;
-        let db_reader = create_dbs_reader(unsafe { std::mem::transmute(&gva_db.get_ro_handler()) });
-
-        gva_db.gva_utxos_write().upsert(
-            GvaUtxoIdDbV1::new(script.clone(), 0, Hash::default(), 0),
-            SourceAmountValV2(SourceAmount::with_base0(500)),
-        )?;
-        gva_db.gva_utxos_write().upsert(
-            GvaUtxoIdDbV1::new(script.clone(), 1, Hash::default(), 1),
-            SourceAmountValV2(SourceAmount::with_base0(800)),
-        )?;
-        gva_db.gva_utxos_write().upsert(
-            GvaUtxoIdDbV1::new(script.clone(), 2, Hash::default(), 2),
-            SourceAmountValV2(SourceAmount::with_base0(1_200)),
-        )?;
-
-        gva_db.gva_utxos_write().upsert(
-            GvaUtxoIdDbV1::new(script2.clone(), 0, Hash::default(), 0),
-            SourceAmountValV2(SourceAmount::with_base0(400)),
-        )?;
-        gva_db.gva_utxos_write().upsert(
-            GvaUtxoIdDbV1::new(script2.clone(), 1, Hash::default(), 1),
-            SourceAmountValV2(SourceAmount::with_base0(700)),
-        )?;
-        gva_db.gva_utxos_write().upsert(
-            GvaUtxoIdDbV1::new(script2.clone(), 2, Hash::default(), 2),
-            SourceAmountValV2(SourceAmount::with_base0(1_100)),
-        )?;
-
-        assert_eq!(
-            db_reader.first_scripts_utxos(None, 2, &[script, script2])?,
-            vec![
-                [
-                    Utxo {
-                        amount: SourceAmount::with_base0(500),
-                        tx_hash: Hash::default(),
-                        output_index: 0,
-                    },
-                    Utxo {
-                        amount: SourceAmount::with_base0(800),
-                        tx_hash: Hash::default(),
-                        output_index: 1,
-                    },
-                ]
-                .iter()
-                .copied()
-                .collect::<ArrayVec<_>>(),
-                [
-                    Utxo {
-                        amount: SourceAmount::with_base0(400),
-                        tx_hash: Hash::default(),
-                        output_index: 0,
-                    },
-                    Utxo {
-                        amount: SourceAmount::with_base0(700),
-                        tx_hash: Hash::default(),
-                        output_index: 1,
-                    },
-                ]
-                .iter()
-                .copied()
-                .collect::<ArrayVec<_>>()
-            ]
-        );
-
-        Ok(())
-    }
-
-    #[test]
-    fn test_find_script_utxos() -> anyhow::Result<()> {
-        let script = WalletScriptV10::single_sig(PublicKey::default());
-
-        let gva_db = duniter_gva_db::GvaV1Db::<Mem>::open(MemConf::default())?;
-        let db_reader = create_dbs_reader(unsafe { std::mem::transmute(&gva_db.get_ro_handler()) });
-        let txs_mp_db =
-            duniter_dbs::databases::txs_mp_v2::TxsMpV2Db::<Mem>::open(MemConf::default())?;
-
-        gva_db.gva_utxos_write().upsert(
-            GvaUtxoIdDbV1::new(script.clone(), 0, Hash::default(), 0),
-            SourceAmountValV2(SourceAmount::with_base0(500)),
-        )?;
-        gva_db.gva_utxos_write().upsert(
-            GvaUtxoIdDbV1::new(script.clone(), 0, Hash::default(), 1),
-            SourceAmountValV2(SourceAmount::with_base0(800)),
-        )?;
-        gva_db.gva_utxos_write().upsert(
-            GvaUtxoIdDbV1::new(script.clone(), 0, Hash::default(), 2),
-            SourceAmountValV2(SourceAmount::with_base0(1200)),
-        )?;
-
-        // Find utxos with amount target
-        let PagedData {
-            data: UtxosWithSum { utxos, sum },
-            has_next_page,
-            has_previous_page,
-        } = db_reader.find_script_utxos(
-            &txs_mp_db,
-            Some(SourceAmount::with_base0(550)),
-            PageInfo::default(),
-            &script,
-        )?;
-
-        assert_eq!(
-            utxos,
-            vec![
-                (
-                    UtxoCursor {
-                        block_number: BlockNumber(0),
-                        tx_hash: Hash::default(),
-                        output_index: 0,
-                    },
-                    SourceAmount::with_base0(500)
-                ),
-                (
-                    UtxoCursor {
-                        block_number: BlockNumber(0),
-                        tx_hash: Hash::default(),
-                        output_index: 1,
-                    },
-                    SourceAmount::with_base0(800)
-                ),
-            ]
-        );
-        assert_eq!(sum, SourceAmount::with_base0(1300));
-        assert!(!has_next_page);
-        assert!(!has_previous_page);
-
-        // Find utxos with amount target in DESC order
-        let PagedData {
-            data: UtxosWithSum { utxos, sum },
-            ..
-        } = db_reader.find_script_utxos(
-            &txs_mp_db,
-            Some(SourceAmount::with_base0(550)),
-            PageInfo {
-                order: false,
-                ..Default::default()
-            },
-            &script,
-        )?;
-
-        assert_eq!(
-            utxos,
-            vec![(
-                UtxoCursor {
-                    block_number: BlockNumber(0),
-                    tx_hash: Hash::default(),
-                    output_index: 2,
-                },
-                SourceAmount::with_base0(1200)
-            ),]
-        );
-        assert_eq!(sum, SourceAmount::with_base0(1200));
-        assert!(!has_next_page);
-        assert!(!has_previous_page);
-
-        // Find utxos with limit in DESC order
-        let PagedData {
-            data: UtxosWithSum { utxos, sum },
-            has_previous_page,
-            has_next_page,
-        } = db_reader.find_script_utxos(
-            &txs_mp_db,
-            None,
-            PageInfo {
-                order: false,
-                limit_opt: NonZeroUsize::new(2),
-                ..Default::default()
-            },
-            &script,
-        )?;
-
-        assert_eq!(
-            utxos,
-            vec![
-                (
-                    UtxoCursor {
-                        block_number: BlockNumber(0),
-                        tx_hash: Hash::default(),
-                        output_index: 2,
-                    },
-                    SourceAmount::with_base0(1200)
-                ),
-                (
-                    UtxoCursor {
-                        block_number: BlockNumber(0),
-                        tx_hash: Hash::default(),
-                        output_index: 1,
-                    },
-                    SourceAmount::with_base0(800)
-                )
-            ]
-        );
-        assert_eq!(sum, SourceAmount::with_base0(2000));
-        assert!(!has_next_page);
-        assert!(has_previous_page);
-
-        Ok(())
-    }
-}
diff --git a/rust-libs/modules/gva/gql/Cargo.toml b/rust-libs/modules/gva/gql/Cargo.toml
deleted file mode 100644
index 08d49dd16..000000000
--- a/rust-libs/modules/gva/gql/Cargo.toml
+++ /dev/null
@@ -1,37 +0,0 @@
-[package]
-name = "duniter-gva-gql"
-version = "0.1.0"
-authors = ["librelois <elois@duniter.org>"]
-license = "AGPL-3.0"
-edition = "2018"
-
-[dependencies]
-anyhow = "1.0.33"
-arrayvec = "0.5.1"
-async-graphql = "2.2.0"
-async-trait = "0.1.41"
-dubp = { version = "0.51.0", features = ["duniter"] }
-duniter-conf = { path = "../../../duniter-conf" }
-duniter-dbs = { path = "../../../duniter-dbs" }
-duniter-bc-reader = { path = "../../../duniter-bc-reader" }
-duniter-gva-db = { path = "../db" }
-duniter-gva-dbs-reader = { path = "../dbs-reader" }
-duniter-global = { path = "../../../duniter-global" }
-duniter-mempools = { path = "../../../duniter-mempools" }
-duniter-module = { path = "../../../duniter-module" }
-fast-threadpool = "0.2.3"
-flume = "0.10.0"
-futures = "0.3.6"
-log = "0.4.11"
-resiter = "0.4.0"
-serde = { version = "1.0.105", features = ["derive"] }
-
-[dev-dependencies]
-duniter-dbs = { path = "../../../duniter-dbs", features = ["mem"] }
-duniter-gva-dbs-reader = { path = "../dbs-reader", features = ["mock"] }
-duniter-global = { path = "../../../duniter-global", features = ["mock"] }
-mockall = "0.9.1"
-pretty_assertions = "0.7"
-serde_json = "1.0.53"
-tokio = { version = "1.2", features = ["macros", "rt-multi-thread", "time"] }
-unwrap = "1.2.1"
diff --git a/rust-libs/modules/gva/gql/src/entities.rs b/rust-libs/modules/gva/gql/src/entities.rs
deleted file mode 100644
index c6ac1569f..000000000
--- a/rust-libs/modules/gva/gql/src/entities.rs
+++ /dev/null
@@ -1,112 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-pub mod block_gva;
-pub mod idty_gva;
-pub mod network;
-pub mod tx_gva;
-pub mod ud_gva;
-pub mod utxos_gva;
-
-use crate::*;
-
-#[derive(Default, async_graphql::SimpleObject)]
-pub(crate) struct AggregateSum {
-    pub(crate) aggregate: Sum,
-}
-
-#[derive(Default, async_graphql::SimpleObject)]
-pub(crate) struct AmountWithBase {
-    pub(crate) amount: i32,
-    pub(crate) base: i32,
-}
-
-#[derive(async_graphql::SimpleObject)]
-pub(crate) struct EdgeTx {
-    pub(crate) direction: TxDirection,
-}
-
-pub(crate) enum RawTxOrChanges {
-    FinalTx(String),
-    Changes(Vec<String>),
-}
-#[async_graphql::Object]
-impl RawTxOrChanges {
-    /// Intermediate transactions documents for compacting sources (`null` if not needed)
-    async fn changes(&self) -> Option<&Vec<String>> {
-        if let Self::Changes(changes) = self {
-            Some(changes)
-        } else {
-            None
-        }
-    }
-    /// Transaction document that carries out the requested transfer (`null` if the amount to be sent requires too many sources)
-    async fn tx(&self) -> Option<&str> {
-        if let Self::FinalTx(raw_tx) = self {
-            Some(raw_tx.as_str())
-        } else {
-            None
-        }
-    }
-}
-
-#[derive(Default, async_graphql::SimpleObject)]
-pub(crate) struct Sum {
-    pub(crate) sum: AmountWithBase,
-}
-
-#[derive(Clone, Copy, Eq, PartialEq, async_graphql::Enum)]
-pub(crate) enum TxDirection {
-    /// Received
-    Received,
-    /// Sent
-    Sent,
-}
-
-#[derive(async_graphql::SimpleObject)]
-pub(crate) struct TxsHistoryMempool {
-    /// Transactions sending
-    pub(crate) sending: Vec<TxGva>,
-    /// Transactions receiving
-    pub(crate) receiving: Vec<TxGva>,
-}
-
-#[derive(Clone, async_graphql::SimpleObject)]
-pub(crate) struct UtxoGva {
-    /// Source amount
-    pub(crate) amount: i64,
-    /// Source base
-    pub(crate) base: i64,
-    /// Hash of origin transaction
-    pub(crate) tx_hash: String,
-    /// Index of output in origin transaction
-    pub(crate) output_index: u32,
-}
-
-#[derive(Clone, async_graphql::SimpleObject)]
-pub(crate) struct UtxoTimedGva {
-    /// Source amount
-    pub(crate) amount: i64,
-    /// Source base
-    pub(crate) base: i64,
-    /// Hash of origin transaction
-    pub(crate) tx_hash: String,
-    /// Index of output in origin transaction
-    pub(crate) output_index: u32,
-    /// Written block
-    pub(crate) written_block: u32,
-    /// Written time
-    pub(crate) written_time: u64,
-}
diff --git a/rust-libs/modules/gva/gql/src/entities/block_gva.rs b/rust-libs/modules/gva/gql/src/entities/block_gva.rs
deleted file mode 100644
index c5be43c5d..000000000
--- a/rust-libs/modules/gva/gql/src/entities/block_gva.rs
+++ /dev/null
@@ -1,176 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use super::tx_gva::TxGva;
-use crate::*;
-use dubp::block::DubpBlockV10;
-use duniter_dbs::BlockMetaV2;
-
-#[derive(async_graphql::SimpleObject)]
-pub(crate) struct BlockMeta {
-    pub version: u64,
-    pub number: u32,
-    pub hash: String,
-    pub signature: String,
-    pub inner_hash: String,
-    pub previous_hash: String,
-    pub issuer: String,
-    pub time: u64,
-    pub pow_min: u32,
-    pub members_count: u64,
-    pub issuers_count: u32,
-    pub issuers_frame: u64,
-    pub median_time: u64,
-    pub nonce: u64,
-    pub monetary_mass: u64,
-    pub unit_base: u32,
-    pub dividend: Option<u32>,
-}
-
-impl From<BlockMetaV2> for BlockMeta {
-    fn from(block_db: BlockMetaV2) -> Self {
-        Self::from(&block_db)
-    }
-}
-impl From<&BlockMetaV2> for BlockMeta {
-    fn from(block_db: &BlockMetaV2) -> Self {
-        BlockMeta {
-            version: block_db.version,
-            number: block_db.number,
-            hash: block_db.hash.to_string(),
-            signature: block_db.signature.to_string(),
-            inner_hash: block_db.inner_hash.to_string(),
-            previous_hash: block_db.previous_hash.to_string(),
-            issuer: block_db.issuer.to_string(),
-            time: block_db.time,
-            pow_min: block_db.pow_min,
-            members_count: block_db.members_count,
-            issuers_count: block_db.issuers_count,
-            issuers_frame: block_db.issuers_frame,
-            median_time: block_db.median_time,
-            nonce: block_db.nonce,
-            monetary_mass: block_db.monetary_mass,
-            unit_base: block_db.unit_base,
-            dividend: block_db.dividend.map(|sa| sa.amount() as u32),
-        }
-    }
-}
-
-#[derive(async_graphql::SimpleObject)]
-pub(crate) struct Block {
-    // Meta
-    pub version: u64,
-    pub number: u32,
-    pub hash: String,
-    pub signature: String,
-    pub inner_hash: String,
-    pub previous_hash: Option<String>,
-    pub issuer: String,
-    pub time: u64,
-    pub pow_min: u32,
-    pub members_count: u64,
-    pub issuers_count: u32,
-    pub issuers_frame: u64,
-    pub median_time: u64,
-    pub nonce: u64,
-    pub monetary_mass: u64,
-    pub unit_base: u32,
-    pub dividend: Option<u32>,
-    // Payload
-    /// Identities
-    pub identities: Vec<String>,
-    /// joiners
-    pub joiners: Vec<String>,
-    /// Actives (=renewals)
-    pub actives: Vec<String>,
-    /// Leavers
-    pub leavers: Vec<String>,
-    /// Revokeds
-    pub revoked: Vec<String>,
-    /// Excludeds
-    pub excluded: Vec<String>,
-    /// Certifications
-    pub certifications: Vec<String>,
-    pub transactions: Vec<TxGva>,
-}
-
-impl From<&DubpBlockV10> for Block {
-    fn from(block: &DubpBlockV10) -> Self {
-        let block = block.to_string_object();
-        Block {
-            // Meta
-            version: block.version,
-            number: block.number as u32,
-            hash: block.hash.unwrap_or_default(),
-            signature: block.signature,
-            inner_hash: block.inner_hash.unwrap_or_default(),
-            previous_hash: block.previous_hash,
-            issuer: block.issuer,
-            time: block.time,
-            pow_min: block.pow_min as u32,
-            members_count: block.members_count,
-            issuers_count: block.issuers_count as u32,
-            issuers_frame: block.issuers_frame,
-            median_time: block.median_time,
-            nonce: block.nonce,
-            monetary_mass: block.monetary_mass,
-            unit_base: block.unit_base as u32,
-            dividend: block.dividend.map(|amount| amount as u32),
-            // Payload
-            identities: block.identities,
-            joiners: block.joiners,
-            actives: block.actives,
-            leavers: block.leavers,
-            revoked: block.revoked,
-            excluded: block.excluded,
-            certifications: block.certifications,
-            transactions: block.transactions.into_iter().map(Into::into).collect(),
-        }
-    }
-}
-
-impl From<&BlockMetaV2> for Block {
-    fn from(block: &BlockMetaV2) -> Self {
-        Block {
-            // Meta
-            version: block.version,
-            number: block.number,
-            hash: block.hash.to_string(),
-            signature: block.signature.to_string(),
-            inner_hash: block.inner_hash.to_string(),
-            previous_hash: Some(block.previous_hash.to_string()),
-            issuer: block.issuer.to_string(),
-            time: block.time,
-            pow_min: block.pow_min,
-            members_count: block.members_count,
-            issuers_count: block.issuers_count,
-            issuers_frame: block.issuers_frame,
-            median_time: block.median_time,
-            nonce: block.nonce,
-            monetary_mass: block.monetary_mass,
-            unit_base: block.unit_base,
-            dividend: block.dividend.map(|sa| sa.amount() as u32),
-            // Payload
-            identities: vec![],
-            joiners: vec![],
-            actives: vec![],
-            leavers: vec![],
-            revoked: vec![],
-            excluded: vec![],
-            certifications: vec![],
-            transactions: vec![],
-        }
-    }
-}
diff --git a/rust-libs/modules/gva/gql/src/entities/idty_gva.rs b/rust-libs/modules/gva/gql/src/entities/idty_gva.rs
deleted file mode 100644
index ee77b0e4d..000000000
--- a/rust-libs/modules/gva/gql/src/entities/idty_gva.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-#[derive(async_graphql::SimpleObject)]
-pub(crate) struct Identity {
-    pub is_member: bool,
-    pub username: String,
-}
diff --git a/rust-libs/modules/gva/gql/src/entities/network.rs b/rust-libs/modules/gva/gql/src/entities/network.rs
deleted file mode 100644
index 7f99918c0..000000000
--- a/rust-libs/modules/gva/gql/src/entities/network.rs
+++ /dev/null
@@ -1,74 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-#[derive(Default, async_graphql::SimpleObject)]
-#[graphql(name = "Peer")]
-pub struct PeerCardGva {
-    pub version: u32,
-    pub currency: String,
-    pub pubkey: String,
-    pub blockstamp: String,
-    pub endpoints: Vec<String>,
-    pub status: String,
-    pub signature: String,
-}
-impl From<duniter_dbs::PeerCardDbV1> for PeerCardGva {
-    fn from(peer: duniter_dbs::PeerCardDbV1) -> Self {
-        Self {
-            version: peer.version,
-            currency: peer.currency,
-            pubkey: peer.pubkey,
-            blockstamp: peer.blockstamp,
-            endpoints: peer.endpoints,
-            status: peer.status,
-            signature: peer.signature,
-        }
-    }
-}
-
-#[derive(Default, async_graphql::SimpleObject)]
-#[graphql(name = "Head")]
-pub struct HeadGva {
-    pub api: String,
-    pub pubkey: String,
-    pub blockstamp: String,
-    pub software: String,
-    pub software_version: String,
-    pub pow_prefix: u32,
-    pub free_member_room: u32,
-    pub free_mirror_room: u32,
-    pub signature: String,
-}
-impl From<duniter_dbs::DunpHeadDbV1> for HeadGva {
-    fn from(head: duniter_dbs::DunpHeadDbV1) -> Self {
-        Self {
-            api: head.api,
-            pubkey: head.pubkey.to_string(),
-            blockstamp: head.blockstamp.to_string(),
-            software: head.software,
-            software_version: head.software_version,
-            pow_prefix: head.pow_prefix,
-            free_member_room: head.free_member_room,
-            free_mirror_room: head.free_member_room,
-            signature: head.signature.to_string(),
-        }
-    }
-}
-
-#[derive(async_graphql::SimpleObject)]
-pub(crate) struct PeerWithHeads {
-    pub peer: PeerCardGva,
-    pub heads: Vec<HeadGva>,
-}
diff --git a/rust-libs/modules/gva/gql/src/entities/tx_gva.rs b/rust-libs/modules/gva/gql/src/entities/tx_gva.rs
deleted file mode 100644
index 6fd376433..000000000
--- a/rust-libs/modules/gva/gql/src/entities/tx_gva.rs
+++ /dev/null
@@ -1,84 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-use dubp::documents::transaction::TransactionDocumentV10Stringified;
-use duniter_gva_db::GvaTxDbV1;
-
-#[derive(async_graphql::SimpleObject)]
-pub(crate) struct TxGva {
-    /// Version.
-    pub version: i32,
-    /// Currency.
-    pub currency: String,
-    /// Blockstamp
-    pub blockstamp: String,
-    /// Locktime
-    pub locktime: u64,
-    /// Document issuers.
-    pub issuers: Vec<String>,
-    /// Transaction inputs.
-    pub inputs: Vec<String>,
-    /// Inputs unlocks.
-    pub unlocks: Vec<String>,
-    /// Transaction outputs.
-    pub outputs: Vec<String>,
-    /// Transaction comment
-    pub comment: String,
-    /// Document signatures
-    pub signatures: Vec<String>,
-    /// Transaction hash
-    pub hash: String,
-    /// Written block
-    pub written_block: Option<String>,
-    /// Written Time
-    pub written_time: Option<i64>,
-}
-
-impl From<GvaTxDbV1> for TxGva {
-    fn from(db_tx: GvaTxDbV1) -> Self {
-        let mut self_: TxGva = (&db_tx.tx).into();
-        self_.written_block = Some(db_tx.written_block.to_string());
-        self_.written_time = Some(db_tx.written_time);
-        self_
-    }
-}
-
-impl From<&TransactionDocumentV10> for TxGva {
-    fn from(tx: &TransactionDocumentV10) -> Self {
-        let tx_stringified = tx.to_string_object();
-        Self::from(tx_stringified)
-    }
-}
-
-impl From<TransactionDocumentV10Stringified> for TxGva {
-    fn from(tx_stringified: TransactionDocumentV10Stringified) -> Self {
-        Self {
-            version: 10,
-            currency: tx_stringified.currency,
-            blockstamp: tx_stringified.blockstamp,
-            locktime: tx_stringified.locktime,
-            issuers: tx_stringified.issuers,
-            inputs: tx_stringified.inputs,
-            unlocks: tx_stringified.unlocks,
-            outputs: tx_stringified.outputs,
-            comment: tx_stringified.comment,
-            signatures: tx_stringified.signatures,
-            hash: tx_stringified.hash.unwrap_or_default(),
-            written_block: None,
-            written_time: None,
-        }
-    }
-}
diff --git a/rust-libs/modules/gva/gql/src/entities/ud_gva.rs b/rust-libs/modules/gva/gql/src/entities/ud_gva.rs
deleted file mode 100644
index e268f5b67..000000000
--- a/rust-libs/modules/gva/gql/src/entities/ud_gva.rs
+++ /dev/null
@@ -1,48 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Clone, async_graphql::SimpleObject)]
-pub(crate) struct CurrentUdGva {
-    /// Ud amount
-    pub(crate) amount: i64,
-    /// Ud base
-    pub(crate) base: i64,
-}
-
-#[derive(Clone, async_graphql::SimpleObject)]
-pub(crate) struct RevalUdGva {
-    /// Ud amount
-    pub(crate) amount: i64,
-    /// Ud base
-    pub(crate) base: i64,
-    /// Number of the block that revaluate ud amount
-    pub(crate) block_number: u32,
-}
-
-#[derive(Clone, async_graphql::SimpleObject)]
-pub(crate) struct UdGva {
-    /// Ud amount
-    pub(crate) amount: i64,
-    /// Ud base
-    pub(crate) base: i64,
-    /// Issuer of this universal dividend
-    pub(crate) issuer: PubKeyGva,
-    /// Number of the block that created this UD
-    pub(crate) block_number: u32,
-    /// Blockchain time of the block that created this UD
-    pub(crate) blockchain_time: u64,
-}
diff --git a/rust-libs/modules/gva/gql/src/entities/utxos_gva.rs b/rust-libs/modules/gva/gql/src/entities/utxos_gva.rs
deleted file mode 100644
index 9bd3e7990..000000000
--- a/rust-libs/modules/gva/gql/src/entities/utxos_gva.rs
+++ /dev/null
@@ -1,42 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-pub(crate) struct UtxosGva(pub arrayvec::ArrayVec<[UtxoGva; 40]>);
-impl async_graphql::Type for UtxosGva {
-    fn type_name() -> Cow<'static, str> {
-        Cow::Owned(format!("[{}]", UtxoGva::qualified_type_name()))
-    }
-
-    fn qualified_type_name() -> String {
-        format!("[{}]!", UtxoGva::qualified_type_name())
-    }
-
-    fn create_type_info(registry: &mut async_graphql::registry::Registry) -> String {
-        UtxoGva::create_type_info(registry);
-        Self::qualified_type_name()
-    }
-}
-#[async_trait::async_trait]
-impl async_graphql::OutputType for UtxosGva {
-    async fn resolve(
-        &self,
-        ctx: &async_graphql::ContextSelectionSet<'_>,
-        field: &async_graphql::Positioned<async_graphql::parser::types::Field>,
-    ) -> async_graphql::ServerResult<async_graphql::Value> {
-        async_graphql::resolver_utils::resolve_list(ctx, field, &self.0, Some(self.0.len())).await
-    }
-}
diff --git a/rust-libs/modules/gva/gql/src/inputs.rs b/rust-libs/modules/gva/gql/src/inputs.rs
deleted file mode 100644
index b90469094..000000000
--- a/rust-libs/modules/gva/gql/src/inputs.rs
+++ /dev/null
@@ -1,57 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(async_graphql::InputObject, Clone, Copy, Default)]
-pub(crate) struct TimeInterval {
-    pub(crate) from: Option<u64>,
-    pub(crate) to: Option<u64>,
-}
-
-#[derive(async_graphql::InputObject)]
-pub(crate) struct TxIssuer {
-    /// Account script (default is a script needed all provided signers)
-    pub(crate) script: Option<String>,
-    /// Signers
-    #[graphql(validator(ListMinLength(length = "1")))]
-    pub(crate) signers: Vec<String>,
-    /// XHX codes needed to unlock funds
-    #[graphql(validator(ListMinLength(length = "1")))]
-    pub(crate) codes: Option<Vec<String>>,
-    /// Amount
-    #[graphql(validator(IntGreaterThan(value = "0")))]
-    pub(crate) amount: i32,
-}
-
-#[derive(async_graphql::InputObject)]
-pub(crate) struct TxRecipient {
-    /// Amount
-    #[graphql(validator(IntGreaterThan(value = "0")))]
-    pub(crate) amount: i32,
-    /// Account script
-    pub(crate) script: String,
-}
-
-#[derive(Clone, Copy, async_graphql::Enum, Eq, PartialEq)]
-pub(crate) enum UdsFilter {
-    All,
-    Unspent,
-}
-impl Default for UdsFilter {
-    fn default() -> Self {
-        UdsFilter::All
-    }
-}
diff --git a/rust-libs/modules/gva/gql/src/inputs_validators.rs b/rust-libs/modules/gva/gql/src/inputs_validators.rs
deleted file mode 100644
index b2578c22b..000000000
--- a/rust-libs/modules/gva/gql/src/inputs_validators.rs
+++ /dev/null
@@ -1,36 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-pub(crate) struct TxCommentValidator;
-
-impl async_graphql::validators::InputValueValidator for TxCommentValidator {
-    fn is_valid(&self, value: &async_graphql::Value) -> Result<(), String> {
-        if let async_graphql::Value::String(comment) = value {
-            if !TransactionDocumentV10::verify_comment(&comment) {
-                // Validation failed
-                Err("invalid comment".to_owned())
-            } else {
-                // Validation succeeded
-                Ok(())
-            }
-        } else {
-            // If the type does not match we can return None and built-in validations
-            // will pick up on the error
-            Ok(())
-        }
-    }
-}
diff --git a/rust-libs/modules/gva/gql/src/lib.rs b/rust-libs/modules/gva/gql/src/lib.rs
deleted file mode 100644
index 019f8ce9a..000000000
--- a/rust-libs/modules/gva/gql/src/lib.rs
+++ /dev/null
@@ -1,157 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-#![deny(
-    clippy::unwrap_used,
-    missing_copy_implementations,
-    trivial_casts,
-    trivial_numeric_casts,
-    unstable_features,
-    unused_import_braces
-)]
-
-mod entities;
-mod inputs;
-mod inputs_validators;
-mod mutations;
-mod pagination;
-mod queries;
-mod scalars;
-mod schema;
-mod subscriptions;
-
-pub use schema::{build_schema_with_data, get_schema_definition, GvaSchema, GvaSchemaData};
-
-use crate::entities::{
-    block_gva::{Block, BlockMeta},
-    idty_gva::Identity,
-    network::{HeadGva, PeerCardGva, PeerWithHeads},
-    tx_gva::TxGva,
-    ud_gva::{CurrentUdGva, RevalUdGva, UdGva},
-    utxos_gva::UtxosGva,
-    AggregateSum, AmountWithBase, EdgeTx, RawTxOrChanges, Sum, TxDirection, TxsHistoryMempool,
-    UtxoGva, UtxoTimedGva,
-};
-use crate::inputs::{TxIssuer, TxRecipient, UdsFilter};
-use crate::inputs_validators::TxCommentValidator;
-use crate::pagination::Pagination;
-use crate::scalars::{PkOrScriptGva, PubKeyGva};
-#[cfg(test)]
-use crate::tests::AsyncAccessor;
-#[cfg(test)]
-use crate::tests::DbsReaderImpl;
-use async_graphql::connection::{Connection, Edge, EmptyFields};
-use async_graphql::validators::{IntGreaterThan, IntRange, ListMaxLength, ListMinLength};
-use dubp::common::crypto::keys::{ed25519::PublicKey, PublicKey as _};
-use dubp::common::prelude::*;
-use dubp::crypto::hashs::Hash;
-use dubp::documents::prelude::*;
-use dubp::documents::transaction::{TransactionDocumentTrait, TransactionDocumentV10};
-use dubp::documents_parser::prelude::*;
-use dubp::wallet::prelude::*;
-use duniter_dbs::databases::txs_mp_v2::TxsMpV2DbReadable;
-use duniter_dbs::prelude::*;
-use duniter_dbs::{kv_typed::prelude::*, FileBackend};
-#[cfg(not(test))]
-use duniter_global::AsyncAccessor;
-use duniter_gva_dbs_reader::pagination::PageInfo;
-use duniter_gva_dbs_reader::DbsReader;
-#[cfg(not(test))]
-use duniter_gva_dbs_reader::DbsReaderImpl;
-use duniter_mempools::TxsMempool;
-use futures::{Stream, StreamExt};
-use resiter::map::Map;
-use std::{borrow::Cow, convert::TryFrom, num::NonZeroUsize, ops::Deref};
-
-#[derive(Clone, Copy, Debug, Default)]
-pub struct QueryContext {
-    pub is_whitelisted: bool,
-}
-
-#[derive(Debug, Default)]
-pub struct ServerMetaData {
-    pub currency: String,
-    pub self_pubkey: PublicKey,
-    pub software_version: &'static str,
-}
-
-#[cfg(test)]
-mod tests {
-    pub use duniter_global::{CurrentMeta, MockAsyncAccessor};
-    pub use duniter_gva_dbs_reader::MockDbsReader;
-
-    use super::*;
-    use fast_threadpool::ThreadPoolConfig;
-
-    pub type AsyncAccessor = duniter_dbs::kv_typed::prelude::Arc<MockAsyncAccessor>;
-    pub type DbsReaderImpl = duniter_dbs::kv_typed::prelude::Arc<MockDbsReader>;
-
-    pub(crate) fn create_schema(
-        mock_cm: MockAsyncAccessor,
-        dbs_ops: MockDbsReader,
-    ) -> KvResult<GvaSchema> {
-        let dbs = SharedDbs::mem()?;
-        let threadpool = fast_threadpool::ThreadPool::start(ThreadPoolConfig::default(), dbs);
-        Ok(schema::build_schema_with_data(
-            schema::GvaSchemaData {
-                cm_accessor: Arc::new(mock_cm),
-                dbs_pool: threadpool.into_async_handler(),
-                dbs_reader: Arc::new(dbs_ops),
-                server_meta_data: ServerMetaData {
-                    currency: "test_currency".to_owned(),
-                    self_pubkey: PublicKey::default(),
-                    software_version: "test",
-                },
-                txs_mempool: TxsMempool::new(10),
-            },
-            true,
-        ))
-    }
-
-    pub(crate) async fn exec_graphql_request(
-        schema: &GvaSchema,
-        request: &str,
-    ) -> anyhow::Result<serde_json::Value> {
-        Ok(serde_json::to_value(
-            schema
-                .execute(async_graphql::Request::new(request).data(QueryContext::default()))
-                .await,
-        )?)
-    }
-
-    /*pub(crate) fn create_schema_sub(dbs: SharedDbs<FileBackend>) -> KvResult<GvaSchema> {
-        let threadpool = fast_threadpool::ThreadPool::start(ThreadPoolConfig::default(), dbs);
-        Ok(schema::build_schema_with_data(
-            schema::GvaSchemaData {
-                dbs_pool: threadpool.into_async_handler(),
-                dbs_reader: Arc::new(MockDbsReader::new()),
-                server_meta_data: ServerMetaData {
-                    currency: "test_currency".to_owned(),
-                    self_pubkey: PublicKey::default(),
-                    software_version: "test",
-                },
-                txs_mempool: TxsMempool::new(10),
-            },
-            true,
-        ))
-    }
-
-    pub(crate) fn exec_graphql_subscription(
-        schema: &GvaSchema,
-        request: String,
-    ) -> impl Stream<Item = serde_json::Result<serde_json::Value>> + Send {
-        schema.execute_stream(request).map(serde_json::to_value)
-    }*/
-}
diff --git a/rust-libs/modules/gva/gql/src/mutations.rs b/rust-libs/modules/gva/gql/src/mutations.rs
deleted file mode 100644
index 3d258e9ae..000000000
--- a/rust-libs/modules/gva/gql/src/mutations.rs
+++ /dev/null
@@ -1,86 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Clone, Copy, Default)]
-pub struct MutationRoot;
-
-#[async_graphql::Object]
-impl MutationRoot {
-    /// Process a transaction
-    /// Return the transaction if it successfully inserted
-    async fn tx(
-        &self,
-        ctx: &async_graphql::Context<'_>,
-        raw_tx: String,
-    ) -> async_graphql::Result<TxGva> {
-        let tx = TransactionDocumentV10::parse_from_raw_text(&raw_tx)?;
-
-        let data = ctx.data::<GvaSchemaData>()?;
-        let expected_currency = data.server_meta_data.currency.clone();
-
-        tx.verify(Some(&expected_currency))?;
-
-        let server_pubkey = data.server_meta_data.self_pubkey;
-        let txs_mempool = data.txs_mempool;
-
-        let tx = data
-            .dbs_pool
-            .execute(move |dbs| {
-                txs_mempool
-                    .add_pending_tx(&dbs.bc_db_ro, server_pubkey, &dbs.txs_mp_db, &tx)
-                    .map(|()| tx)
-            })
-            .await??;
-
-        Ok(TxGva::from(&tx))
-    }
-
-    /// Process several transactions
-    /// Return an array of successfully inserted transactions
-    async fn txs(
-        &self,
-        ctx: &async_graphql::Context<'_>,
-        raw_txs: Vec<String>,
-    ) -> async_graphql::Result<Vec<TxGva>> {
-        let txs = raw_txs
-            .iter()
-            .map(|raw_tx| TransactionDocumentV10::parse_from_raw_text(&raw_tx))
-            .collect::<Result<Vec<TransactionDocumentV10>, _>>()?;
-
-        let data = ctx.data::<GvaSchemaData>()?;
-        let expected_currency = data.server_meta_data.currency.clone();
-
-        let server_pubkey = data.server_meta_data.self_pubkey;
-        let txs_mempool = data.txs_mempool;
-
-        let mut processed_txs = Vec::with_capacity(txs.len());
-        for tx in txs {
-            tx.verify(Some(&expected_currency))?;
-            let tx = data
-                .dbs_pool
-                .execute(move |dbs| {
-                    txs_mempool
-                        .add_pending_tx(&dbs.bc_db_ro, server_pubkey, &dbs.txs_mp_db, &tx)
-                        .map(|()| tx)
-                })
-                .await??;
-            processed_txs.push(TxGva::from(&tx));
-        }
-
-        Ok(processed_txs)
-    }
-}
diff --git a/rust-libs/modules/gva/gql/src/pagination.rs b/rust-libs/modules/gva/gql/src/pagination.rs
deleted file mode 100644
index 98db4e9ab..000000000
--- a/rust-libs/modules/gva/gql/src/pagination.rs
+++ /dev/null
@@ -1,73 +0,0 @@
-use std::str::FromStr;
-
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-const MAX_PAGE_SIZE: u32 = 1_000;
-
-#[derive(Clone, Copy, async_graphql::Enum, Eq, PartialEq)]
-pub(crate) enum Order {
-    /// Ascending order
-    Asc,
-    /// Decreasing order
-    Desc,
-}
-impl Default for Order {
-    fn default() -> Self {
-        Order::Asc
-    }
-}
-
-#[derive(async_graphql::InputObject)]
-pub(crate) struct Pagination {
-    /// Identifier of the 1st desired element (of the last one in descending order)
-    cursor: Option<String>,
-    ord: Order,
-    page_size: u32,
-}
-
-impl Default for Pagination {
-    fn default() -> Self {
-        Pagination {
-            cursor: None,
-            ord: Order::default(),
-            page_size: 10,
-        }
-    }
-}
-
-impl Pagination {
-    pub(crate) fn convert_to_page_info<
-        E: 'static + std::error::Error + Send + Sync,
-        T: FromStr<Err = E>,
-    >(
-        self,
-        is_whitelisted: bool,
-    ) -> anyhow::Result<duniter_gva_dbs_reader::PageInfo<T>> {
-        let page_size = if is_whitelisted || (self.page_size > 0 && self.page_size < MAX_PAGE_SIZE)
-        {
-            NonZeroUsize::new(self.page_size as usize)
-        } else {
-            return Err(anyhow::Error::msg("pageSize must be between 1 and 1000."));
-        };
-        Ok(duniter_gva_dbs_reader::PageInfo::new(
-            self.cursor.map(|c| T::from_str(&c)).transpose()?,
-            self.ord == Order::Asc,
-            page_size,
-        ))
-    }
-}
diff --git a/rust-libs/modules/gva/gql/src/queries.rs b/rust-libs/modules/gva/gql/src/queries.rs
deleted file mode 100644
index 7357f4937..000000000
--- a/rust-libs/modules/gva/gql/src/queries.rs
+++ /dev/null
@@ -1,86 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-pub mod account_balance;
-pub mod block;
-pub mod current_block;
-pub mod current_frame;
-pub mod first_utxos_of_scripts;
-pub mod gen_tx;
-pub mod idty;
-pub mod network;
-pub mod txs_history;
-pub mod uds;
-pub mod utxos_of_script;
-
-use crate::*;
-
-#[derive(async_graphql::MergedObject, Default)]
-pub struct QueryRoot(
-    queries::NodeQuery,
-    queries::account_balance::AccountBalanceQuery,
-    queries::block::BlockQuery,
-    queries::current_block::CurrentBlockQuery,
-    queries::current_frame::CurrentFrameQuery,
-    queries::first_utxos_of_scripts::FirstUtxosQuery,
-    queries::gen_tx::GenTxsQuery,
-    queries::idty::IdtyQuery,
-    queries::network::NetworkQuery,
-    queries::txs_history::TxsHistoryBlockchainQuery,
-    queries::txs_history::TxsHistoryMempoolQuery,
-    queries::uds::UdsQuery,
-    queries::utxos_of_script::UtxosQuery,
-);
-
-#[derive(Default, async_graphql::SimpleObject)]
-struct NodeQuery {
-    node: Node,
-}
-
-#[derive(Default)]
-struct Node;
-
-#[async_graphql::Object]
-impl Node {
-    /// Peer card
-    async fn peer(
-        &self,
-        ctx: &async_graphql::Context<'_>,
-    ) -> async_graphql::Result<Option<PeerCardGva>> {
-        let data = ctx.data::<GvaSchemaData>()?;
-
-        if let Some(self_peer_old) = data
-            .cm_accessor()
-            .get_self_peer_old(|self_peer_old| self_peer_old.clone())
-            .await
-        {
-            Ok(Some(PeerCardGva::from(self_peer_old)))
-        } else {
-            Ok(None)
-        }
-    }
-    /// Software
-    async fn software(&self) -> &'static str {
-        duniter_module::SOFTWARE_NAME
-    }
-    /// Software version
-    async fn version(
-        &self,
-        ctx: &async_graphql::Context<'_>,
-    ) -> async_graphql::Result<&'static str> {
-        let data = ctx.data::<GvaSchemaData>()?;
-        Ok(data.server_meta_data.software_version)
-    }
-}
diff --git a/rust-libs/modules/gva/gql/src/queries/account_balance.rs b/rust-libs/modules/gva/gql/src/queries/account_balance.rs
deleted file mode 100644
index 9f25cdeca..000000000
--- a/rust-libs/modules/gva/gql/src/queries/account_balance.rs
+++ /dev/null
@@ -1,143 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Default)]
-pub(crate) struct AccountBalanceQuery;
-#[async_graphql::Object]
-impl AccountBalanceQuery {
-    /// Get the balance of an account identified by a public key or a script.
-    ///
-    /// If the balance is null, the account has never been used. If the balance is zero, the account has already transited money in the past.
-    async fn balance(
-        &self,
-        ctx: &async_graphql::Context<'_>,
-        #[graphql(desc = "Account script or public key")] script: PkOrScriptGva,
-    ) -> async_graphql::Result<Option<AmountWithBase>> {
-        let data = ctx.data::<GvaSchemaData>()?;
-        let dbs_reader = data.dbs_reader();
-
-        Ok(data
-            .dbs_pool
-            .execute(move |_| dbs_reader.get_account_balance(&script.0))
-            .await??
-            .map(|balance| AmountWithBase {
-                amount: balance.0.amount() as i32,
-                base: balance.0.base() as i32,
-            }))
-    }
-    /// Get the balance of several accounts in a single request
-    ///
-    /// Each account can be identified by a public key or a script. It is possible to mix the two in the same request.
-    /// The balances are returned in the order of the accounts provided as input. Each account has a balance,
-    /// which is null if the account does not exist.
-    async fn balances(
-        &self,
-        ctx: &async_graphql::Context<'_>,
-        #[graphql(desc = "Accounts scripts or publics keys")] scripts: Vec<PkOrScriptGva>,
-    ) -> async_graphql::Result<Vec<Option<AmountWithBase>>> {
-        let data = ctx.data::<GvaSchemaData>()?;
-        let dbs_reader = data.dbs_reader();
-
-        Ok(data
-            .dbs_pool
-            .execute(move |_| {
-                scripts
-                    .iter()
-                    .map(|account_script| {
-                        dbs_reader
-                            .get_account_balance(&account_script.0)
-                            .map(|balance_opt| {
-                                balance_opt.map(|balance| AmountWithBase {
-                                    amount: balance.0.amount() as i32,
-                                    base: balance.0.base() as i32,
-                                })
-                            })
-                    })
-                    .collect::<Result<Vec<_>, _>>()
-            })
-            .await??)
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use crate::tests::*;
-    use duniter_dbs::SourceAmountValV2;
-
-    #[tokio::test]
-    async fn query_balance() -> anyhow::Result<()> {
-        let mut dbs_reader = MockDbsReader::new();
-        dbs_reader
-            .expect_get_account_balance()
-            .withf(|s| {
-                s == &WalletScriptV10::single_sig(
-                    PublicKey::from_base58("DnjL6hYA1k7FavGHbbir79PKQbmzw63d6bsamBBdUULP")
-                        .expect("wrong pubkey"),
-                )
-            })
-            .times(1)
-            .returning(|_| Ok(Some(SourceAmountValV2(SourceAmount::with_base0(38)))));
-        let schema = create_schema(MockAsyncAccessor::new(), dbs_reader)?;
-        assert_eq!(
-            exec_graphql_request(
-                &schema,
-                r#"{ balance(script: "DnjL6hYA1k7FavGHbbir79PKQbmzw63d6bsamBBdUULP") {amount} }"#
-            )
-            .await?,
-            serde_json::json!({
-                "data": {
-                    "balance": {
-                      "amount": 38
-                    }
-                }
-            })
-        );
-        Ok(())
-    }
-
-    #[tokio::test]
-    async fn query_balances() -> anyhow::Result<()> {
-        let mut dbs_reader = MockDbsReader::new();
-        dbs_reader
-            .expect_get_account_balance()
-            .withf(|s| {
-                s == &WalletScriptV10::single_sig(
-                    PublicKey::from_base58("DnjL6hYA1k7FavGHbbir79PKQbmzw63d6bsamBBdUULP")
-                        .expect("wrong pubkey"),
-                )
-            })
-            .times(1)
-            .returning(|_| Ok(Some(SourceAmountValV2(SourceAmount::with_base0(38)))));
-        let schema = create_schema(MockAsyncAccessor::new(), dbs_reader)?;
-        assert_eq!(
-            exec_graphql_request(
-                &schema,
-                r#"{ balances(scripts: ["DnjL6hYA1k7FavGHbbir79PKQbmzw63d6bsamBBdUULP"]) {amount} }"#
-            )
-            .await?,
-            serde_json::json!({
-                "data": {
-                    "balances": [{
-                      "amount": 38
-                    }]
-                }
-            })
-        );
-        Ok(())
-    }
-}
diff --git a/rust-libs/modules/gva/gql/src/queries/block.rs b/rust-libs/modules/gva/gql/src/queries/block.rs
deleted file mode 100644
index 1d09cb664..000000000
--- a/rust-libs/modules/gva/gql/src/queries/block.rs
+++ /dev/null
@@ -1,142 +0,0 @@
-//  Copyright (C) 2021 Pascal Engélibert
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-use duniter_gva_dbs_reader::PagedData;
-
-#[derive(Default)]
-pub(crate) struct BlockQuery;
-#[async_graphql::Object]
-impl BlockQuery {
-    /// Get block by number
-    async fn block_by_number(
-        &self,
-        ctx: &async_graphql::Context<'_>,
-        #[graphql(desc = "block number")] number: u32,
-    ) -> async_graphql::Result<Option<BlockMeta>> {
-        let data = ctx.data::<GvaSchemaData>()?;
-        let dbs_reader = data.dbs_reader();
-
-        let block = data
-            .dbs_pool
-            .execute(move |dbs| dbs_reader.block(&dbs.bc_db_ro, U32BE(number)))
-            .await??;
-
-        Ok(block.map(|block| BlockMeta::from(&block)))
-    }
-
-    /// Get blocks
-    async fn blocks(
-        &self,
-        ctx: &async_graphql::Context<'_>,
-        #[graphql(desc = "pagination", default)] pagination: Pagination,
-    ) -> async_graphql::Result<Connection<String, BlockMeta, EmptyFields, EmptyFields>> {
-        let QueryContext { is_whitelisted } = ctx.data::<QueryContext>()?;
-        let page_info = Pagination::convert_to_page_info(pagination, *is_whitelisted)?;
-
-        let data = ctx.data::<GvaSchemaData>()?;
-        let dbs_reader = data.dbs_reader();
-
-        let PagedData {
-            data: blocks,
-            has_next_page,
-            has_previous_page,
-        } = data
-            .dbs_pool
-            .execute(move |dbs| dbs_reader.blocks(&dbs.bc_db_ro, page_info))
-            .await??;
-
-        let mut conn = Connection::new(has_previous_page, has_next_page);
-
-        conn.append(blocks.into_iter().map(|(block_cursor, block)| {
-            Edge::new(block_cursor.to_string(), BlockMeta::from(block))
-        }));
-
-        Ok(conn)
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::BlockNumber;
-    use crate::tests::*;
-    use duniter_dbs::BlockMetaV2;
-    use duniter_gva_dbs_reader::{block::BlockCursor, PagedData};
-
-    #[tokio::test]
-    async fn test_block_by_number() -> anyhow::Result<()> {
-        let mut dbs_reader = MockDbsReader::new();
-        dbs_reader
-            .expect_block()
-            .withf(|_, s| s.0 == 0)
-            .times(1)
-            .returning(|_, _| Ok(Some(BlockMetaV2::default())));
-        let schema = create_schema(MockAsyncAccessor::new(), dbs_reader)?;
-        assert_eq!(
-            exec_graphql_request(&schema, r#"{ blockByNumber(number: 0) {number} }"#).await?,
-            serde_json::json!({
-                "data": {
-                    "blockByNumber": {
-                        "number": BlockMetaV2::default().number,
-                    }
-                }
-            })
-        );
-        Ok(())
-    }
-
-    #[tokio::test]
-    async fn test_blocks() -> anyhow::Result<()> {
-        let mut dbs_reader = MockDbsReader::new();
-        dbs_reader.expect_blocks().times(1).returning(|_, _| {
-            Ok(PagedData {
-                data: vec![(
-                    BlockCursor {
-                        number: BlockNumber(0),
-                    },
-                    BlockMetaV2::default(),
-                )],
-                has_next_page: false,
-                has_previous_page: false,
-            })
-        });
-        let schema = create_schema(MockAsyncAccessor::new(), dbs_reader)?;
-        assert_eq!(
-            exec_graphql_request(
-                &schema,
-                r#"{ blocks{pageInfo{startCursor,endCursor},edges{node{number}}} }"#
-            )
-            .await?,
-            serde_json::json!({
-                "data": {
-                    "blocks": {
-                        "edges": [
-                            {
-                                "node": {
-                                    "number": BlockMetaV2::default().number,
-                                }
-                            }
-                        ],
-                        "pageInfo": {
-                            "endCursor": BlockMetaV2::default().number.to_string(),
-                            "startCursor": BlockMetaV2::default().number.to_string(),
-                        }
-                    }
-                }
-            })
-        );
-        Ok(())
-    }
-}
diff --git a/rust-libs/modules/gva/gql/src/queries/current_block.rs b/rust-libs/modules/gva/gql/src/queries/current_block.rs
deleted file mode 100644
index 100706dbd..000000000
--- a/rust-libs/modules/gva/gql/src/queries/current_block.rs
+++ /dev/null
@@ -1,65 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Default)]
-pub(crate) struct CurrentBlockQuery;
-#[async_graphql::Object]
-impl CurrentBlockQuery {
-    /// Get current block
-    async fn current_block(
-        &self,
-        ctx: &async_graphql::Context<'_>,
-    ) -> async_graphql::Result<BlockMeta> {
-        let data = ctx.data::<GvaSchemaData>()?;
-
-        if let Some(current_block_meta) = data
-            .cm_accessor()
-            .get_current_meta(|cm| cm.current_block_meta)
-            .await
-        {
-            Ok(current_block_meta.into())
-        } else {
-            Err(async_graphql::Error::new("no blockchain"))
-        }
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use crate::tests::*;
-
-    #[tokio::test]
-    async fn query_current_block() -> anyhow::Result<()> {
-        let mut mock_cm = MockAsyncAccessor::new();
-        mock_cm
-            .expect_get_current_meta::<duniter_dbs::BlockMetaV2>()
-            .times(1)
-            .returning(|f| Some(f(&CurrentMeta::default())));
-        let schema = create_schema(mock_cm, MockDbsReader::new())?;
-        assert_eq!(
-            exec_graphql_request(&schema, r#"{ currentBlock {nonce} }"#).await?,
-            serde_json::json!({
-                "data": {
-                    "currentBlock": {
-                      "nonce": 0
-                    }
-                }
-            })
-        );
-        Ok(())
-    }
-}
diff --git a/rust-libs/modules/gva/gql/src/queries/current_frame.rs b/rust-libs/modules/gva/gql/src/queries/current_frame.rs
deleted file mode 100644
index a5ba2584a..000000000
--- a/rust-libs/modules/gva/gql/src/queries/current_frame.rs
+++ /dev/null
@@ -1,94 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Default)]
-pub(crate) struct CurrentFrameQuery;
-#[async_graphql::Object]
-impl CurrentFrameQuery {
-    /// Get blocks in current frame
-    async fn current_frame(
-        &self,
-        ctx: &async_graphql::Context<'_>,
-    ) -> async_graphql::Result<Vec<BlockMeta>> {
-        let data = ctx.data::<GvaSchemaData>()?;
-        let dbs_reader = data.dbs_reader();
-
-        if let Some(current_block_meta) = data
-            .cm_accessor()
-            .get_current_meta(|cm| cm.current_block_meta)
-            .await
-        {
-            Ok(data
-                .dbs_pool
-                .execute(move |dbs| {
-                    dbs_reader.get_current_frame(&dbs.bc_db_ro, &current_block_meta)
-                })
-                .await??
-                .into_iter()
-                .map(Into::into)
-                .collect())
-        } else {
-            Ok(vec![])
-        }
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use crate::tests::*;
-    use duniter_dbs::databases::bc_v2::BcV2DbRo;
-    use duniter_dbs::BlockMetaV2;
-
-    #[tokio::test]
-    async fn query_current_frame() -> anyhow::Result<()> {
-        let mut mock_cm = MockAsyncAccessor::new();
-        mock_cm
-            .expect_get_current_meta::<BlockMetaV2>()
-            .times(1)
-            .returning(|f| {
-                Some(f(&CurrentMeta {
-                    current_block_meta: BlockMetaV2 {
-                        issuers_frame: 1,
-                        ..Default::default()
-                    },
-                    ..Default::default()
-                }))
-            });
-        let mut dbs_reader = MockDbsReader::new();
-        dbs_reader
-            .expect_get_current_frame::<BcV2DbRo<FileBackend>>()
-            .times(1)
-            .returning(|_, _| {
-                Ok(vec![BlockMetaV2 {
-                    ..Default::default()
-                }])
-            });
-        let schema = create_schema(mock_cm, dbs_reader)?;
-        assert_eq!(
-            exec_graphql_request(&schema, r#"{ currentFrame {nonce} }"#).await?,
-            serde_json::json!({
-                "data": {
-                    "currentFrame": [{
-                      "nonce": 0
-                    }]
-                }
-            })
-        );
-        Ok(())
-    }
-}
diff --git a/rust-libs/modules/gva/gql/src/queries/first_utxos_of_scripts.rs b/rust-libs/modules/gva/gql/src/queries/first_utxos_of_scripts.rs
deleted file mode 100644
index a8d3c1bd2..000000000
--- a/rust-libs/modules/gva/gql/src/queries/first_utxos_of_scripts.rs
+++ /dev/null
@@ -1,65 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Default)]
-pub(crate) struct FirstUtxosQuery;
-#[async_graphql::Object]
-impl FirstUtxosQuery {
-    /// First utxos of scripts
-    async fn first_utxos_of_scripts(
-        &self,
-        ctx: &async_graphql::Context<'_>,
-        #[graphql(
-            desc = "DUBP wallets scripts",
-            validator(ListMaxLength(length = "100"))
-        )]
-        scripts: Vec<PkOrScriptGva>,
-        #[graphql(
-            desc = "Number of first utxos to get ",
-            default = 10,
-            validator(IntRange(min = "1", max = "40"))
-        )]
-        first: i32,
-    ) -> async_graphql::Result<Vec<UtxosGva>> {
-        let scripts: Vec<WalletScriptV10> = scripts.into_iter().map(|script| script.0).collect();
-
-        let data = ctx.data::<GvaSchemaData>()?;
-        let db_reader = data.dbs_reader();
-
-        let utxos_matrice: Vec<arrayvec::ArrayVec<_>> = data
-            .dbs_pool
-            .execute(move |_| db_reader.first_scripts_utxos(None, first as usize, &scripts))
-            .await??;
-
-        Ok(utxos_matrice
-            .into_iter()
-            .map(|utxos| {
-                UtxosGva(
-                    utxos
-                        .into_iter()
-                        .map(|utxo| UtxoGva {
-                            amount: utxo.amount.amount(),
-                            base: utxo.amount.base(),
-                            tx_hash: utxo.tx_hash.to_hex(),
-                            output_index: utxo.output_index as u32,
-                        })
-                        .collect(),
-                )
-            })
-            .collect())
-    }
-}
diff --git a/rust-libs/modules/gva/gql/src/queries/gen_tx.rs b/rust-libs/modules/gva/gql/src/queries/gen_tx.rs
deleted file mode 100644
index 8762966a8..000000000
--- a/rust-libs/modules/gva/gql/src/queries/gen_tx.rs
+++ /dev/null
@@ -1,277 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-use dubp::{
-    crypto::bases::BaseConversionError,
-    documents::transaction::v10_gen::{TransactionDocV10ComplexGen, TxV10ComplexIssuer},
-    documents::transaction::UnsignedTransactionDocumentTrait,
-};
-use duniter_dbs::smallvec::SmallVec;
-
-struct TxIssuerTyped {
-    script: WalletScriptV10,
-    signers: SmallVec<[PublicKey; 1]>,
-    codes: SmallVec<[String; 1]>,
-    amount: i32,
-}
-impl TryFrom<TxIssuer> for TxIssuerTyped {
-    type Error = async_graphql::Error;
-
-    fn try_from(input: TxIssuer) -> async_graphql::Result<Self> {
-        let codes = if let Some(codes) = input.codes {
-            codes.into_iter().collect()
-        } else {
-            SmallVec::new()
-        };
-        let signers: SmallVec<[PublicKey; 1]> = input
-            .signers
-            .iter()
-            .map(|s| PublicKey::from_base58(s))
-            .collect::<Result<_, BaseConversionError>>()?;
-        let script = if let Some(ref script_str) = input.script {
-            dubp::documents_parser::wallet_script_from_str(script_str)?
-        } else if signers.len() <= 3 && codes.is_empty() {
-            match signers.len() {
-                1 => WalletScriptV10::single(WalletConditionV10::Sig(signers[0])),
-                2 => WalletScriptV10::and(
-                    WalletConditionV10::Sig(signers[0]),
-                    WalletConditionV10::Sig(signers[1]),
-                ),
-                3 => WalletScriptV10::and_and(
-                    WalletConditionV10::Sig(signers[0]),
-                    WalletConditionV10::Sig(signers[1]),
-                    WalletConditionV10::Sig(signers[2]),
-                ),
-                _ => unreachable!(),
-            }
-        } else {
-            return Err(async_graphql::Error::new("missing a issuer script"));
-        };
-        Ok(Self {
-            script,
-            signers,
-            codes,
-            amount: input.amount,
-        })
-    }
-}
-struct TxRecipientTyped {
-    amount: i32,
-    script: WalletScriptV10,
-}
-impl TryFrom<TxRecipient> for TxRecipientTyped {
-    type Error = async_graphql::Error;
-
-    fn try_from(input: TxRecipient) -> async_graphql::Result<Self> {
-        let script = dubp::documents_parser::wallet_script_from_str(&input.script)?;
-        Ok(Self {
-            amount: input.amount,
-            script,
-        })
-    }
-}
-
-#[derive(Default)]
-pub(crate) struct GenTxsQuery;
-#[async_graphql::Object]
-impl GenTxsQuery {
-    #[allow(clippy::too_many_arguments)]
-    /// Generate simple transaction document
-    async fn gen_tx(
-        &self,
-        ctx: &async_graphql::Context<'_>,
-        #[graphql(desc = "Transaction amount", validator(IntGreaterThan(value = "0")))] amount: i32,
-        #[graphql(
-            desc = "Cash back address, equal to issuer address by default (Ed25519 public key on base 58 representation)"
-        )]
-        cash_back_address: Option<PubKeyGva>,
-        #[graphql(desc = "Transaction comment", validator(TxCommentValidator))] comment: Option<
-            String,
-        >,
-        issuer: PubKeyGva,
-        #[graphql(desc = "Recipient address")] recipient: PkOrScriptGva,
-        #[graphql(desc = "Use mempool sources", default = false)] use_mempool_sources: bool,
-    ) -> async_graphql::Result<Vec<String>> {
-        let comment = comment.unwrap_or_default();
-        let issuer = issuer.0;
-        let recipient = recipient.0;
-
-        let data = ctx.data::<GvaSchemaData>()?;
-        let db_reader = data.dbs_reader();
-        let currency = data.server_meta_data.currency.clone();
-
-        if let Some(current_block_meta) = data
-            .cm_accessor
-            .get_current_meta(|cm| cm.current_block_meta)
-            .await
-        {
-            let (inputs, inputs_sum) = data
-                .dbs_pool
-                .execute(move |dbs| {
-                    db_reader.find_inputs(
-                        &dbs.bc_db_ro,
-                        &dbs.txs_mp_db,
-                        SourceAmount::new(amount as i64, current_block_meta.unit_base as i64),
-                        &WalletScriptV10::single(WalletConditionV10::Sig(issuer)),
-                        use_mempool_sources,
-                    )
-                })
-                .await??;
-
-            let amount = SourceAmount::new(amount as i64, current_block_meta.unit_base as i64);
-
-            if inputs_sum < amount {
-                return Err(async_graphql::Error::new("insufficient balance"));
-            }
-
-            let current_blockstamp = Blockstamp {
-                number: BlockNumber(current_block_meta.number),
-                hash: BlockHash(current_block_meta.hash),
-            };
-
-            Ok(TransactionDocumentV10::generate_simple_txs(
-                current_blockstamp,
-                currency,
-                (inputs, inputs_sum),
-                issuer,
-                recipient,
-                (amount, comment),
-                cash_back_address.map(|pubkey_gva| pubkey_gva.0),
-            )
-            .into_iter()
-            .map(|tx| tx.as_text().to_owned())
-            .collect())
-        } else {
-            Err(async_graphql::Error::new("no blockchain"))
-        }
-    }
-    /// Generate complex transaction document
-    async fn gen_complex_tx(
-        &self,
-        ctx: &async_graphql::Context<'_>,
-        #[graphql(desc = "Transaction issuers")] issuers: Vec<TxIssuer>,
-        #[graphql(desc = "Transaction recipients")] recipients: Vec<TxRecipient>,
-        #[graphql(desc = "Transaction comment", validator(TxCommentValidator))] comment: Option<
-            String,
-        >,
-        #[graphql(desc = "Use mempool sources", default = false)] use_mempool_sources: bool,
-    ) -> async_graphql::Result<RawTxOrChanges> {
-        let comment = comment.unwrap_or_default();
-        let issuers = issuers
-            .into_iter()
-            .map(TryFrom::try_from)
-            .collect::<async_graphql::Result<Vec<TxIssuerTyped>>>()?;
-        let recipients = recipients
-            .into_iter()
-            .map(TryFrom::try_from)
-            .collect::<async_graphql::Result<Vec<TxRecipientTyped>>>()?;
-
-        let issuers_sum: i32 = issuers.iter().map(|issuer| issuer.amount).sum();
-        let recipients_sum: i32 = recipients.iter().map(|recipient| recipient.amount).sum();
-        if issuers_sum != recipients_sum {
-            return Err(async_graphql::Error::new(
-            "The sum of the amounts of the issuers must be equal to the sum of the amounts of the recipients.",
-        ));
-        }
-
-        let data = ctx.data::<GvaSchemaData>()?;
-        let db_reader = data.dbs_reader();
-        let currency = data.server_meta_data.currency.clone();
-
-        if let Some(current_block_meta) = data
-            .cm_accessor
-            .get_current_meta(|cm| cm.current_block_meta)
-            .await
-        {
-            let issuers_inputs_with_sum = data
-                .dbs_pool
-                .execute(move |dbs| {
-                    let mut issuers_inputs_with_sum = Vec::new();
-                    for issuer in issuers {
-                        issuers_inputs_with_sum.push((
-                            db_reader.find_inputs(
-                                &dbs.bc_db_ro,
-                                &dbs.txs_mp_db,
-                                SourceAmount::new(
-                                    issuer.amount as i64,
-                                    current_block_meta.unit_base as i64,
-                                ),
-                                &issuer.script,
-                                use_mempool_sources,
-                            )?,
-                            issuer,
-                        ));
-                    }
-                    Ok::<_, anyhow::Error>(issuers_inputs_with_sum)
-                })
-                .await??;
-
-            for ((_inputs, inputs_sum), issuer) in &issuers_inputs_with_sum {
-                let amount =
-                    SourceAmount::new(issuer.amount as i64, current_block_meta.unit_base as i64);
-                if *inputs_sum < amount {
-                    return Err(async_graphql::Error::new(format!(
-                        "Insufficient balance for issuer {}",
-                        issuer.script.to_string()
-                    )));
-                }
-            }
-
-            let current_blockstamp = Blockstamp {
-                number: BlockNumber(current_block_meta.number),
-                hash: BlockHash(current_block_meta.hash),
-            };
-            let base = current_block_meta.unit_base as i64;
-
-            let (final_tx_opt, changes_txs) = TransactionDocV10ComplexGen {
-                blockstamp: current_blockstamp,
-                currency,
-                issuers: issuers_inputs_with_sum
-                    .into_iter()
-                    .map(|((inputs, inputs_sum), issuer)| TxV10ComplexIssuer {
-                        amount: SourceAmount::new(issuer.amount as i64, base),
-                        codes: issuer.codes,
-                        inputs,
-                        inputs_sum,
-                        script: issuer.script,
-                        signers: issuer.signers,
-                    })
-                    .collect(),
-                recipients: recipients
-                    .into_iter()
-                    .map(|TxRecipientTyped { amount, script }| {
-                        (SourceAmount::new(amount as i64, base), script)
-                    })
-                    .collect(),
-                user_comment: comment,
-            }
-            .gen()?;
-
-            if let Some(final_tx) = final_tx_opt {
-                Ok(RawTxOrChanges::FinalTx(final_tx.as_text().to_owned()))
-            } else {
-                Ok(RawTxOrChanges::Changes(
-                    changes_txs
-                        .into_iter()
-                        .map(|tx| tx.as_text().to_owned())
-                        .collect(),
-                ))
-            }
-        } else {
-            Err(async_graphql::Error::new("no blockchain"))
-        }
-    }
-}
diff --git a/rust-libs/modules/gva/gql/src/queries/idty.rs b/rust-libs/modules/gva/gql/src/queries/idty.rs
deleted file mode 100644
index ac0090e8c..000000000
--- a/rust-libs/modules/gva/gql/src/queries/idty.rs
+++ /dev/null
@@ -1,81 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Default)]
-pub(crate) struct IdtyQuery;
-#[async_graphql::Object]
-impl IdtyQuery {
-    /// Get identity by public key
-    async fn idty(
-        &self,
-        ctx: &async_graphql::Context<'_>,
-        #[graphql(desc = "public key")] pubkey: PubKeyGva,
-    ) -> async_graphql::Result<Option<Identity>> {
-        let data = ctx.data::<GvaSchemaData>()?;
-        let dbs_reader = data.dbs_reader();
-
-        Ok(data
-            .dbs_pool
-            .execute(move |dbs| dbs_reader.idty(&dbs.bc_db_ro, pubkey.0))
-            .await??
-            .map(|idty| Identity {
-                is_member: idty.is_member,
-                username: idty.username,
-            }))
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use crate::tests::*;
-
-    #[tokio::test]
-    async fn test_idty() -> anyhow::Result<()> {
-        let mut dbs_reader = MockDbsReader::new();
-        dbs_reader
-            .expect_idty()
-            .withf(|_, s| {
-                s == &PublicKey::from_base58("DnjL6hYA1k7FavGHbbir79PKQbmzw63d6bsamBBdUULP")
-                    .expect("wrong pubkey")
-            })
-            .times(1)
-            .returning(|_, _| {
-                Ok(Some(duniter_dbs::IdtyDbV2 {
-                    is_member: true,
-                    username: String::from("JohnDoe"),
-                }))
-            });
-        let schema = create_schema(MockAsyncAccessor::new(), dbs_reader)?;
-        assert_eq!(
-            exec_graphql_request(
-                &schema,
-                r#"{ idty(pubkey: "DnjL6hYA1k7FavGHbbir79PKQbmzw63d6bsamBBdUULP") {isMember, username} }"#
-            )
-            .await?,
-            serde_json::json!({
-                "data": {
-                    "idty": {
-                        "isMember": true,
-                        "username": "JohnDoe"
-                    }
-                }
-            })
-        );
-        Ok(())
-    }
-}
diff --git a/rust-libs/modules/gva/gql/src/queries/network.rs b/rust-libs/modules/gva/gql/src/queries/network.rs
deleted file mode 100644
index e24be4b4d..000000000
--- a/rust-libs/modules/gva/gql/src/queries/network.rs
+++ /dev/null
@@ -1,144 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Default, async_graphql::SimpleObject)]
-pub(crate) struct NetworkQuery {
-    network: NetworkQueryInner,
-}
-
-#[derive(Default)]
-pub(crate) struct NetworkQueryInner;
-
-#[async_graphql::Object]
-impl NetworkQueryInner {
-    /// Get endpoints known by the node
-    async fn endpoints(
-        &self,
-        ctx: &async_graphql::Context<'_>,
-        #[graphql(
-            desc = "filter endpoints by api (exact match endpoint first word, case sensitive)"
-        )]
-        api_list: Vec<String>,
-    ) -> async_graphql::Result<Vec<String>> {
-        let data = ctx.data::<GvaSchemaData>()?;
-        let dbs_reader = data.dbs_reader();
-
-        Ok(data
-            .dbs_pool
-            .execute(move |dbs| dbs_reader.endpoints(&dbs.dunp_db, api_list))
-            .await??)
-    }
-    /// Get peers and heads
-    async fn nodes(
-        &self,
-        ctx: &async_graphql::Context<'_>,
-    ) -> async_graphql::Result<Vec<PeerWithHeads>> {
-        let data = ctx.data::<GvaSchemaData>()?;
-
-        let db_reader = data.dbs_reader();
-
-        Ok(data
-            .dbs_pool
-            .execute(move |dbs| db_reader.peers_and_heads(&dbs.dunp_db))
-            .await??
-            .into_iter()
-            .map(|(peer, heads)| PeerWithHeads {
-                peer: PeerCardGva::from(peer),
-                heads: heads.into_iter().map(HeadGva::from).collect(),
-            })
-            .collect())
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use crate::tests::*;
-    use duniter_dbs::databases::network_v1::NetworkV1Db;
-    use pretty_assertions::assert_eq;
-
-    #[tokio::test]
-    async fn test_endpoints() -> anyhow::Result<()> {
-        let mock_cm = MockAsyncAccessor::new();
-        let mut mock_dbs_reader = MockDbsReader::new();
-        mock_dbs_reader
-            .expect_endpoints::<NetworkV1Db<FileBackend>>()
-            .times(1)
-            .returning(|_, _| {
-                Ok(vec![
-                    "GVA S g1.librelois.fr 443 gva".to_owned(),
-                    "GVA S domain.tld 443 gva".to_owned(),
-                ])
-            });
-        let schema = create_schema(mock_cm, mock_dbs_reader)?;
-        assert_eq!(
-            exec_graphql_request(&schema, r#"{ network { endpoints(apiList:["GVA"]) } }"#).await?,
-            serde_json::json!({
-                "data": {
-                    "network": {
-                        "endpoints": [
-                            "GVA S g1.librelois.fr 443 gva",
-                            "GVA S domain.tld 443 gva"
-                        ]
-                    }
-                }
-            })
-        );
-        Ok(())
-    }
-
-    #[tokio::test]
-    async fn test_peers_and_heads() -> anyhow::Result<()> {
-        let mut dbs_reader = MockDbsReader::new();
-        dbs_reader
-            .expect_peers_and_heads::<NetworkV1Db<FileBackend>>()
-            .times(1)
-            .returning(|_| {
-                Ok(vec![(
-                    duniter_dbs::PeerCardDbV1::default(),
-                    vec![duniter_dbs::DunpHeadDbV1::default()],
-                )])
-            });
-        let schema = create_schema(MockAsyncAccessor::new(), dbs_reader)?;
-        assert_eq!(
-            exec_graphql_request(
-                &schema,
-                r#"{ network { nodes { peer { blockstamp }, heads { blockstamp } } } }"#
-            )
-            .await?,
-            serde_json::json!({
-                "data": {
-                    "network": {
-                        "nodes": [
-                            {
-                                "heads": [
-                                    {
-                                        "blockstamp": "0-0000000000000000000000000000000000000000000000000000000000000000"
-                                    }
-                                ],
-                                "peer": {
-                                    "blockstamp": ""
-                                }
-                            }
-                        ],
-                    }
-                }
-            })
-        );
-        Ok(())
-    }
-}
diff --git a/rust-libs/modules/gva/gql/src/queries/txs_history.rs b/rust-libs/modules/gva/gql/src/queries/txs_history.rs
deleted file mode 100644
index 3cf5bfe93..000000000
--- a/rust-libs/modules/gva/gql/src/queries/txs_history.rs
+++ /dev/null
@@ -1,345 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::inputs::TimeInterval;
-use crate::*;
-use duniter_gva_db::GvaTxDbV1;
-use duniter_gva_dbs_reader::txs_history::TxBcCursor;
-use futures::future::join;
-
-#[derive(Default)]
-pub(crate) struct TxsHistoryBlockchainQuery;
-
-#[async_graphql::Object]
-impl TxsHistoryBlockchainQuery {
-    /// Transactions history (written in blockchain)
-    async fn txs_history_bc(
-        &self,
-        ctx: &async_graphql::Context<'_>,
-        #[graphql(desc = "pagination", default)] pagination: Pagination,
-        script: PkOrScriptGva,
-        #[graphql(default)] time_interval: TimeInterval,
-    ) -> async_graphql::Result<TxsHistoryBlockchainQueryInner> {
-        let QueryContext { is_whitelisted } = ctx.data::<QueryContext>()?;
-        let pagination = Pagination::convert_to_page_info(pagination, *is_whitelisted)?;
-        let script_hash = Hash::compute(script.0.to_string().as_bytes());
-        Ok(TxsHistoryBlockchainQueryInner {
-            pagination,
-            script_hash,
-            time_interval,
-        })
-    }
-}
-
-pub(crate) struct TxsHistoryBlockchainQueryInner {
-    pub(crate) pagination: PageInfo<TxBcCursor>,
-    pub(crate) script_hash: Hash,
-    pub(crate) time_interval: TimeInterval,
-}
-
-#[async_graphql::Object]
-impl TxsHistoryBlockchainQueryInner {
-    /// Transactions history (written in blockchain)
-    async fn both(
-        &self,
-        ctx: &async_graphql::Context<'_>,
-    ) -> async_graphql::Result<Connection<String, TxGva, EmptyFields, EdgeTx>> {
-        let start_time = std::time::Instant::now();
-
-        let data = ctx.data::<GvaSchemaData>()?;
-
-        let db_reader = data.dbs_reader();
-        let pagination = self.pagination;
-        let script_hash = self.script_hash;
-        let time_interval = self.time_interval;
-        let sent_fut = data.dbs_pool.execute(move |_| {
-            db_reader.get_txs_history_bc_sent(
-                time_interval.from,
-                pagination,
-                script_hash,
-                time_interval.to,
-            )
-        });
-        let db_reader = data.dbs_reader();
-        let script_hash = self.script_hash;
-        let received_fut = data.dbs_pool.execute(move |_| {
-            db_reader.get_txs_history_bc_received(
-                time_interval.from,
-                pagination,
-                script_hash,
-                time_interval.to,
-            )
-        });
-        let (sent_res, received_res) = join(sent_fut, received_fut).await;
-        let (sent, received) = (sent_res??, received_res??);
-
-        let mut both_txs = sent
-            .data
-            .into_iter()
-            .map(|db_tx| (TxDirection::Sent, db_tx))
-            .chain(
-                received
-                    .data
-                    .into_iter()
-                    .map(|db_tx| (TxDirection::Received, db_tx)),
-            )
-            .collect::<Vec<(TxDirection, GvaTxDbV1)>>();
-        /*if let Some(TxBcCursor { tx_hash, .. }) = pagination.pos() {
-            while both.txs
-        }*/
-        if self.pagination.order() {
-            both_txs.sort_unstable_by(|(_, db_tx1), (_, db_tx2)| {
-                db_tx1
-                    .written_block
-                    .number
-                    .cmp(&db_tx2.written_block.number)
-            });
-        } else {
-            both_txs.sort_unstable_by(|(_, db_tx1), (_, db_tx2)| {
-                db_tx2
-                    .written_block
-                    .number
-                    .cmp(&db_tx1.written_block.number)
-            });
-        }
-        if let Some(limit) = self.pagination.limit_opt() {
-            both_txs.truncate(limit.get());
-        }
-        let mut conn = Connection::new(
-            sent.has_previous_page || received.has_previous_page,
-            sent.has_next_page || received.has_next_page,
-        );
-        conn.append(both_txs.into_iter().map(|(tx_direction, db_tx)| {
-            Edge::with_additional_fields(
-                TxBcCursor {
-                    block_number: db_tx.written_block.number,
-                    tx_hash: db_tx.tx.get_hash(),
-                }
-                .to_string(),
-                db_tx.into(),
-                EdgeTx {
-                    direction: tx_direction,
-                },
-            )
-        }));
-
-        println!(
-            "txs_history_bc::both duration: {}ms",
-            start_time.elapsed().as_millis()
-        );
-
-        Ok(conn)
-    }
-    /// Received transactions history (written in blockchain)
-    async fn received(
-        &self,
-        ctx: &async_graphql::Context<'_>,
-    ) -> async_graphql::Result<Connection<String, TxGva, EmptyFields, EmptyFields>> {
-        let data = ctx.data::<GvaSchemaData>()?;
-        let db_reader = data.dbs_reader();
-        let pagination = self.pagination;
-        let script_hash = self.script_hash;
-        let time_interval = self.time_interval;
-        let received = data
-            .dbs_pool
-            .execute(move |_| {
-                db_reader.get_txs_history_bc_received(
-                    time_interval.from,
-                    pagination,
-                    script_hash,
-                    time_interval.to,
-                )
-            })
-            .await??;
-        let mut conn = Connection::new(received.has_previous_page, received.has_next_page);
-        conn.append(received.data.into_iter().map(|db_tx| {
-            Edge::new(
-                TxBcCursor {
-                    block_number: db_tx.written_block.number,
-                    tx_hash: db_tx.tx.get_hash(),
-                }
-                .to_string(),
-                db_tx.into(),
-            )
-        }));
-
-        Ok(conn)
-    }
-    /// Sent transactions history (written in blockchain)
-    async fn sent(
-        &self,
-        ctx: &async_graphql::Context<'_>,
-    ) -> async_graphql::Result<Connection<String, TxGva, EmptyFields, EmptyFields>> {
-        let data = ctx.data::<GvaSchemaData>()?;
-        let db_reader = data.dbs_reader();
-        let pagination = self.pagination;
-        let script_hash = self.script_hash;
-        let time_interval = self.time_interval;
-        let sent = data
-            .dbs_pool
-            .execute(move |_| {
-                db_reader.get_txs_history_bc_sent(
-                    time_interval.from,
-                    pagination,
-                    script_hash,
-                    time_interval.to,
-                )
-            })
-            .await??;
-        let mut conn = Connection::new(sent.has_previous_page, sent.has_next_page);
-        conn.append(sent.data.into_iter().map(|db_tx| {
-            Edge::new(
-                TxBcCursor {
-                    block_number: db_tx.written_block.number,
-                    tx_hash: db_tx.tx.get_hash(),
-                }
-                .to_string(),
-                db_tx.into(),
-            )
-        }));
-
-        Ok(conn)
-    }
-}
-
-#[derive(Default)]
-pub(crate) struct TxsHistoryMempoolQuery;
-
-#[async_graphql::Object]
-impl TxsHistoryMempoolQuery {
-    /// Transactions waiting on mempool
-    async fn txs_history_mp(
-        &self,
-        ctx: &async_graphql::Context<'_>,
-        #[graphql(desc = "Ed25519 public key on base 58 representation")] pubkey: PubKeyGva,
-    ) -> async_graphql::Result<TxsHistoryMempool> {
-        let data = ctx.data::<GvaSchemaData>()?;
-        let db_reader = data.dbs_reader();
-
-        let (sending, pending) = data
-            .dbs_pool
-            .execute(move |dbs| db_reader.get_txs_history_mempool(&dbs.txs_mp_db, pubkey.0))
-            .await??;
-
-        Ok(TxsHistoryMempool {
-            sending: sending
-                .into_iter()
-                .map(|db_tx| TxGva::from(&db_tx))
-                .collect(),
-            receiving: pending
-                .into_iter()
-                .map(|db_tx| TxGva::from(&db_tx))
-                .collect(),
-        })
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use std::collections::VecDeque;
-
-    use crate::tests::*;
-    use dubp::documents::transaction::TransactionDocumentV10;
-    use dubp::documents::transaction::TransactionDocumentV10Stringified;
-    use dubp::documents_parser::prelude::FromStringObject;
-    use duniter_gva_db::GvaTxDbV1;
-    use duniter_gva_dbs_reader::pagination::PagedData;
-
-    #[tokio::test]
-    async fn test_txs_history_blockchain() -> anyhow::Result<()> {
-        let mut dbs_reader = MockDbsReader::new();
-        dbs_reader
-            .expect_get_txs_history_bc_received()
-            .times(1)
-            .returning(|_, _, _, _| Ok(PagedData::empty()));
-        dbs_reader
-            .expect_get_txs_history_bc_sent()
-            .times(1)
-            .returning(|_, _, _, _| {
-                let tx = TransactionDocumentV10::from_string_object(
-                    &TransactionDocumentV10Stringified {
-                        currency: "test".to_owned(),
-                        blockstamp:
-                            "0-0000000000000000000000000000000000000000000000000000000000000000"
-                                .to_owned(),
-                        locktime: 0,
-                        issuers: vec![],
-                        inputs: vec![],
-                        unlocks: vec![],
-                        outputs: vec![],
-                        comment: "".to_owned(),
-                        signatures: vec![],
-                        hash: Some(
-                            "0000000000000000000000000000000000000000000000000000000000000000"
-                                .to_owned(),
-                        ),
-                    },
-                )
-                .expect("wrong tx");
-                let mut expected_data = VecDeque::new();
-                expected_data.push_back(GvaTxDbV1 {
-                    tx,
-                    ..Default::default()
-                });
-                Ok(PagedData {
-                    data: expected_data,
-                    has_previous_page: false,
-                    has_next_page: false,
-                })
-            });
-        let schema = create_schema(MockAsyncAccessor::new(), dbs_reader)?;
-        assert_eq!(
-            exec_graphql_request(
-                &schema,
-                r#"{
-                txsHistoryBc(script: "D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx") {
-                    sent {
-                        edges {
-                            node {
-                                blockstamp
-                            }
-                        }
-                    }
-                    received {
-                        edges {
-                            node {
-                                blockstamp
-                            }
-                        }
-                    }
-                }
-              }"#
-            )
-            .await?,
-            serde_json::json!({
-                "data": {
-                    "txsHistoryBc": {
-                        "received": {
-                            "edges": []
-                        },
-                        "sent": {
-                            "edges": [{
-                                "node": {
-                                    "blockstamp": "0-0000000000000000000000000000000000000000000000000000000000000000",
-                                }
-                            }]
-                        }
-                    }
-                  }
-            })
-        );
-        Ok(())
-    }
-}
diff --git a/rust-libs/modules/gva/gql/src/queries/uds.rs b/rust-libs/modules/gva/gql/src/queries/uds.rs
deleted file mode 100644
index a3eab34c1..000000000
--- a/rust-libs/modules/gva/gql/src/queries/uds.rs
+++ /dev/null
@@ -1,185 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-use async_graphql::connection::*;
-use duniter_dbs::databases::bc_v2::BcV2DbReadable;
-use duniter_gva_dbs_reader::{uds_of_pubkey::UdsWithSum, PagedData};
-
-#[derive(Default)]
-pub(crate) struct UdsQuery;
-#[async_graphql::Object]
-impl UdsQuery {
-    /// Current universal dividends amount
-    async fn current_ud(
-        &self,
-        ctx: &async_graphql::Context<'_>,
-    ) -> async_graphql::Result<Option<CurrentUdGva>> {
-        let data = ctx.data::<GvaSchemaData>()?;
-
-        Ok(
-            if let Some(current_ud) = data.cm_accessor.get_current_meta(|cm| cm.current_ud).await {
-                Some(CurrentUdGva {
-                    amount: current_ud.amount(),
-                    base: current_ud.base(),
-                })
-            } else {
-                None
-            },
-        )
-    }
-    /// Universal dividends issued by a public key
-    #[allow(clippy::clippy::too_many_arguments)]
-    async fn uds_of_pubkey(
-        &self,
-        ctx: &async_graphql::Context<'_>,
-        #[graphql(desc = "Ed25519 public key on base 58 representation")] pubkey: PubKeyGva,
-        #[graphql(default)] filter: UdsFilter,
-        #[graphql(desc = "pagination", default)] pagination: Pagination,
-        #[graphql(desc = "Amount needed")] amount: Option<i64>,
-    ) -> async_graphql::Result<Connection<String, UdGva, AggregateSum, EmptyFields>> {
-        let QueryContext { is_whitelisted } = ctx.data::<QueryContext>()?;
-        let pagination = Pagination::convert_to_page_info(pagination, *is_whitelisted)?;
-
-        let data = ctx.data::<GvaSchemaData>()?;
-        let dbs_reader = data.dbs_reader();
-
-        if let Some(current_base) = data
-            .cm_accessor
-            .get_current_meta(|cm| cm.current_block_meta.unit_base)
-            .await
-        {
-            let (
-                PagedData {
-                    data: UdsWithSum { uds, sum },
-                    has_previous_page,
-                    has_next_page,
-                },
-                times,
-            ) = data
-                .dbs_pool
-                .execute(move |dbs| {
-                    let paged_data = match filter {
-                        UdsFilter::All => {
-                            dbs_reader.all_uds_of_pubkey(&dbs.bc_db_ro, pubkey.0, pagination)
-                        }
-                        UdsFilter::Unspent => dbs_reader.unspent_uds_of_pubkey(
-                            &dbs.bc_db_ro,
-                            pubkey.0,
-                            pagination,
-                            None,
-                            amount.map(|amount| SourceAmount::new(amount, current_base as i64)),
-                        ),
-                    }?;
-
-                    let mut times = Vec::with_capacity(paged_data.data.uds.len());
-                    for (bn, _sa) in &paged_data.data.uds {
-                        times.push(dbs_reader.get_blockchain_time(*bn)?);
-                    }
-                    Ok::<_, anyhow::Error>((paged_data, times))
-                })
-                .await??;
-
-            let mut conn = Connection::with_additional_fields(
-                has_previous_page,
-                has_next_page,
-                AggregateSum {
-                    aggregate: Sum {
-                        sum: AmountWithBase {
-                            amount: sum.amount() as i32,
-                            base: sum.base() as i32,
-                        },
-                    },
-                },
-            );
-            let uds_timed =
-                uds.into_iter()
-                    .zip(times.into_iter())
-                    .map(|((bn, sa), blockchain_time)| {
-                        Edge::new(
-                            bn.0.to_string(),
-                            UdGva {
-                                amount: sa.amount(),
-                                base: sa.base(),
-                                issuer: pubkey,
-                                block_number: bn.0,
-                                blockchain_time,
-                            },
-                        )
-                    });
-            if pagination.order() {
-                conn.append(uds_timed);
-            } else {
-                conn.append(uds_timed.rev());
-            }
-            Ok(conn)
-        } else {
-            Err(async_graphql::Error::new("no blockchain"))
-        }
-    }
-    /// Universal dividends revaluations
-    async fn uds_reval(
-        &self,
-        ctx: &async_graphql::Context<'_>,
-    ) -> async_graphql::Result<Vec<RevalUdGva>> {
-        let data = ctx.data::<GvaSchemaData>()?;
-
-        Ok(data
-            .dbs_pool
-            .execute(move |dbs| {
-                dbs.bc_db_ro.uds_reval().iter(.., |it| {
-                    it.map_ok(|(block_number, sa)| RevalUdGva {
-                        amount: sa.0.amount(),
-                        base: sa.0.base(),
-                        block_number: block_number.0,
-                    })
-                    .collect::<KvResult<Vec<_>>>()
-                })
-            })
-            .await??)
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use crate::tests::*;
-
-    #[tokio::test]
-    async fn query_current_ud() -> anyhow::Result<()> {
-        let mut mock_cm = MockAsyncAccessor::new();
-        mock_cm
-            .expect_get_current_meta::<SourceAmount>()
-            .times(1)
-            .returning(|f| {
-                Some(f(&CurrentMeta {
-                    current_ud: SourceAmount::with_base0(100),
-                    ..Default::default()
-                }))
-            });
-        let schema = create_schema(mock_cm, MockDbsReader::new())?;
-        assert_eq!(
-            exec_graphql_request(&schema, r#"{ currentUd {amount} }"#).await?,
-            serde_json::json!({
-                "data": {
-                    "currentUd": {
-                      "amount": 100
-                    }
-                }
-            })
-        );
-        Ok(())
-    }
-}
diff --git a/rust-libs/modules/gva/gql/src/queries/utxos_of_script.rs b/rust-libs/modules/gva/gql/src/queries/utxos_of_script.rs
deleted file mode 100644
index c3a3039e5..000000000
--- a/rust-libs/modules/gva/gql/src/queries/utxos_of_script.rs
+++ /dev/null
@@ -1,103 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-use async_graphql::connection::*;
-use duniter_gva_dbs_reader::{
-    utxos::{UtxoCursor, UtxosWithSum},
-    PagedData,
-};
-
-#[derive(Default)]
-pub(crate) struct UtxosQuery;
-#[async_graphql::Object]
-impl UtxosQuery {
-    /// Utxos of script
-    async fn utxos_of_script(
-        &self,
-        ctx: &async_graphql::Context<'_>,
-        #[graphql(desc = "DUBP wallet script")] script: PkOrScriptGva,
-        #[graphql(desc = "pagination", default)] pagination: Pagination,
-        #[graphql(desc = "Amount needed")] amount: Option<i64>,
-    ) -> async_graphql::Result<Connection<String, UtxoTimedGva, AggregateSum, EmptyFields>> {
-        let QueryContext { is_whitelisted } = ctx.data::<QueryContext>()?;
-        log::info!("is_whitelisted={}", is_whitelisted);
-        let pagination = Pagination::convert_to_page_info(pagination, *is_whitelisted)?;
-
-        let data = ctx.data::<GvaSchemaData>()?;
-        let cm_accessor = data.cm_accessor();
-        let db_reader = data.dbs_reader();
-
-        if let Some(current_base) = cm_accessor
-            .get_current_meta(|cm| cm.current_block_meta.unit_base)
-            .await
-        {
-            let (
-                PagedData {
-                    data: UtxosWithSum { utxos, sum },
-                    has_previous_page,
-                    has_next_page,
-                },
-                times,
-            ) = data
-                .dbs_pool
-                .execute(move |dbs| {
-                    let paged_data = db_reader.find_script_utxos(
-                        &dbs.txs_mp_db,
-                        amount.map(|amount| SourceAmount::new(amount, current_base as i64)),
-                        pagination,
-                        &script.0,
-                    )?;
-                    let mut times = Vec::with_capacity(paged_data.data.utxos.len());
-                    for (UtxoCursor { block_number, .. }, _sa) in &paged_data.data.utxos {
-                        times.push(db_reader.get_blockchain_time(*block_number)?);
-                    }
-                    Ok::<_, anyhow::Error>((paged_data, times))
-                })
-                .await??;
-
-            let mut conn = Connection::with_additional_fields(
-                has_previous_page,
-                has_next_page,
-                AggregateSum {
-                    aggregate: Sum {
-                        sum: AmountWithBase {
-                            amount: sum.amount() as i32,
-                            base: sum.base() as i32,
-                        },
-                    },
-                },
-            );
-            conn.append(utxos.into_iter().zip(times.into_iter()).map(
-                |((utxo_cursor, source_amount), blockchain_time)| {
-                    Edge::new(
-                        utxo_cursor.to_string(),
-                        UtxoTimedGva {
-                            amount: source_amount.amount(),
-                            base: source_amount.base(),
-                            tx_hash: utxo_cursor.tx_hash.to_hex(),
-                            output_index: utxo_cursor.output_index as u32,
-                            written_block: utxo_cursor.block_number.0,
-                            written_time: blockchain_time,
-                        },
-                    )
-                },
-            ));
-            Ok(conn)
-        } else {
-            Err(async_graphql::Error::new("no blockchain"))
-        }
-    }
-}
diff --git a/rust-libs/modules/gva/gql/src/scalars.rs b/rust-libs/modules/gva/gql/src/scalars.rs
deleted file mode 100644
index f58a79ba5..000000000
--- a/rust-libs/modules/gva/gql/src/scalars.rs
+++ /dev/null
@@ -1,83 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-use async_graphql::{InputValueError, InputValueResult, Scalar, ScalarType};
-use dubp::crypto::bases::b58::ToBase58;
-
-#[derive(Clone, Copy, Debug)]
-pub(crate) struct PubKeyGva(pub(crate) PublicKey);
-
-impl async_graphql::Description for PubKeyGva {
-    fn description() -> &'static str {
-        "Public key on base 58 representation"
-    }
-}
-
-#[Scalar(use_type_description = true)]
-impl ScalarType for PubKeyGva {
-    fn parse(value: async_graphql::Value) -> InputValueResult<Self> {
-        if let async_graphql::Value::String(value_str) = &value {
-            if value_str.len() < 40 {
-                Err(InputValueError::custom("too short public key"))
-            } else if value_str.len() > 44 {
-                Err(InputValueError::custom("too long public key"))
-            } else {
-                Ok(PublicKey::from_base58(value_str).map(PubKeyGva)?)
-            }
-        } else {
-            // If the type does not match
-            Err(InputValueError::expected_type(value))
-        }
-    }
-
-    fn to_value(&self) -> async_graphql::Value {
-        async_graphql::Value::String(self.0.to_base58())
-    }
-}
-
-pub(crate) struct PkOrScriptGva(pub(crate) WalletScriptV10);
-
-impl async_graphql::Description for PkOrScriptGva {
-    fn description() -> &'static str {
-        "Public key on base 58 representation or complex DUBP script"
-    }
-}
-
-#[Scalar(use_type_description = true)]
-impl ScalarType for PkOrScriptGva {
-    fn parse(value: async_graphql::Value) -> InputValueResult<Self> {
-        if let async_graphql::Value::String(value_str) = &value {
-            Ok(PkOrScriptGva(
-                if value_str.len() >= 40 || value_str.len() <= 44 {
-                    if let Ok(pubkey) = PublicKey::from_base58(&value_str) {
-                        WalletScriptV10::single_sig(pubkey)
-                    } else {
-                        dubp::documents_parser::wallet_script_from_str(&value_str)?
-                    }
-                } else {
-                    dubp::documents_parser::wallet_script_from_str(&value_str)?
-                },
-            ))
-        } else {
-            // If the type does not match
-            Err(InputValueError::expected_type(value))
-        }
-    }
-
-    fn to_value(&self) -> async_graphql::Value {
-        async_graphql::Value::String(self.0.to_string())
-    }
-}
diff --git a/rust-libs/modules/gva/gql/src/schema.rs b/rust-libs/modules/gva/gql/src/schema.rs
deleted file mode 100644
index c5ab4f6de..000000000
--- a/rust-libs/modules/gva/gql/src/schema.rs
+++ /dev/null
@@ -1,74 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-pub type GvaSchema = async_graphql::Schema<
-    crate::queries::QueryRoot,
-    crate::mutations::MutationRoot,
-    crate::subscriptions::SubscriptionRoot,
->;
-
-pub fn get_schema_definition() -> String {
-    async_graphql::Schema::build(
-        queries::QueryRoot::default(),
-        mutations::MutationRoot::default(),
-        subscriptions::SubscriptionRoot::default(),
-    )
-    .finish()
-    .sdl()
-}
-
-pub fn build_schema_with_data(data: GvaSchemaData, logger: bool) -> GvaSchema {
-    let mut builder = async_graphql::Schema::build(
-        queries::QueryRoot::default(),
-        mutations::MutationRoot::default(),
-        subscriptions::SubscriptionRoot::default(),
-    )
-    .data(data);
-    if logger {
-        builder = builder.extension(async_graphql::extensions::Logger);
-    }
-    builder.finish()
-}
-
-pub struct GvaSchemaData {
-    pub cm_accessor: AsyncAccessor,
-    pub dbs_pool: fast_threadpool::ThreadPoolAsyncHandler<SharedDbs<FileBackend>>,
-    pub dbs_reader: DbsReaderImpl,
-    pub server_meta_data: ServerMetaData,
-    pub txs_mempool: TxsMempool,
-}
-
-#[cfg(not(test))]
-impl GvaSchemaData {
-    #[inline(always)]
-    pub fn cm_accessor(&self) -> AsyncAccessor {
-        self.cm_accessor
-    }
-    #[inline(always)]
-    pub fn dbs_reader(&self) -> DbsReaderImpl {
-        self.dbs_reader
-    }
-}
-#[cfg(test)]
-impl GvaSchemaData {
-    pub fn cm_accessor(&self) -> AsyncAccessor {
-        self.cm_accessor.clone()
-    }
-    pub fn dbs_reader(&self) -> DbsReaderImpl {
-        self.dbs_reader.clone()
-    }
-}
diff --git a/rust-libs/modules/gva/gql/src/subscriptions.rs b/rust-libs/modules/gva/gql/src/subscriptions.rs
deleted file mode 100644
index 4a5dafaa6..000000000
--- a/rust-libs/modules/gva/gql/src/subscriptions.rs
+++ /dev/null
@@ -1,62 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-mod new_blocks;
-mod receive_pending_txs;
-
-use crate::*;
-use futures::future::Either;
-
-#[derive(Clone, Copy, Default, async_graphql::MergedSubscription)]
-pub struct SubscriptionRoot(
-    new_blocks::NewBlocksSubscription,
-    receive_pending_txs::PendingTxsSubscription,
-);
-
-pub(crate) async fn create_subscription<C, D, E, F, FC, FUT>(
-    ctx: &async_graphql::Context<'_>,
-    select_col: FC,
-    f: F,
-) -> impl Stream<Item = async_graphql::Result<D>>
-where
-    C: DbCollectionRo<Event = E, K = E::K, V = E::V>,
-    E: EventTrait,
-    F: FnMut(Arc<Events<E>>) -> FUT,
-    FUT: std::future::Future<Output = Option<async_graphql::Result<D>>>,
-    FC: 'static + Send + FnOnce(&SharedDbs<FileBackend>) -> &C,
-{
-    match subscribe_to_col(ctx, select_col).await {
-        Ok(r) => Either::Left(r.into_stream().filter_map(f)),
-        Err(e) => {
-            use futures::FutureExt;
-            Either::Right(futures::future::ready(Err(e)).into_stream())
-        }
-    }
-}
-
-async fn subscribe_to_col<C, E, F>(
-    ctx: &async_graphql::Context<'_>,
-    f: F,
-) -> async_graphql::Result<flume::Receiver<Arc<Events<E>>>>
-where
-    C: DbCollectionRo<Event = E, K = E::K, V = E::V>,
-    E: EventTrait,
-    F: 'static + Send + FnOnce(&SharedDbs<FileBackend>) -> &C,
-{
-    let data = ctx.data::<GvaSchemaData>()?;
-    let (s, r) = flume::unbounded();
-    data.dbs_pool.execute(|dbs| f(dbs).subscribe(s)).await??;
-    Ok(r)
-}
diff --git a/rust-libs/modules/gva/gql/src/subscriptions/new_blocks.rs b/rust-libs/modules/gva/gql/src/subscriptions/new_blocks.rs
deleted file mode 100644
index aa6c56e34..000000000
--- a/rust-libs/modules/gva/gql/src/subscriptions/new_blocks.rs
+++ /dev/null
@@ -1,51 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use super::create_subscription;
-use crate::*;
-use duniter_dbs::databases::cm_v1::{CmV1DbReadable, CurrentBlockEvent};
-
-#[derive(Clone, Copy, Default)]
-pub struct NewBlocksSubscription;
-
-#[async_graphql::Subscription]
-impl NewBlocksSubscription {
-    async fn new_blocks(
-        &self,
-        ctx: &async_graphql::Context<'_>,
-    ) -> impl Stream<Item = async_graphql::Result<Vec<Block>>> {
-        create_subscription(
-            ctx,
-            |dbs| dbs.cm_db.current_block(),
-            |events| {
-                let mut blocks = Vec::new();
-                for event in events.deref() {
-                    if let CurrentBlockEvent::Upsert {
-                        value: ref block, ..
-                    } = event
-                    {
-                        blocks.push(Block::from(&block.0));
-                    }
-                }
-                if blocks.is_empty() {
-                    futures::future::ready(None)
-                } else {
-                    futures::future::ready(Some(Ok(blocks)))
-                }
-            },
-        )
-        .await
-    }
-}
diff --git a/rust-libs/modules/gva/gql/src/subscriptions/receive_pending_txs.rs b/rust-libs/modules/gva/gql/src/subscriptions/receive_pending_txs.rs
deleted file mode 100644
index 232822866..000000000
--- a/rust-libs/modules/gva/gql/src/subscriptions/receive_pending_txs.rs
+++ /dev/null
@@ -1,52 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use super::create_subscription;
-use crate::*;
-use duniter_dbs::databases::txs_mp_v2::TxsEvent;
-
-#[derive(Clone, Copy, Default)]
-pub struct PendingTxsSubscription;
-
-#[async_graphql::Subscription]
-impl PendingTxsSubscription {
-    async fn receive_pending_txs(
-        &self,
-        ctx: &async_graphql::Context<'_>,
-    ) -> impl Stream<Item = async_graphql::Result<Vec<TxGva>>> {
-        create_subscription(
-            ctx,
-            |dbs| dbs.txs_mp_db.txs(),
-            |events| {
-                let mut txs = Vec::new();
-                for event in events.deref() {
-                    if let TxsEvent::Upsert {
-                        value: ref pending_tx,
-                        ..
-                    } = event
-                    {
-                        txs.push(TxGva::from(&pending_tx.0));
-                    }
-                }
-                if txs.is_empty() {
-                    futures::future::ready(None)
-                } else {
-                    futures::future::ready(Some(Ok(txs)))
-                }
-            },
-        )
-        .await
-    }
-}
diff --git a/rust-libs/modules/gva/indexer/Cargo.toml b/rust-libs/modules/gva/indexer/Cargo.toml
deleted file mode 100644
index 966ffef15..000000000
--- a/rust-libs/modules/gva/indexer/Cargo.toml
+++ /dev/null
@@ -1,25 +0,0 @@
-[package]
-name = "duniter-gva-indexer"
-version = "0.1.0"
-authors = ["elois <elois@duniter.org>"]
-description = "Duniter GVA DB writer"
-repository = "https://git.duniter.org/nodes/typescript/duniter"
-keywords = ["dubp", "duniter", "blockchain", "database"]
-license = "AGPL-3.0"
-edition = "2018"
-
-[lib]
-path = "src/lib.rs"
-
-[dependencies]
-anyhow = "1.0.34"
-duniter-dbs = { path = "../../../duniter-dbs" }
-duniter-gva-db = { path = "../db" }
-dubp = { version = "0.51.0", features = ["duniter"] }
-once_cell = "1.5.2"
-resiter = "0.4.0"
-
-[dev-dependencies]
-duniter-dbs = { path = "../../../duniter-dbs", features = ["mem"] }
-maplit = "1.0.2"
-smallvec = { version = "1.4.0", features = ["serde", "write"] }
diff --git a/rust-libs/modules/gva/indexer/src/identities.rs b/rust-libs/modules/gva/indexer/src/identities.rs
deleted file mode 100644
index 0a33b376b..000000000
--- a/rust-libs/modules/gva/indexer/src/identities.rs
+++ /dev/null
@@ -1,80 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-pub(crate) fn update_identities<B: Backend>(
-    block: &DubpBlockV10,
-    identities: &mut TxColRw<B::Col, GvaIdentitiesEvent>,
-) -> KvResult<()> {
-    for mb in block.joiners() {
-        let pubkey = mb.issuers()[0];
-
-        let mut idty = identities.get(&PubKeyKeyV2(pubkey))?.unwrap_or_default();
-        idty.is_member = true;
-        idty.joins.push(block.number());
-        identities.upsert(PubKeyKeyV2(pubkey), idty);
-    }
-    for revo in block.revoked() {
-        let pubkey = revo.issuer;
-        if let Some(mut idty) = identities.get(&PubKeyKeyV2(pubkey))? {
-            idty.is_member = false;
-            idty.leaves.insert(block.number());
-            identities.upsert(PubKeyKeyV2(pubkey), idty)
-        }
-    }
-    for pubkey in block.excluded().iter().copied() {
-        if let Some(mut idty) = identities.get(&PubKeyKeyV2(pubkey))? {
-            idty.is_member = false;
-            idty.leaves.insert(block.number());
-            identities.upsert(PubKeyKeyV2(pubkey), idty)
-        }
-    }
-    Ok(())
-}
-
-pub(crate) fn revert_identities<B: Backend>(
-    block: &DubpBlockV10,
-    identities: &mut TxColRw<B::Col, GvaIdentitiesEvent>,
-) -> KvResult<()> {
-    for mb in block.joiners() {
-        let pubkey = mb.issuers()[0];
-
-        let mut idty = identities.get(&PubKeyKeyV2(pubkey))?.unwrap_or_default();
-        idty.is_member = false;
-        idty.joins.pop();
-        identities.upsert(PubKeyKeyV2(pubkey), idty);
-    }
-    for idty in block.identities() {
-        let pubkey = idty.issuers()[0];
-        identities.remove(PubKeyKeyV2(pubkey));
-    }
-    for revo in block.revoked() {
-        let pubkey = revo.issuer;
-        if let Some(mut idty) = identities.get(&PubKeyKeyV2(pubkey))? {
-            idty.is_member = true;
-            idty.leaves.remove(&block.number());
-            identities.upsert(PubKeyKeyV2(pubkey), idty)
-        }
-    }
-    for pubkey in block.excluded().iter().copied() {
-        if let Some(mut idty) = identities.get(&PubKeyKeyV2(pubkey))? {
-            idty.is_member = true;
-            idty.leaves.remove(&block.number());
-            identities.upsert(PubKeyKeyV2(pubkey), idty)
-        }
-    }
-    Ok(())
-}
diff --git a/rust-libs/modules/gva/indexer/src/lib.rs b/rust-libs/modules/gva/indexer/src/lib.rs
deleted file mode 100644
index 333e1981e..000000000
--- a/rust-libs/modules/gva/indexer/src/lib.rs
+++ /dev/null
@@ -1,593 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-#![deny(
-    clippy::unwrap_used,
-    missing_copy_implementations,
-    trivial_casts,
-    trivial_numeric_casts,
-    unstable_features,
-    unused_import_braces
-)]
-
-mod identities;
-mod tx;
-mod utxos;
-
-use dubp::block::prelude::*;
-use dubp::common::crypto::hashs::Hash;
-use dubp::common::prelude::*;
-use dubp::documents::{
-    prelude::*, transaction::TransactionDocumentTrait, transaction::TransactionDocumentV10,
-};
-use dubp::wallet::prelude::*;
-use duniter_dbs::{
-    kv_typed::prelude::*, prelude::*, FileBackend, HashKeyV2, PubKeyKeyV2, SourceAmountValV2,
-    WalletConditionsV2,
-};
-use duniter_gva_db::*;
-use resiter::filter::Filter;
-use std::{
-    collections::{BTreeSet, HashMap},
-    path::Path,
-};
-
-static GVA_DB_RO: once_cell::sync::OnceCell<GvaV1DbRo<FileBackend>> =
-    once_cell::sync::OnceCell::new();
-static GVA_DB_RW: once_cell::sync::OnceCell<GvaV1Db<FileBackend>> =
-    once_cell::sync::OnceCell::new();
-
-pub fn get_gva_db_ro(profile_path_opt: Option<&Path>) -> &'static GvaV1DbRo<FileBackend> {
-    GVA_DB_RO.get_or_init(|| get_gva_db_rw(profile_path_opt).get_ro_handler())
-}
-pub fn get_gva_db_rw(profile_path_opt: Option<&Path>) -> &'static GvaV1Db<FileBackend> {
-    GVA_DB_RW.get_or_init(|| {
-        duniter_gva_db::GvaV1Db::<FileBackend>::open(FileBackend::gen_backend_conf(
-            "gva_v1",
-            profile_path_opt,
-        ))
-        .expect("Fail to open GVA DB")
-    })
-}
-
-pub struct UtxoV10<'s> {
-    pub id: UtxoIdV10,
-    pub amount: SourceAmount,
-    pub script: &'s WalletScriptV10,
-    pub written_block: BlockNumber,
-}
-
-pub fn apply_block<B: Backend>(block: &DubpBlockV10, gva_db: &GvaV1Db<B>) -> KvResult<()> {
-    let blockstamp = Blockstamp {
-        number: block.number(),
-        hash: block.hash(),
-    };
-    gva_db.write(|mut db| {
-        db.blocks_by_common_time
-            .upsert(U64BE(block.common_time()), block.number().0);
-        db.blockchain_time
-            .upsert(U32BE(block.number().0), block.common_time());
-        identities::update_identities::<B>(&block, &mut db.gva_identities)?;
-        if let Some(divident_amount) = block.dividend() {
-            db.blocks_with_ud.upsert(U32BE(blockstamp.number.0), ());
-            apply_ud::<B>(
-                blockstamp.number,
-                divident_amount,
-                &mut db.balances,
-                &mut db.gva_identities,
-            )?;
-        }
-        apply_block_txs::<B>(
-            &mut db,
-            blockstamp,
-            block.common_time() as i64,
-            block.transactions(),
-        )
-    })?;
-
-    Ok(())
-}
-
-pub fn revert_block<B: Backend>(block: &DubpBlockV10, gva_db: &GvaV1Db<B>) -> KvResult<()> {
-    gva_db.write(|mut db| {
-        db.blocks_by_common_time.remove(U64BE(block.common_time()));
-        db.blockchain_time.remove(U32BE(block.number().0));
-        identities::revert_identities::<B>(&block, &mut db.gva_identities)?;
-        if let Some(divident_amount) = block.dividend() {
-            db.blocks_with_ud.remove(U32BE(block.number().0));
-            revert_ud::<B>(
-                block.number(),
-                divident_amount,
-                &mut db.balances,
-                &mut db.gva_identities,
-            )?;
-        }
-
-        let mut scripts_hash = HashMap::with_capacity(block.transactions().len() * 3);
-        for tx in block.transactions() {
-            let tx_hash = tx.get_hash();
-            tx::revert_tx::<B>(block.number(), &mut db, &mut scripts_hash, &tx_hash)?.ok_or_else(
-                || {
-                    KvError::DbCorrupted(format!(
-                        "GVA: tx '{}' dont exist on txs history.",
-                        tx_hash,
-                    ))
-                },
-            )?;
-        }
-        db.txs_by_block.remove(U32BE(block.number().0));
-        Ok(())
-    })?;
-
-    Ok(())
-}
-
-fn apply_ud<B: Backend>(
-    block_number: BlockNumber,
-    divident_amount: SourceAmount,
-    balances: &mut TxColRw<B::Col, BalancesEvent>,
-    identities: &mut TxColRw<B::Col, GvaIdentitiesEvent>,
-) -> KvResult<()> {
-    let members = identities.iter(.., |it| {
-        it.filter_ok(|(_pk, idty)| idty.is_member)
-            .collect::<KvResult<Vec<_>>>()
-    })?;
-    for (pk, mut idty) in members {
-        if idty.first_ud.is_none() {
-            idty.first_ud = Some(block_number);
-            identities.upsert(pk, idty);
-        }
-
-        // Increase account balance
-        let account_script = WalletScriptV10::single_sig(pk.0);
-        let balance = balances
-            .get(WalletConditionsV2::from_ref(&account_script))?
-            .unwrap_or_default();
-        balances.upsert(
-            WalletConditionsV2(account_script),
-            SourceAmountValV2(balance.0 + divident_amount),
-        );
-    }
-    Ok(())
-}
-
-fn revert_ud<B: Backend>(
-    block_number: BlockNumber,
-    divident_amount: SourceAmount,
-    balances: &mut TxColRw<B::Col, BalancesEvent>,
-    identities: &mut TxColRw<B::Col, GvaIdentitiesEvent>,
-) -> KvResult<()> {
-    let members = identities.iter(.., |it| {
-        it.filter_ok(|(_pk, idty)| idty.is_member)
-            .collect::<KvResult<Vec<_>>>()
-    })?;
-    for (pk, mut idty) in members {
-        if let Some(first_ud) = idty.first_ud {
-            if first_ud == block_number {
-                idty.first_ud = None;
-                identities.upsert(pk, idty);
-            }
-        }
-
-        // Increase account balance
-        let account_script = WalletScriptV10::single_sig(pk.0);
-        if let Some(SourceAmountValV2(balance)) =
-            balances.get(WalletConditionsV2::from_ref(&account_script))?
-        {
-            balances.upsert(
-                WalletConditionsV2(account_script),
-                SourceAmountValV2(balance - divident_amount),
-            );
-        }
-    }
-    Ok(())
-}
-
-fn apply_block_txs<B: Backend>(
-    gva_db: &mut GvaV1DbTxRw<B::Col>,
-    current_blockstamp: Blockstamp,
-    current_time: i64,
-    txs: &[TransactionDocumentV10],
-) -> KvResult<()> {
-    let mut scripts_index = HashMap::new();
-    let mut txs_by_issuer_mem = HashMap::new();
-    let mut txs_by_recipient_mem = HashMap::new();
-    let mut txs_hashes = Vec::with_capacity(txs.len());
-    for tx in txs {
-        let tx_hash = tx.get_hash();
-        txs_hashes.push(tx_hash);
-        // Write tx and update sources
-        tx::apply_tx::<B>(
-            current_blockstamp,
-            current_time,
-            gva_db,
-            &mut scripts_index,
-            tx_hash,
-            tx,
-            &mut txs_by_issuer_mem,
-            &mut txs_by_recipient_mem,
-        )?;
-    }
-
-    if !txs_hashes.is_empty() {
-        gva_db
-            .txs_by_block
-            .upsert(U32BE(current_blockstamp.number.0), txs_hashes);
-    }
-    for (k, v) in txs_by_issuer_mem {
-        gva_db.txs_by_issuer.upsert(k, v);
-    }
-    for (k, v) in txs_by_recipient_mem {
-        gva_db.txs_by_recipient.upsert(k, v);
-    }
-    Ok(())
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use dubp::{
-        crypto::keys::{ed25519::PublicKey, PublicKey as _},
-        documents::transaction::TransactionDocumentV10Stringified,
-        documents_parser::prelude::FromStringObject,
-    };
-
-    #[test]
-    fn test_gva_apply_block() -> anyhow::Result<()> {
-        let gva_db = GvaV1Db::<Mem>::open(MemConf::default())?;
-
-        let s1 = WalletScriptV10::single_sig(PublicKey::from_base58(
-            "D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx",
-        )?);
-        let s2 = WalletScriptV10::single_sig(PublicKey::from_base58(
-            "4fHMTFBMo5sTQEc5p1CNWz28S4mnnqdUBmECq1zt4n2m",
-        )?);
-
-        let b0 = DubpBlockV10::from_string_object(&DubpBlockV10Stringified {
-            version: 10,
-            median_time: 5_243,
-            dividend: Some(1000),
-            joiners: vec!["D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx:FFeyrvYio9uYwY5aMcDGswZPNjGLrl8THn9l3EPKSNySD3SDSHjCljSfFEwb87sroyzJQoVzPwER0sW/cbZMDg==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:elois".to_owned()],
-            inner_hash: Some("0000000A65A12DB95B3153BCD05DB4D5C30CC7F0B1292D9FFBC3DE67F72F6040".to_owned()),
-            signature: "7B0hvcfajE2G8nBLp0vLVaQcQdQIyli21Gu8F2l+nimKHRe+fUNi+MWd1e/u29BYZa+RZ1yxhbHIbFzytg7fAA==".to_owned(),
-            hash: Some("0000000000000000000000000000000000000000000000000000000000000000".to_owned()),
-            ..Default::default()
-        })?;
-
-        apply_block(&b0, &gva_db)?;
-
-        assert_eq!(gva_db.blocks_by_common_time().count()?, 1);
-        assert_eq!(gva_db.blocks_by_common_time().get(&U64BE(5_243))?, Some(0));
-        assert_eq!(gva_db.blockchain_time().count()?, 1);
-        assert_eq!(gva_db.blockchain_time().get(&U32BE(0))?, Some(5_243));
-        assert_eq!(gva_db.balances().count()?, 1);
-        assert_eq!(
-            gva_db.balances().get(&WalletConditionsV2(s1.clone()))?,
-            Some(SourceAmountValV2(SourceAmount::with_base0(1000)))
-        );
-        assert_eq!(gva_db.txs_by_block().count()?, 0);
-
-        let b1 = DubpBlockV10::from_string_object(&DubpBlockV10Stringified {
-            number: 1,
-            version: 10,
-            median_time: 5_245,
-            transactions: vec![TransactionDocumentV10Stringified {
-                currency: "test".to_owned(),
-                blockstamp: "0-0000000000000000000000000000000000000000000000000000000000000000".to_owned(),
-                locktime: 0,
-                issuers: vec!["D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx".to_owned()],
-                inputs: vec!["1000:0:D:D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx:0".to_owned()],
-                unlocks: vec![],
-                outputs: vec![
-                    "600:0:SIG(4fHMTFBMo5sTQEc5p1CNWz28S4mnnqdUBmECq1zt4n2m)".to_owned(),
-                    "400:0:SIG(D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx)".to_owned(),
-                ],
-                comment: "".to_owned(),
-                signatures: vec![],
-                hash: Some("0000000000000000000000000000000000000000000000000000000000000000".to_owned()),
-            }],
-            inner_hash: Some("0000000A65A12DB95B3153BCD05DB4D5C30CC7F0B1292D9FFBC3DE67F72F6040".to_owned()),
-            signature: "7B0hvcfajE2G8nBLp0vLVaQcQdQIyli21Gu8F2l+nimKHRe+fUNi+MWd1e/u29BYZa+RZ1yxhbHIbFzytg7fAA==".to_owned(),
-            hash: Some("0000000000000000000000000000000000000000000000000000000000000000".to_owned()),
-            ..Default::default()
-        })?;
-
-        apply_block(&b1, &gva_db)?;
-
-        assert_eq!(gva_db.blocks_by_common_time().count()?, 2);
-        assert_eq!(gva_db.blocks_by_common_time().get(&U64BE(5_245))?, Some(1));
-        assert_eq!(gva_db.blockchain_time().count()?, 2);
-        assert_eq!(gva_db.blockchain_time().get(&U32BE(1))?, Some(5_245));
-        assert_eq!(gva_db.balances().count()?, 2);
-        assert_eq!(
-            gva_db.balances().get(&WalletConditionsV2(s2.clone()))?,
-            Some(SourceAmountValV2(SourceAmount::with_base0(600)))
-        );
-        assert_eq!(
-            gva_db.balances().get(&WalletConditionsV2(s1.clone()))?,
-            Some(SourceAmountValV2(SourceAmount::with_base0(400)))
-        );
-        assert_eq!(gva_db.gva_utxos().count()?, 2);
-        assert_eq!(
-            gva_db
-                .gva_utxos()
-                .iter(.., |it| it.collect::<KvResult<Vec<_>>>())?,
-            vec![
-                (
-                    GvaUtxoIdDbV1::new(s1.clone(), 1, Hash::default(), 1),
-                    SourceAmountValV2(SourceAmount::with_base0(400))
-                ),
-                (
-                    GvaUtxoIdDbV1::new(s2.clone(), 1, Hash::default(), 0),
-                    SourceAmountValV2(SourceAmount::with_base0(600))
-                ),
-            ]
-        );
-        assert_eq!(gva_db.txs_by_block().count()?, 1);
-        assert_eq!(
-            gva_db.txs_by_block().get(&U32BE(1))?,
-            Some(vec![Hash::from_hex(
-                "0000000000000000000000000000000000000000000000000000000000000000"
-            )?])
-        );
-
-        let b2 = DubpBlockV10::from_string_object(&DubpBlockV10Stringified {
-            number: 2,
-            version: 10,
-            median_time: 5_247,
-            transactions: vec![TransactionDocumentV10Stringified {
-                currency: "test".to_owned(),
-                blockstamp: "0-0000000000000000000000000000000000000000000000000000000000000000".to_owned(),
-                locktime: 0,
-                issuers: vec!["D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx".to_owned()],
-                inputs: vec!["400:0:T:0000000000000000000000000000000000000000000000000000000000000000:1".to_owned()],
-                unlocks: vec![],
-                outputs: vec![
-                    "300:0:SIG(D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx)".to_owned(),
-                    "100:0:SIG(4fHMTFBMo5sTQEc5p1CNWz28S4mnnqdUBmECq1zt4n2m)".to_owned(),
-                ],
-                comment: "".to_owned(),
-                signatures: vec![],
-                hash: Some("0101010101010101010101010101010101010101010101010101010101010101".to_owned()),
-            }],
-            inner_hash: Some("0000000A65A12DB95B3153BCD05DB4D5C30CC7F0B1292D9FFBC3DE67F72F6040".to_owned()),
-            signature: "7B0hvcfajE2G8nBLp0vLVaQcQdQIyli21Gu8F2l+nimKHRe+fUNi+MWd1e/u29BYZa+RZ1yxhbHIbFzytg7fAA==".to_owned(),
-            hash: Some("0000000000000000000000000000000000000000000000000000000000000000".to_owned()),
-            ..Default::default()
-        })?;
-
-        apply_block(&b2, &gva_db)?;
-
-        assert_eq!(gva_db.blocks_by_common_time().count()?, 3);
-        assert_eq!(gva_db.blocks_by_common_time().get(&U64BE(5_247))?, Some(2));
-        assert_eq!(gva_db.blockchain_time().count()?, 3);
-        assert_eq!(gva_db.blockchain_time().get(&U32BE(2))?, Some(5_247));
-        assert_eq!(gva_db.balances().count()?, 2);
-        assert_eq!(
-            gva_db.balances().get(&WalletConditionsV2(s2.clone()))?,
-            Some(SourceAmountValV2(SourceAmount::with_base0(700)))
-        );
-        assert_eq!(
-            gva_db.balances().get(&WalletConditionsV2(s1.clone()))?,
-            Some(SourceAmountValV2(SourceAmount::with_base0(300)))
-        );
-        assert_eq!(gva_db.gva_utxos().count()?, 3);
-        assert_eq!(
-            gva_db
-                .gva_utxos()
-                .iter(.., |it| it.collect::<KvResult<Vec<_>>>())?,
-            vec![
-                (
-                    GvaUtxoIdDbV1::new(s1, 2, Hash([1; 32]), 0),
-                    SourceAmountValV2(SourceAmount::with_base0(300))
-                ),
-                (
-                    GvaUtxoIdDbV1::new(s2.clone(), 1, Hash::default(), 0),
-                    SourceAmountValV2(SourceAmount::with_base0(600))
-                ),
-                (
-                    GvaUtxoIdDbV1::new(s2, 2, Hash([1; 32]), 1),
-                    SourceAmountValV2(SourceAmount::with_base0(100))
-                ),
-            ]
-        );
-        assert_eq!(gva_db.txs_by_block().count()?, 2);
-        assert_eq!(
-            gva_db.txs_by_block().get(&U32BE(2))?,
-            Some(vec![Hash::from_hex(
-                "0101010101010101010101010101010101010101010101010101010101010101"
-            )?])
-        );
-
-        Ok(())
-    }
-
-    #[test]
-    fn test_gva_revert_block() -> anyhow::Result<()> {
-        let gva_db = GvaV1Db::<Mem>::open(MemConf::default())?;
-
-        let s1 = WalletScriptV10::single_sig(PublicKey::from_base58(
-            "D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx",
-        )?);
-        let s2 = WalletScriptV10::single_sig(PublicKey::from_base58(
-            "4fHMTFBMo5sTQEc5p1CNWz28S4mnnqdUBmECq1zt4n2m",
-        )?);
-
-        let b0 = DubpBlockV10::from_string_object(&DubpBlockV10Stringified {
-            version: 10,
-            median_time: 5_243,
-            dividend: Some(1000),
-            joiners: vec!["D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx:FFeyrvYio9uYwY5aMcDGswZPNjGLrl8THn9l3EPKSNySD3SDSHjCljSfFEwb87sroyzJQoVzPwER0sW/cbZMDg==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:elois".to_owned()],
-            inner_hash: Some("0000000A65A12DB95B3153BCD05DB4D5C30CC7F0B1292D9FFBC3DE67F72F6040".to_owned()),
-            signature: "7B0hvcfajE2G8nBLp0vLVaQcQdQIyli21Gu8F2l+nimKHRe+fUNi+MWd1e/u29BYZa+RZ1yxhbHIbFzytg7fAA==".to_owned(),
-            hash: Some("0000000000000000000000000000000000000000000000000000000000000000".to_owned()),
-            ..Default::default()
-        })?;
-
-        apply_block(&b0, &gva_db)?;
-
-        let b1 = DubpBlockV10::from_string_object(&DubpBlockV10Stringified {
-            number: 1,
-            version: 10,
-            median_time: 5_245,
-            transactions: vec![TransactionDocumentV10Stringified {
-                currency: "test".to_owned(),
-                blockstamp: "0-0000000000000000000000000000000000000000000000000000000000000000".to_owned(),
-                locktime: 0,
-                issuers: vec!["D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx".to_owned()],
-                inputs: vec!["1000:0:D:D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx:0".to_owned()],
-                unlocks: vec![],
-                outputs: vec![
-                    "600:0:SIG(4fHMTFBMo5sTQEc5p1CNWz28S4mnnqdUBmECq1zt4n2m)".to_owned(),
-                    "400:0:SIG(D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx)".to_owned(),
-                ],
-                comment: "".to_owned(),
-                signatures: vec![],
-                hash: Some("0000000000000000000000000000000000000000000000000000000000000000".to_owned()),
-            }],
-            inner_hash: Some("0000000A65A12DB95B3153BCD05DB4D5C30CC7F0B1292D9FFBC3DE67F72F6040".to_owned()),
-            signature: "7B0hvcfajE2G8nBLp0vLVaQcQdQIyli21Gu8F2l+nimKHRe+fUNi+MWd1e/u29BYZa+RZ1yxhbHIbFzytg7fAA==".to_owned(),
-            hash: Some("0000000000000000000000000000000000000000000000000000000000000000".to_owned()),
-            ..Default::default()
-        })?;
-
-        apply_block(&b1, &gva_db)?;
-
-        let b2 = DubpBlockV10::from_string_object(&DubpBlockV10Stringified {
-            number: 2,
-            version: 10,
-            median_time: 5_247,
-            transactions: vec![TransactionDocumentV10Stringified {
-                currency: "test".to_owned(),
-                blockstamp: "0-0000000000000000000000000000000000000000000000000000000000000000".to_owned(),
-                locktime: 0,
-                issuers: vec!["D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx".to_owned()],
-                inputs: vec!["400:0:T:0000000000000000000000000000000000000000000000000000000000000000:1".to_owned()],
-                unlocks: vec![],
-                outputs: vec![
-                    "400:0:SIG(4fHMTFBMo5sTQEc5p1CNWz28S4mnnqdUBmECq1zt4n2m)".to_owned(),
-                ],
-                comment: "".to_owned(),
-                signatures: vec![],
-                hash: Some("0101010101010101010101010101010101010101010101010101010101010101".to_owned()),
-            }],
-            inner_hash: Some("0000000A65A12DB95B3153BCD05DB4D5C30CC7F0B1292D9FFBC3DE67F72F6040".to_owned()),
-            signature: "7B0hvcfajE2G8nBLp0vLVaQcQdQIyli21Gu8F2l+nimKHRe+fUNi+MWd1e/u29BYZa+RZ1yxhbHIbFzytg7fAA==".to_owned(),
-            hash: Some("0000000000000000000000000000000000000000000000000000000000000000".to_owned()),
-            ..Default::default()
-        })?;
-
-        apply_block(&b2, &gva_db)?;
-
-        let b3 = DubpBlockV10::from_string_object(&DubpBlockV10Stringified {
-            number: 3,
-            version: 10,
-            median_time: 5_249,
-            transactions: vec![TransactionDocumentV10Stringified {
-                currency: "test".to_owned(),
-                blockstamp: "0-0000000000000000000000000000000000000000000000000000000000000000".to_owned(),
-                locktime: 0,
-                issuers: vec!["4fHMTFBMo5sTQEc5p1CNWz28S4mnnqdUBmECq1zt4n2m".to_owned()],
-                inputs: vec!["400:0:T:0101010101010101010101010101010101010101010101010101010101010101:0".to_owned()],
-                unlocks: vec![],
-                outputs: vec![
-                    "400:0:SIG(D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx)".to_owned(),
-                ],
-                comment: "".to_owned(),
-                signatures: vec![],
-                hash: Some("0202020202020202020202020202020202020202020202020202020202020202".to_owned()),
-            }],
-            inner_hash: Some("0000000A65A12DB95B3153BCD05DB4D5C30CC7F0B1292D9FFBC3DE67F72F6040".to_owned()),
-            signature: "7B0hvcfajE2G8nBLp0vLVaQcQdQIyli21Gu8F2l+nimKHRe+fUNi+MWd1e/u29BYZa+RZ1yxhbHIbFzytg7fAA==".to_owned(),
-            hash: Some("0000000000000000000000000000000000000000000000000000000000000000".to_owned()),
-            ..Default::default()
-        })?;
-
-        apply_block(&b3, &gva_db)?;
-
-        revert_block(&b3, &gva_db)?;
-
-        assert_eq!(gva_db.blockchain_time().count()?, 3);
-        assert_eq!(gva_db.blockchain_time().get(&U32BE(2))?, Some(5_247));
-        assert_eq!(gva_db.balances().count()?, 2);
-        assert_eq!(
-            gva_db.balances().get(&WalletConditionsV2(s1.clone()))?,
-            Some(SourceAmountValV2(SourceAmount::ZERO))
-        );
-        assert_eq!(
-            gva_db.balances().get(&WalletConditionsV2(s2.clone()))?,
-            Some(SourceAmountValV2(SourceAmount::with_base0(1_000)))
-        );
-        assert_eq!(gva_db.gva_utxos().count()?, 2);
-        assert_eq!(
-            gva_db
-                .gva_utxos()
-                .iter(.., |it| it.collect::<KvResult<Vec<_>>>())?,
-            vec![
-                (
-                    GvaUtxoIdDbV1::new(s2.clone(), 1, Hash::default(), 0),
-                    SourceAmountValV2(SourceAmount::with_base0(600))
-                ),
-                (
-                    GvaUtxoIdDbV1::new(s2.clone(), 2, Hash([1u8; 32]), 0),
-                    SourceAmountValV2(SourceAmount::with_base0(400))
-                ),
-            ]
-        );
-
-        revert_block(&b2, &gva_db)?;
-
-        assert_eq!(gva_db.blockchain_time().count()?, 2);
-        assert_eq!(gva_db.blockchain_time().get(&U32BE(1))?, Some(5_245));
-        assert_eq!(gva_db.balances().count()?, 2);
-        assert_eq!(
-            gva_db.balances().get(&WalletConditionsV2(s2.clone()))?,
-            Some(SourceAmountValV2(SourceAmount::with_base0(600)))
-        );
-        assert_eq!(
-            gva_db.balances().get(&WalletConditionsV2(s1.clone()))?,
-            Some(SourceAmountValV2(SourceAmount::with_base0(400)))
-        );
-        assert_eq!(gva_db.gva_utxos().count()?, 2);
-        assert_eq!(
-            gva_db
-                .gva_utxos()
-                .iter(.., |it| it.collect::<KvResult<Vec<_>>>())?,
-            vec![
-                (
-                    GvaUtxoIdDbV1::new(s1.clone(), 1, Hash::default(), 1),
-                    SourceAmountValV2(SourceAmount::with_base0(400))
-                ),
-                (
-                    GvaUtxoIdDbV1::new(s2.clone(), 1, Hash::default(), 0),
-                    SourceAmountValV2(SourceAmount::with_base0(600))
-                ),
-            ]
-        );
-
-        revert_block(&b1, &gva_db)?;
-
-        assert_eq!(gva_db.blockchain_time().count()?, 1);
-        assert_eq!(gva_db.blockchain_time().get(&U32BE(0))?, Some(5_243));
-        assert_eq!(gva_db.balances().count()?, 1);
-        assert_eq!(
-            gva_db.balances().get(&WalletConditionsV2(s1))?,
-            Some(SourceAmountValV2(SourceAmount::with_base0(1000)))
-        );
-        assert_eq!(gva_db.balances().get(&WalletConditionsV2(s2))?, None);
-
-        Ok(())
-    }
-}
diff --git a/rust-libs/modules/gva/indexer/src/tx.rs b/rust-libs/modules/gva/indexer/src/tx.rs
deleted file mode 100644
index 709ebd557..000000000
--- a/rust-libs/modules/gva/indexer/src/tx.rs
+++ /dev/null
@@ -1,514 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-pub(crate) type ScriptsHash = HashMap<WalletScriptV10, Hash>;
-
-fn get_script_hash(script: &WalletScriptV10, scripts_hash: &mut ScriptsHash) -> Hash {
-    if let Some(script_hash) = scripts_hash.get(script) {
-        *script_hash
-    } else {
-        let script_hash = Hash::compute(script.to_string().as_bytes());
-        scripts_hash.insert(script.clone(), script_hash);
-        script_hash
-    }
-}
-
-#[allow(clippy::too_many_arguments)]
-pub(crate) fn apply_tx<B: Backend>(
-    current_blockstamp: Blockstamp,
-    current_time: i64,
-    gva_db: &mut GvaV1DbTxRw<B::Col>,
-    scripts_hash: &mut ScriptsHash,
-    tx_hash: Hash,
-    tx: &TransactionDocumentV10,
-    txs_by_issuer_mem: &mut HashMap<WalletHashWithBnV1Db, BTreeSet<Hash>>,
-    txs_by_recipient_mem: &mut HashMap<WalletHashWithBnV1Db, BTreeSet<Hash>>,
-) -> KvResult<()> {
-    let mut issuers_scripts_hashs = BTreeSet::new();
-    for input in tx.get_inputs() {
-        let (account_script_hash, account_script) = match input.id {
-            SourceIdV10::Utxo(utxo_id) => {
-                // Get issuer script & written block
-                let db_tx_origin = gva_db
-                    .txs
-                    .get(&HashKeyV2::from_ref(&utxo_id.tx_hash))?
-                    .ok_or_else(|| {
-                        KvError::DbCorrupted(format!("Not found origin tx of uxto {}", utxo_id))
-                    })?;
-                let utxo_script = db_tx_origin.tx.get_outputs()[utxo_id.output_index]
-                    .conditions
-                    .script
-                    .clone();
-                let utxo_script_hash = get_script_hash(&utxo_script, scripts_hash);
-
-                // Remove consumed UTXOs
-                super::utxos::remove_utxo_v10::<B>(
-                    &mut gva_db.scripts_by_pubkey,
-                    &mut gva_db.gva_utxos,
-                    utxo_id,
-                    &utxo_script,
-                    utxo_script_hash,
-                    db_tx_origin.written_block.number.0,
-                )?;
-
-                // Return utxo_script with hash
-                (utxo_script_hash, utxo_script)
-            }
-            SourceIdV10::Ud(UdSourceIdV10 { issuer, .. }) => {
-                let script = WalletScriptV10::single_sig(issuer);
-                (Hash::compute(script.to_string().as_bytes()), script)
-            }
-        };
-        issuers_scripts_hashs.insert(account_script_hash);
-        // Insert on col `txs_by_issuer`
-        txs_by_issuer_mem
-            .entry(WalletHashWithBnV1Db::new(
-                account_script_hash,
-                current_blockstamp.number,
-            ))
-            .or_default()
-            .insert(tx_hash);
-        // Decrease account balance
-        decrease_account_balance::<B>(
-            account_script,
-            account_script_hash,
-            &mut gva_db.balances,
-            input.amount,
-            &mut gva_db.gva_identities,
-            false,
-            &mut gva_db.txs_by_recipient,
-        )?;
-    }
-
-    for (output_index, output) in tx.get_outputs().iter().enumerate() {
-        let utxo_script_hash = get_script_hash(&output.conditions.script, scripts_hash);
-        // Insert created UTXOs
-        super::utxos::write_utxo_v10::<B>(
-            &mut gva_db.scripts_by_pubkey,
-            &mut gva_db.gva_utxos,
-            UtxoV10 {
-                id: UtxoIdV10 {
-                    tx_hash,
-                    output_index,
-                },
-                amount: output.amount,
-                script: &output.conditions.script,
-                written_block: current_blockstamp.number,
-            },
-            utxo_script_hash,
-        )?;
-
-        // Insert on col `txs_by_recipient`
-        if !issuers_scripts_hashs.contains(&utxo_script_hash) {
-            txs_by_recipient_mem
-                .entry(WalletHashWithBnV1Db::new(
-                    utxo_script_hash,
-                    current_blockstamp.number,
-                ))
-                .or_default()
-                .insert(tx_hash);
-        }
-
-        // Increase account balance
-        let balance = gva_db
-            .balances
-            .get(WalletConditionsV2::from_ref(&output.conditions.script))?
-            .unwrap_or_default();
-        gva_db.balances.upsert(
-            WalletConditionsV2(output.conditions.script.clone()),
-            SourceAmountValV2(balance.0 + output.amount),
-        );
-    }
-
-    // Insert tx itself
-    gva_db.txs.upsert(
-        HashKeyV2(tx_hash),
-        GvaTxDbV1 {
-            tx: tx.clone(),
-            written_block: current_blockstamp,
-            written_time: current_time,
-        },
-    );
-
-    Ok(())
-}
-
-pub(crate) fn revert_tx<B: Backend>(
-    block_number: BlockNumber,
-    gva_db: &mut GvaV1DbTxRw<B::Col>,
-    scripts_hash: &mut ScriptsHash,
-    tx_hash: &Hash,
-) -> KvResult<Option<TransactionDocumentV10>> {
-    if let Some(tx_db) = gva_db.txs.get(&HashKeyV2::from_ref(tx_hash))? {
-        use dubp::documents::transaction::TransactionDocumentTrait as _;
-        for (output_index, output) in tx_db.tx.get_outputs().iter().enumerate() {
-            let script = &output.conditions.script;
-            let utxo_script_hash = get_script_hash(&script, scripts_hash);
-
-            // Remove UTXOs created by this tx
-            super::utxos::remove_utxo_v10::<B>(
-                &mut gva_db.scripts_by_pubkey,
-                &mut gva_db.gva_utxos,
-                UtxoIdV10 {
-                    tx_hash: *tx_hash,
-                    output_index,
-                },
-                script,
-                utxo_script_hash,
-                block_number.0,
-            )?;
-
-            // Remove on col `txs_by_recipient`
-            let k = WalletHashWithBnV1Db::new(utxo_script_hash, block_number);
-            gva_db.txs_by_recipient.remove(k);
-
-            // Decrease account balance
-            decrease_account_balance::<B>(
-                script.clone(),
-                utxo_script_hash,
-                &mut gva_db.balances,
-                output.amount,
-                &mut gva_db.gva_identities,
-                true,
-                &mut gva_db.txs_by_recipient,
-            )?;
-        }
-        // Recreate UTXOs consumed by this tx (and update balance)
-        for input in tx_db.tx.get_inputs() {
-            let (account_script_hash, account_script) = match input.id {
-                SourceIdV10::Utxo(utxo_id) => {
-                    let db_tx_origin = gva_db
-                        .txs
-                        .get(&HashKeyV2::from_ref(&utxo_id.tx_hash))?
-                        .ok_or_else(|| {
-                            KvError::DbCorrupted(format!("Not found origin tx of uxto {}", utxo_id))
-                        })?;
-                    let utxo_script = db_tx_origin.tx.get_outputs()[utxo_id.output_index]
-                        .conditions
-                        .script
-                        .clone();
-                    let utxo_script_hash = get_script_hash(&utxo_script, scripts_hash);
-                    super::utxos::write_utxo_v10::<B>(
-                        &mut gva_db.scripts_by_pubkey,
-                        &mut gva_db.gva_utxos,
-                        UtxoV10 {
-                            id: utxo_id,
-                            amount: input.amount,
-                            script: &utxo_script,
-                            written_block: db_tx_origin.written_block.number,
-                        },
-                        utxo_script_hash,
-                    )?;
-
-                    // Return utxo_script
-                    (utxo_script_hash, utxo_script)
-                }
-                SourceIdV10::Ud(UdSourceIdV10 { issuer, .. }) => {
-                    let script = WalletScriptV10::single_sig(issuer);
-                    (Hash::compute(script.to_string().as_bytes()), script)
-                }
-            };
-            // Remove on col `txs_by_issuer`
-            gva_db
-                .txs_by_issuer
-                .remove(WalletHashWithBnV1Db::new(account_script_hash, block_number));
-            // Increase account balance
-            let balance = gva_db
-                .balances
-                .get(WalletConditionsV2::from_ref(&account_script))?
-                .unwrap_or_default();
-
-            gva_db.balances.upsert(
-                WalletConditionsV2(account_script),
-                SourceAmountValV2(balance.0 + input.amount),
-            );
-        }
-
-        // Remove tx itself
-        gva_db.txs.remove(HashKeyV2(*tx_hash));
-
-        Ok(Some(tx_db.tx))
-    } else {
-        Ok(None)
-    }
-}
-
-fn decrease_account_balance<B: Backend>(
-    account_script: WalletScriptV10,
-    account_script_hash: Hash,
-    balances: &mut TxColRw<B::Col, BalancesEvent>,
-    decrease_amount: SourceAmount,
-    identities: &mut TxColRw<B::Col, GvaIdentitiesEvent>,
-    revert: bool,
-    txs_by_recipients: &mut TxColRw<B::Col, TxsByRecipientEvent>,
-) -> KvResult<()> {
-    if let Some(SourceAmountValV2(balance)) =
-        balances.get(WalletConditionsV2::from_ref(&account_script))?
-    {
-        let new_balance = balance - decrease_amount;
-        let remove_balance = if revert && new_balance == SourceAmount::ZERO {
-            let (k_min, k_max) = WalletHashWithBnV1Db::wallet_hash_interval(account_script_hash);
-            if txs_by_recipients
-                .iter(k_min..k_max, |it| it.keys().next_res())?
-                .is_some()
-            {
-                false
-            } else if let Some(pubkey) = account_script.as_single_sig() {
-                if let Some(idty) = identities.get(&PubKeyKeyV2(pubkey))? {
-                    idty.first_ud.is_none()
-                } else {
-                    true
-                }
-            } else {
-                true
-            }
-        } else {
-            false
-        };
-        if remove_balance {
-            balances.remove(WalletConditionsV2(account_script));
-        } else {
-            balances.upsert(
-                WalletConditionsV2(account_script),
-                SourceAmountValV2(new_balance),
-            );
-        }
-    }
-    Ok(())
-}
-
-#[cfg(test)]
-mod tests {
-
-    use super::*;
-    use dubp::{
-        crypto::keys::ed25519::Ed25519KeyPair, crypto::keys::KeyPair as _,
-        documents::smallvec::smallvec as svec, documents::transaction::v10::*,
-        documents::transaction::UTXOConditions,
-    };
-    use duniter_dbs::BlockMetaV2;
-    use maplit::btreeset;
-
-    #[test]
-    fn test_apply_tx() -> KvResult<()> {
-        let kp = Ed25519KeyPair::generate_random().expect("gen rand kp");
-        let kp2 = Ed25519KeyPair::generate_random().expect("gen rand kp");
-
-        let ud0_amount = SourceAmount::with_base0(1000);
-        let o1_amount = ud0_amount - SourceAmount::with_base0(600);
-        let o2_amount = ud0_amount - SourceAmount::with_base0(400);
-
-        let gva_db = GvaV1Db::<Mem>::open(MemConf::default())?;
-
-        let b0 = BlockMetaV2 {
-            dividend: Some(ud0_amount),
-            ..Default::default()
-        };
-        let current_blockstamp = b0.blockstamp();
-        let pk = kp.public_key();
-        //println!("TMP pk1={}", pk);
-        let pk2 = kp2.public_key();
-        //println!("TMP pk2={}", pk2);
-        let script = WalletScriptV10::single_sig(pk);
-        let script2 = WalletScriptV10::single_sig(pk2);
-        let script_hash = Hash::compute(script.to_string().as_bytes());
-        let script2_hash = Hash::compute(script2.to_string().as_bytes());
-
-        gva_db.balances_write().upsert(
-            WalletConditionsV2(script.clone()),
-            SourceAmountValV2(ud0_amount),
-        )?;
-
-        let tx1 = TransactionDocumentV10Builder {
-            currency: "test",
-            blockstamp: current_blockstamp,
-            locktime: 0,
-            issuers: svec![pk],
-            inputs: &[TransactionInputV10 {
-                amount: ud0_amount,
-                id: SourceIdV10::Ud(UdSourceIdV10 {
-                    issuer: pk,
-                    block_number: BlockNumber(0),
-                }),
-            }],
-            unlocks: &[TransactionInputUnlocksV10::default()],
-            outputs: svec![
-                TransactionOutputV10 {
-                    amount: o1_amount,
-                    conditions: UTXOConditions::from(script2.clone()),
-                },
-                TransactionOutputV10 {
-                    amount: o2_amount,
-                    conditions: UTXOConditions::from(script.clone()),
-                }
-            ],
-            comment: "",
-            hash: None,
-        }
-        .build_and_sign(vec![kp.generate_signator()]);
-        let tx1_hash = tx1.get_hash();
-
-        let mut scripts_hash = HashMap::new();
-
-        let mut txs_by_issuer_mem = HashMap::new();
-        let mut txs_by_recipient_mem = HashMap::new();
-        (&gva_db).write(|mut db| {
-            apply_tx::<Mem>(
-                current_blockstamp,
-                b0.median_time as i64,
-                &mut db,
-                &mut scripts_hash,
-                tx1_hash,
-                &tx1,
-                &mut txs_by_issuer_mem,
-                &mut txs_by_recipient_mem,
-            )
-        })?;
-
-        assert_eq!(txs_by_issuer_mem.len(), 1);
-        assert_eq!(
-            txs_by_issuer_mem.get(&WalletHashWithBnV1Db::new(script_hash, BlockNumber(0))),
-            Some(&btreeset![tx1_hash])
-        );
-        assert_eq!(txs_by_recipient_mem.len(), 1);
-        assert_eq!(
-            txs_by_recipient_mem.get(&WalletHashWithBnV1Db::new(script2_hash, BlockNumber(0))),
-            Some(&btreeset![tx1_hash])
-        );
-
-        assert_eq!(
-            gva_db
-                .balances()
-                .get(WalletConditionsV2::from_ref(&script2))?,
-            Some(SourceAmountValV2(o1_amount))
-        );
-        assert_eq!(
-            gva_db
-                .balances()
-                .get(WalletConditionsV2::from_ref(&script))?,
-            Some(SourceAmountValV2(o2_amount))
-        );
-
-        let tx2 = TransactionDocumentV10Builder {
-            currency: "test",
-            blockstamp: current_blockstamp,
-            locktime: 0,
-            issuers: svec![pk2],
-            inputs: &[TransactionInputV10 {
-                amount: o1_amount,
-                id: SourceIdV10::Utxo(UtxoIdV10 {
-                    tx_hash: tx1_hash,
-                    output_index: 0,
-                }),
-            }],
-            unlocks: &[TransactionInputUnlocksV10::default()],
-            outputs: svec![TransactionOutputV10 {
-                amount: o1_amount,
-                conditions: UTXOConditions::from(script.clone()),
-            },],
-            comment: "",
-            hash: None,
-        }
-        .build_and_sign(vec![kp.generate_signator()]);
-        let tx2_hash = tx2.get_hash();
-
-        let mut txs_by_issuer_mem = HashMap::new();
-        let mut txs_by_recipient_mem = HashMap::new();
-        (&gva_db).write(|mut db| {
-            apply_tx::<Mem>(
-                current_blockstamp,
-                b0.median_time as i64,
-                &mut db,
-                &mut scripts_hash,
-                tx2_hash,
-                &tx2,
-                &mut txs_by_issuer_mem,
-                &mut txs_by_recipient_mem,
-            )
-        })?;
-
-        assert_eq!(txs_by_issuer_mem.len(), 1);
-        assert_eq!(
-            txs_by_issuer_mem.get(&WalletHashWithBnV1Db::new(script2_hash, BlockNumber(0))),
-            Some(&btreeset![tx2_hash])
-        );
-        assert_eq!(txs_by_recipient_mem.len(), 1);
-        assert_eq!(
-            txs_by_recipient_mem.get(&WalletHashWithBnV1Db::new(script_hash, BlockNumber(0))),
-            Some(&btreeset![tx2_hash])
-        );
-
-        assert_eq!(
-            gva_db
-                .balances()
-                .get(WalletConditionsV2::from_ref(&script2))?,
-            Some(SourceAmountValV2(SourceAmount::ZERO))
-        );
-        assert_eq!(
-            gva_db
-                .balances()
-                .get(WalletConditionsV2::from_ref(&script))?,
-            Some(SourceAmountValV2(ud0_amount))
-        );
-
-        (&gva_db).write(|mut db| {
-            revert_tx::<Mem>(
-                current_blockstamp.number,
-                &mut db,
-                &mut scripts_hash,
-                &tx2_hash,
-            )
-        })?;
-
-        assert_eq!(
-            gva_db
-                .balances()
-                .get(WalletConditionsV2::from_ref(&script2))?,
-            Some(SourceAmountValV2(o1_amount))
-        );
-        assert_eq!(
-            gva_db
-                .balances()
-                .get(WalletConditionsV2::from_ref(&script))?,
-            Some(SourceAmountValV2(o2_amount))
-        );
-
-        (&gva_db).write(|mut db| {
-            revert_tx::<Mem>(
-                current_blockstamp.number,
-                &mut db,
-                &mut scripts_hash,
-                &tx1_hash,
-            )
-        })?;
-
-        assert_eq!(
-            gva_db
-                .balances()
-                .get(WalletConditionsV2::from_ref(&script2))?,
-            None
-        );
-        assert_eq!(
-            gva_db
-                .balances()
-                .get(WalletConditionsV2::from_ref(&script))?,
-            Some(SourceAmountValV2(ud0_amount))
-        );
-
-        Ok(())
-    }
-}
diff --git a/rust-libs/modules/gva/indexer/src/utxos.rs b/rust-libs/modules/gva/indexer/src/utxos.rs
deleted file mode 100644
index 91ec82723..000000000
--- a/rust-libs/modules/gva/indexer/src/utxos.rs
+++ /dev/null
@@ -1,86 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-pub(crate) fn write_utxo_v10<'s, B: Backend>(
-    scripts_by_pubkey: &mut TxColRw<B::Col, ScriptsByPubkeyEvent>,
-    gva_utxos: &mut TxColRw<B::Col, GvaUtxosEvent>,
-    utxo: UtxoV10<'s>,
-    utxo_script_hash: Hash,
-) -> KvResult<()> {
-    for pubkey in utxo.script.pubkeys() {
-        let mut pubkey_scripts = scripts_by_pubkey
-            .get(&PubKeyKeyV2(pubkey))?
-            .unwrap_or_default();
-        if !pubkey_scripts.0.contains(&utxo.script) {
-            pubkey_scripts.0.insert(utxo.script.clone());
-            scripts_by_pubkey.upsert(PubKeyKeyV2(pubkey), pubkey_scripts);
-        }
-    }
-
-    let block_number = utxo.written_block.0;
-    let utxo_amount = utxo.amount;
-    let utxo_id = utxo.id;
-    gva_utxos.upsert(
-        GvaUtxoIdDbV1::new_(
-            utxo_script_hash,
-            block_number,
-            utxo_id.tx_hash,
-            utxo_id.output_index as u8,
-        ),
-        SourceAmountValV2(utxo_amount),
-    );
-
-    Ok(())
-}
-
-pub(crate) fn remove_utxo_v10<B: Backend>(
-    scripts_by_pubkey: &mut TxColRw<B::Col, ScriptsByPubkeyEvent>,
-    gva_utxos: &mut TxColRw<B::Col, GvaUtxosEvent>,
-    utxo_id: UtxoIdV10,
-    utxo_script: &WalletScriptV10,
-    utxo_script_hash: Hash,
-    written_block_number: u32,
-) -> KvResult<()> {
-    gva_utxos.remove(GvaUtxoIdDbV1::new_(
-        utxo_script_hash,
-        written_block_number,
-        utxo_id.tx_hash,
-        utxo_id.output_index as u8,
-    ));
-
-    let (k_min, k_max) = GvaUtxoIdDbV1::script_interval(utxo_script_hash);
-    if gva_utxos
-        .iter(k_min..k_max, |it| it.keys().next_res())?
-        .is_none()
-    {
-        let pubkeys = utxo_script.pubkeys();
-        for pubkey in pubkeys {
-            let mut pubkey_scripts =
-                scripts_by_pubkey
-                    .get(&PubKeyKeyV2(pubkey))?
-                    .ok_or_else(|| {
-                        KvError::DbCorrupted(format!(
-                            "GVA: key {} dont exist on col `scripts_by_pubkey`.",
-                            pubkey,
-                        ))
-                    })?;
-            pubkey_scripts.0.remove(utxo_script);
-            scripts_by_pubkey.upsert(PubKeyKeyV2(pubkey), pubkey_scripts);
-        }
-    }
-    Ok(())
-}
diff --git a/rust-libs/modules/gva/src/anti_spam.rs b/rust-libs/modules/gva/src/anti_spam.rs
deleted file mode 100644
index 30d2009ac..000000000
--- a/rust-libs/modules/gva/src/anti_spam.rs
+++ /dev/null
@@ -1,201 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-use async_mutex::Mutex;
-use duniter_dbs::kv_typed::prelude::Arc;
-use std::{
-    collections::{HashMap, HashSet},
-    net::IpAddr,
-    time::Duration,
-    time::Instant,
-};
-
-pub(super) const MAX_BATCH_SIZE: usize = 5;
-
-const COUNT_INTERVAL: usize = 10;
-const MIN_DURATION_INTERVAL: Duration = Duration::from_secs(20);
-const LARGE_DURATION_INTERVAL: Duration = Duration::from_secs(180);
-const REDUCED_COUNT_INTERVAL: usize = COUNT_INTERVAL / 2;
-const MAX_BAN_COUNT: usize = 16;
-const BAN_FORGET_MIN_DURATION: Duration = Duration::from_secs(180);
-
-#[derive(Clone)]
-pub(crate) struct AntiSpam {
-    state: Arc<Mutex<AntiSpamInner>>,
-    whitelist: HashSet<IpAddr>,
-}
-
-#[derive(Clone)]
-pub(crate) struct AntiSpamResponse {
-    pub is_whitelisted: bool,
-    pub is_ok: bool,
-}
-
-impl AntiSpamResponse {
-    fn ban() -> Self {
-        AntiSpamResponse {
-            is_whitelisted: false,
-            is_ok: false,
-        }
-    }
-    fn ok() -> Self {
-        AntiSpamResponse {
-            is_whitelisted: false,
-            is_ok: true,
-        }
-    }
-    fn whitelisted() -> Self {
-        AntiSpamResponse {
-            is_whitelisted: true,
-            is_ok: true,
-        }
-    }
-}
-
-struct AntiSpamInner {
-    ban: HashMap<IpAddr, (bool, usize, Instant)>,
-    ips_time: HashMap<IpAddr, (usize, Instant)>,
-}
-
-impl From<&GvaConf> for AntiSpam {
-    fn from(conf: &GvaConf) -> Self {
-        AntiSpam {
-            state: Arc::new(Mutex::new(AntiSpamInner {
-                ban: HashMap::with_capacity(10),
-                ips_time: HashMap::with_capacity(10),
-            })),
-            whitelist: conf.get_whitelist().iter().copied().collect(),
-        }
-    }
-}
-
-impl AntiSpam {
-    pub(crate) async fn verify(
-        &self,
-        remote_addr_opt: Option<std::net::IpAddr>,
-    ) -> AntiSpamResponse {
-        if let Some(ip) = remote_addr_opt {
-            log::trace!("GVA: receive request from {}", ip);
-            if self.whitelist.contains(&ip) {
-                AntiSpamResponse::whitelisted()
-            } else {
-                let mut guard = self.state.lock().await;
-                if let Some((is_banned, ban_count, instant)) = guard.ban.get(&ip).copied() {
-                    let ban_duration =
-                        Duration::from_secs(1 << std::cmp::min(ban_count, MAX_BAN_COUNT));
-                    if is_banned {
-                        if Instant::now().duration_since(instant) > ban_duration {
-                            guard.ban.insert(ip, (false, ban_count + 1, Instant::now()));
-                            guard.ips_time.insert(ip, (1, Instant::now()));
-                            AntiSpamResponse::ok()
-                        } else {
-                            guard.ban.insert(ip, (true, ban_count + 1, Instant::now()));
-                            AntiSpamResponse::ban()
-                        }
-                    } else if Instant::now().duration_since(instant)
-                        > std::cmp::max(ban_duration, BAN_FORGET_MIN_DURATION)
-                    {
-                        guard.ban.remove(&ip);
-                        guard.ips_time.insert(ip, (1, Instant::now()));
-                        AntiSpamResponse::ok()
-                    } else {
-                        Self::verify_interval(ip, &mut guard, ban_count)
-                    }
-                } else {
-                    Self::verify_interval(ip, &mut guard, 0)
-                }
-            }
-        } else {
-            AntiSpamResponse::ban()
-        }
-    }
-    fn verify_interval(
-        ip: IpAddr,
-        state: &mut AntiSpamInner,
-        ban_count: usize,
-    ) -> AntiSpamResponse {
-        if let Some((count, instant)) = state.ips_time.get(&ip).copied() {
-            if count == COUNT_INTERVAL {
-                let duration = Instant::now().duration_since(instant);
-                if duration > MIN_DURATION_INTERVAL {
-                    if duration > LARGE_DURATION_INTERVAL {
-                        state.ips_time.insert(ip, (1, Instant::now()));
-                        AntiSpamResponse::ok()
-                    } else {
-                        state
-                            .ips_time
-                            .insert(ip, (REDUCED_COUNT_INTERVAL, Instant::now()));
-                        AntiSpamResponse::ok()
-                    }
-                } else {
-                    state.ban.insert(ip, (true, ban_count, Instant::now()));
-                    AntiSpamResponse::ban()
-                }
-            } else {
-                state.ips_time.insert(ip, (count + 1, instant));
-                AntiSpamResponse::ok()
-            }
-        } else {
-            state.ips_time.insert(ip, (1, Instant::now()));
-            AntiSpamResponse::ok()
-        }
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use std::net::{Ipv4Addr, Ipv6Addr};
-
-    const LOCAL_IP4: IpAddr = IpAddr::V4(Ipv4Addr::LOCALHOST);
-    const LOCAL_IP6: IpAddr = IpAddr::V6(Ipv6Addr::LOCALHOST);
-
-    #[tokio::test]
-    async fn test_anti_spam() {
-        let anti_spam = AntiSpam::from(&GvaConf::default());
-        assert!(!anti_spam.verify(None).await.is_ok);
-
-        for _ in 0..(COUNT_INTERVAL * 2) {
-            assert!(anti_spam.verify(Some(LOCAL_IP4)).await.is_ok);
-            assert!(anti_spam.verify(Some(LOCAL_IP6)).await.is_ok);
-        }
-
-        let extern_ip = IpAddr::V4(Ipv4Addr::UNSPECIFIED);
-
-        // Consume max queries
-        for _ in 0..COUNT_INTERVAL {
-            assert!(anti_spam.verify(Some(extern_ip)).await.is_ok);
-        }
-        // Should be banned
-        assert!(!anti_spam.verify(Some(extern_ip)).await.is_ok);
-
-        // Should be un-banned after one second
-        tokio::time::sleep(Duration::from_millis(1_100)).await;
-        // Re-consume max queries
-        for _ in 0..COUNT_INTERVAL {
-            assert!(anti_spam.verify(Some(extern_ip)).await.is_ok);
-        }
-        // Should be banned for 2 seconds this time
-        tokio::time::sleep(Duration::from_millis(1_100)).await;
-        // Attempting a request when I'm banned must be twice my banning time
-        assert!(!anti_spam.verify(Some(extern_ip)).await.is_ok);
-        tokio::time::sleep(Duration::from_millis(4_100)).await;
-        // Re-consume max queries
-        for _ in 0..COUNT_INTERVAL {
-            assert!(anti_spam.verify(Some(extern_ip)).await.is_ok);
-        }
-    }
-}
diff --git a/rust-libs/modules/gva/src/lib.rs b/rust-libs/modules/gva/src/lib.rs
deleted file mode 100644
index b637c342e..000000000
--- a/rust-libs/modules/gva/src/lib.rs
+++ /dev/null
@@ -1,367 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-#![deny(
-    clippy::unwrap_used,
-    missing_copy_implementations,
-    trivial_casts,
-    trivial_numeric_casts,
-    unstable_features,
-    unused_import_braces
-)]
-
-mod anti_spam;
-mod warp_;
-
-pub use duniter_conf::gva_conf::GvaConf;
-
-use async_graphql::http::GraphQLPlaygroundConfig;
-use dubp::common::prelude::*;
-use dubp::documents::transaction::TransactionDocumentV10;
-use dubp::{block::DubpBlockV10, crypto::hashs::Hash};
-use dubp::{
-    common::crypto::keys::{ed25519::PublicKey, KeyPair as _},
-    crypto::keys::ed25519::Ed25519KeyPair,
-};
-use duniter_conf::DuniterMode;
-use duniter_dbs::databases::txs_mp_v2::TxsMpV2DbReadable;
-use duniter_dbs::prelude::*;
-use duniter_dbs::{kv_typed::prelude::*, FileBackend};
-use duniter_global::AsyncAccessor;
-use duniter_gva_db::*;
-use duniter_gva_gql::{GvaSchema, QueryContext};
-use duniter_gva_indexer::{get_gva_db_ro, get_gva_db_rw};
-use duniter_mempools::Mempools;
-use futures::{StreamExt, TryStreamExt};
-use std::{convert::Infallible, path::Path};
-use warp::{http::Response as HttpResponse, Filter as _, Rejection};
-
-#[derive(Debug)]
-pub struct GvaModule {
-    conf: Option<GvaConf>,
-    currency: String,
-    dbs_pool: fast_threadpool::ThreadPoolAsyncHandler<SharedDbs<FileBackend>>,
-    gva_db_ro: &'static GvaV1DbRo<FileBackend>,
-    mempools: Mempools,
-    mode: DuniterMode,
-    self_keypair: Ed25519KeyPair,
-    software_version: &'static str,
-}
-
-#[async_trait::async_trait]
-impl duniter_module::DuniterModule for GvaModule {
-    const INDEX_BLOCKS: bool = true;
-
-    fn apply_block(
-        block: &DubpBlockV10,
-        _conf: &duniter_conf::DuniterConf,
-        profile_path_opt: Option<&Path>,
-    ) -> KvResult<()> {
-        let gva_db = get_gva_db_rw(profile_path_opt);
-        duniter_gva_indexer::apply_block(&block, gva_db)
-    }
-    fn revert_block(
-        block: &DubpBlockV10,
-        _conf: &duniter_conf::DuniterConf,
-        profile_path_opt: Option<&Path>,
-    ) -> KvResult<()> {
-        let gva_db = get_gva_db_rw(profile_path_opt);
-        duniter_gva_indexer::revert_block(&block, gva_db)
-    }
-    fn init(
-        conf: &duniter_conf::DuniterConf,
-        currency: &str,
-        dbs_pool: &fast_threadpool::ThreadPoolAsyncHandler<SharedDbs<FileBackend>>,
-        mempools: Mempools,
-        mode: duniter_conf::DuniterMode,
-        profile_path_opt: Option<&Path>,
-        software_version: &'static str,
-    ) -> anyhow::Result<(Self, Vec<duniter_module::Endpoint>)> {
-        let mut endpoints = Vec::new();
-        if let Some(conf) = conf.gva.clone() {
-            let remote_port = conf.get_remote_port();
-            endpoints.push(format!(
-                "GVA {}{} {} {}",
-                if remote_port == 443 || conf.get_remote_tls() {
-                    "S "
-                } else {
-                    ""
-                },
-                conf.get_remote_host(),
-                remote_port,
-                conf.get_remote_path(),
-            ));
-            endpoints.push(format!(
-                "GVASUB {}{} {} {}",
-                if remote_port == 443 || conf.get_remote_tls() {
-                    "S "
-                } else {
-                    ""
-                },
-                conf.get_remote_host(),
-                remote_port,
-                conf.get_remote_subscriptions_path(),
-            ));
-        };
-        Ok((
-            GvaModule {
-                conf: conf.gva.to_owned(),
-                currency: currency.to_owned(),
-                dbs_pool: dbs_pool.to_owned(),
-                gva_db_ro: get_gva_db_ro(profile_path_opt),
-                mempools,
-                mode,
-                self_keypair: conf.self_key_pair.clone(),
-                software_version,
-            },
-            endpoints,
-        ))
-    }
-
-    async fn start(self) -> anyhow::Result<()> {
-        // Do not start GVA server on js tests
-        if std::env::var_os("DUNITER_JS_TESTS") != Some("yes".into()) {
-            let GvaModule {
-                conf,
-                currency,
-                dbs_pool,
-                gva_db_ro,
-                mempools,
-                mode,
-                self_keypair,
-                software_version,
-            } = self;
-
-            if let DuniterMode::Start = mode {
-                if let Some(conf) = conf {
-                    GvaModule::start_inner(
-                        conf,
-                        currency,
-                        dbs_pool,
-                        gva_db_ro,
-                        mempools,
-                        self_keypair,
-                        software_version,
-                    )
-                    .await
-                }
-            }
-        }
-        Ok(())
-    }
-    // Needed for BMA only, will be removed when the migration is complete.
-    fn get_transactions_history_for_bma(
-        dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
-        profile_path_opt: Option<&Path>,
-        pubkey: PublicKey,
-    ) -> KvResult<Option<duniter_module::TxsHistoryForBma>> {
-        let gva_db = get_gva_db_ro(profile_path_opt);
-        let duniter_gva_dbs_reader::txs_history::TxsHistory {
-            sent,
-            received,
-            sending,
-            pending,
-        } = dbs_pool
-            .execute(move |dbs| {
-                duniter_gva_dbs_reader::txs_history::get_transactions_history_for_bma(
-                    gva_db,
-                    &dbs.txs_mp_db,
-                    pubkey,
-                )
-            })
-            .expect("dbs pool disconnected")?;
-        Ok(Some(duniter_module::TxsHistoryForBma {
-            sent: sent
-                .into_iter()
-                .map(
-                    |GvaTxDbV1 {
-                         tx,
-                         written_block,
-                         written_time,
-                     }| (tx, written_block, written_time),
-                )
-                .collect(),
-            received: received
-                .into_iter()
-                .map(
-                    |GvaTxDbV1 {
-                         tx,
-                         written_block,
-                         written_time,
-                     }| (tx, written_block, written_time),
-                )
-                .collect(),
-            sending,
-            pending,
-        }))
-    }
-    // Needed for BMA only, will be removed when the migration is complete.
-    fn get_tx_by_hash(
-        dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
-        hash: Hash,
-        profile_path_opt: Option<&Path>,
-    ) -> KvResult<Option<(TransactionDocumentV10, Option<BlockNumber>)>> {
-        let gva_db = get_gva_db_ro(profile_path_opt);
-        dbs_pool
-            .execute(move |dbs| {
-                if let Some(tx) = dbs.txs_mp_db.txs().get(&duniter_dbs::HashKeyV2(hash))? {
-                    Ok(Some((tx.0, None)))
-                } else if let Some(tx_db) = gva_db.txs().get(&duniter_dbs::HashKeyV2(hash))? {
-                    Ok(Some((tx_db.tx, Some(tx_db.written_block.number))))
-                } else {
-                    Ok(None)
-                }
-            })
-            .expect("dbs pool disconnected")
-    }
-}
-
-impl GvaModule {
-    async fn start_inner(
-        conf: GvaConf,
-        currency: String,
-        dbs_pool: fast_threadpool::ThreadPoolAsyncHandler<SharedDbs<FileBackend>>,
-        gva_db_ro: &'static GvaV1DbRo<FileBackend>,
-        mempools: Mempools,
-        self_keypair: Ed25519KeyPair,
-        software_version: &'static str,
-    ) {
-        log::info!("GvaServer::start: conf={:?}", conf);
-
-        // Create BcaExecutor and GvaSchema
-        let self_pubkey = self_keypair.public_key();
-        duniter_bca::set_bca_executor(
-            currency.clone(),
-            AsyncAccessor::new(),
-            dbs_pool.clone(),
-            duniter_gva_dbs_reader::create_dbs_reader(gva_db_ro),
-            self_keypair,
-            software_version,
-            mempools.txs,
-        );
-        let gva_schema = duniter_gva_gql::build_schema_with_data(
-            duniter_gva_gql::GvaSchemaData {
-                cm_accessor: AsyncAccessor::new(),
-                dbs_reader: duniter_gva_dbs_reader::create_dbs_reader(gva_db_ro),
-                dbs_pool,
-                server_meta_data: duniter_gva_gql::ServerMetaData {
-                    currency,
-                    self_pubkey,
-                    software_version,
-                },
-                txs_mempool: mempools.txs,
-            },
-            true,
-        );
-
-        // Create warp server routes
-        let graphql_post = warp_::graphql(
-            &conf,
-            gva_schema.clone(),
-            async_graphql::http::MultipartOptions::default(),
-        );
-
-        let conf_clone = conf.clone();
-        let graphql_playground =
-            warp::path::path(conf.get_path())
-                .and(warp::get())
-                .map(move || {
-                    HttpResponse::builder()
-                        .header("content-type", "text/html")
-                        .body(async_graphql::http::playground_source(
-                            GraphQLPlaygroundConfig::new(&format!("/{}", &conf_clone.get_path()))
-                                .subscription_endpoint(&format!(
-                                    "/{}",
-                                    &conf_clone.get_subscriptions_path(),
-                                )),
-                        ))
-                });
-
-        let routes = graphql_playground
-            .or(graphql_post)
-            .or(warp_::graphql_ws(&conf, gva_schema.clone()))
-            .recover(|err: Rejection| async move {
-                if let Some(warp_::BadRequest(err)) = err.find() {
-                    return Ok::<_, Infallible>(warp::reply::with_status(
-                        err.to_string(),
-                        http::StatusCode::BAD_REQUEST,
-                    ));
-                }
-
-                Ok(warp::reply::with_status(
-                    "INTERNAL_SERVER_ERROR".to_string(),
-                    http::StatusCode::INTERNAL_SERVER_ERROR,
-                ))
-            });
-
-        // Start warp server
-        log::info!(
-            "GVA server listen on http://{}:{}/{}",
-            conf.get_ip4(),
-            conf.get_port(),
-            &conf.get_path()
-        );
-        if let Some(ip6) = conf.get_ip6() {
-            log::info!(
-                "GVA server listen on http://{}:{}/{}",
-                ip6,
-                conf.get_port(),
-                &conf.get_path()
-            );
-            futures::future::join(
-                warp::serve(routes.clone()).run((conf.get_ip4(), conf.get_port())),
-                warp::serve(routes).run((ip6, conf.get_port())),
-            )
-            .await;
-        } else {
-            warp::serve(routes)
-                .run((conf.get_ip4(), conf.get_port()))
-                .await;
-        }
-        log::warn!("GVA server stopped");
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use duniter_conf::DuniterConf;
-    use duniter_mempools::Mempools;
-    use duniter_module::DuniterModule;
-    use fast_threadpool::{ThreadPool, ThreadPoolConfig};
-    use unwrap::unwrap;
-
-    #[tokio::test]
-    #[ignore]
-    async fn launch_mem_gva() -> anyhow::Result<()> {
-        let dbs = unwrap!(SharedDbs::mem());
-        let threadpool = ThreadPool::start(ThreadPoolConfig::default(), dbs);
-
-        GvaModule::init(
-            &DuniterConf::default(),
-            "",
-            &threadpool.into_async_handler(),
-            Mempools::default(),
-            duniter_conf::DuniterMode::Start,
-            None,
-            "test",
-        )?
-        .0
-        .start()
-        .await?;
-
-        Ok(())
-    }
-}
diff --git a/rust-libs/modules/gva/src/warp_.rs b/rust-libs/modules/gva/src/warp_.rs
deleted file mode 100644
index 2673a34fc..000000000
--- a/rust-libs/modules/gva/src/warp_.rs
+++ /dev/null
@@ -1,323 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use std::{
-    net::{IpAddr, SocketAddr},
-    time::Duration,
-};
-
-use bytes::Bytes;
-
-use crate::anti_spam::{AntiSpam, AntiSpamResponse};
-use crate::*;
-
-const MAX_BATCH_REQ_PROCESS_DURATION_IN_MILLIS: u64 = 5_000;
-
-pub struct BadRequest(pub anyhow::Error);
-
-impl std::fmt::Debug for BadRequest {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(f, "{}", self.0)
-    }
-}
-
-impl warp::reject::Reject for BadRequest {}
-
-pub struct ReqExecTooLong;
-
-impl std::fmt::Debug for ReqExecTooLong {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(f, "server error: request execution too long")
-    }
-}
-
-impl warp::reject::Reject for ReqExecTooLong {}
-
-struct GraphQlRequest {
-    inner: async_graphql::BatchRequest,
-}
-
-impl GraphQlRequest {
-    fn data<D: std::any::Any + Copy + Send + Sync>(self, data: D) -> Self {
-        match self.inner {
-            async_graphql::BatchRequest::Single(request) => {
-                Self::new(async_graphql::BatchRequest::Single(request.data(data)))
-            }
-            async_graphql::BatchRequest::Batch(requests) => {
-                Self::new(async_graphql::BatchRequest::Batch(
-                    requests.into_iter().map(|req| req.data(data)).collect(),
-                ))
-            }
-        }
-    }
-    #[allow(clippy::from_iter_instead_of_collect)]
-    async fn execute(self, schema: GvaSchema) -> async_graphql::BatchResponse {
-        use std::iter::FromIterator as _;
-        match self.inner {
-            async_graphql::BatchRequest::Single(request) => {
-                async_graphql::BatchResponse::Single(schema.execute(request).await)
-            }
-            async_graphql::BatchRequest::Batch(requests) => async_graphql::BatchResponse::Batch(
-                futures::stream::FuturesOrdered::from_iter(
-                    requests
-                        .into_iter()
-                        .zip(std::iter::repeat(schema))
-                        .map(|(request, schema)| async move { schema.execute(request).await }),
-                )
-                .collect()
-                .await,
-            ),
-        }
-    }
-    fn len(&self) -> usize {
-        match &self.inner {
-            async_graphql::BatchRequest::Single(_) => 1,
-            async_graphql::BatchRequest::Batch(requests) => requests.len(),
-        }
-    }
-    fn new(inner: async_graphql::BatchRequest) -> Self {
-        Self { inner }
-    }
-    fn single(request: async_graphql::Request) -> Self {
-        Self::new(async_graphql::BatchRequest::Single(request))
-    }
-}
-
-enum ServerResponse {
-    Bincode(Vec<u8>),
-    GraphQl(async_graphql::BatchResponse),
-}
-
-impl warp::reply::Reply for ServerResponse {
-    fn into_response(self) -> warp::reply::Response {
-        match self {
-            ServerResponse::Bincode(bytes) => bytes.into_response(),
-            ServerResponse::GraphQl(gql_batch_resp) => {
-                let mut resp = warp::reply::with_header(
-                    warp::reply::json(&gql_batch_resp),
-                    "content-type",
-                    "application/json",
-                )
-                .into_response();
-                add_cache_control_batch(&mut resp, &gql_batch_resp);
-                resp
-            }
-        }
-    }
-}
-
-fn add_cache_control_batch(
-    http_resp: &mut warp::reply::Response,
-    batch_resp: &async_graphql::BatchResponse,
-) {
-    match batch_resp {
-        async_graphql::BatchResponse::Single(resp) => add_cache_control(http_resp, resp),
-        async_graphql::BatchResponse::Batch(resps) => {
-            for resp in resps {
-                add_cache_control(http_resp, resp)
-            }
-        }
-    }
-}
-
-fn add_cache_control(http_resp: &mut warp::reply::Response, resp: &async_graphql::Response) {
-    if resp.is_ok() {
-        if let Some(cache_control) = resp.cache_control.value() {
-            if let Ok(value) = cache_control.parse() {
-                http_resp.headers_mut().insert("cache-control", value);
-            }
-        }
-    }
-}
-
-pub(crate) fn graphql(
-    conf: &GvaConf,
-    gva_schema: GvaSchema,
-    opts: async_graphql::http::MultipartOptions,
-) -> impl warp::Filter<Extract = (impl warp::Reply,), Error = Rejection> + Clone {
-    let anti_spam = AntiSpam::from(conf);
-    let opts = Arc::new(opts);
-    warp::path::path(conf.get_path())
-        .and(warp::method())
-        .and(warp::query::raw().or(warp::any().map(String::new)).unify())
-        .and(warp::addr::remote())
-        .and(warp::header::optional::<IpAddr>("X-Real-IP"))
-        .and(warp::header::optional::<String>("content-type"))
-        .and(warp::body::stream())
-        .and(warp::any().map(move || anti_spam.clone()))
-        .and(warp::any().map(move || gva_schema.clone()))
-        .and(warp::any().map(move || opts.clone()))
-        .and_then(
-            |method,
-             query: String,
-             remote_addr: Option<SocketAddr>,
-             x_real_ip: Option<IpAddr>,
-             content_type: Option<String>,
-             body,
-             anti_spam: AntiSpam,
-             gva_schema: GvaSchema,
-             opts: Arc<async_graphql::http::MultipartOptions>| async move {
-                let AntiSpamResponse {
-                    is_whitelisted,
-                    is_ok,
-                } = anti_spam
-                    .verify(x_real_ip.or_else(|| remote_addr.map(|ra| ra.ip())))
-                    .await;
-                if is_ok {
-                    if method == http::Method::GET {
-                        let request: async_graphql::Request = serde_urlencoded::from_str(&query)
-                            .map_err(|err| warp::reject::custom(BadRequest(err.into())))?;
-                        Ok(ServerResponse::GraphQl(
-                            GraphQlRequest::single(request.data(QueryContext { is_whitelisted }))
-                                .execute(gva_schema)
-                                .await,
-                        ))
-                    } else {
-                        let body_stream = futures::TryStreamExt::map_err(body, |err| {
-                            std::io::Error::new(std::io::ErrorKind::Other, err)
-                        })
-                        .map_ok(|mut buf| {
-                            let remaining = warp::Buf::remaining(&buf);
-                            warp::Buf::copy_to_bytes(&mut buf, remaining)
-                        });
-                        if content_type.as_deref() == Some("application/bincode") {
-                            tokio::time::timeout(
-                                Duration::from_millis(MAX_BATCH_REQ_PROCESS_DURATION_IN_MILLIS),
-                                process_bincode_batch_queries(body_stream, is_whitelisted),
-                            )
-                            .await
-                            .map_err(|_| warp::reject::custom(ReqExecTooLong))?
-                        } else {
-                            tokio::time::timeout(
-                                Duration::from_millis(MAX_BATCH_REQ_PROCESS_DURATION_IN_MILLIS),
-                                process_json_batch_queries(
-                                    body_stream.into_async_read(),
-                                    content_type,
-                                    gva_schema,
-                                    is_whitelisted,
-                                    *opts,
-                                ),
-                            )
-                            .await
-                            .map_err(|_| warp::reject::custom(ReqExecTooLong))?
-                        }
-                    }
-                } else {
-                    Err(warp::reject::custom(BadRequest(anyhow::Error::msg(
-                        r#"{ "error": "too many requests" }"#,
-                    ))))
-                }
-            },
-        )
-}
-
-async fn process_bincode_batch_queries(
-    body_reader: impl 'static + futures::TryStream<Ok = Bytes, Error = std::io::Error> + Send + Unpin,
-    is_whitelisted: bool,
-) -> Result<ServerResponse, warp::Rejection> {
-    Ok(ServerResponse::Bincode(
-        duniter_bca::execute(body_reader, is_whitelisted).await,
-    ))
-}
-
-async fn process_json_batch_queries(
-    body_reader: impl 'static + futures::AsyncRead + Send + Unpin,
-    content_type: Option<String>,
-    gva_schema: GvaSchema,
-    is_whitelisted: bool,
-    opts: async_graphql::http::MultipartOptions,
-) -> Result<ServerResponse, warp::Rejection> {
-    let batch_request = GraphQlRequest::new(
-        async_graphql::http::receive_batch_body(
-            content_type,
-            body_reader,
-            async_graphql::http::MultipartOptions::clone(&opts),
-        )
-        .await
-        .map_err(|err| warp::reject::custom(BadRequest(err.into())))?,
-    );
-    if is_whitelisted || batch_request.len() <= anti_spam::MAX_BATCH_SIZE {
-        Ok(ServerResponse::GraphQl(
-            batch_request
-                .data(QueryContext { is_whitelisted })
-                .execute(gva_schema)
-                .await,
-        ))
-    } else {
-        Err(warp::reject::custom(BadRequest(anyhow::Error::msg(
-            r#"{ "error": "The batch contains too many requests" }"#,
-        ))))
-    }
-}
-
-pub(crate) fn graphql_ws(
-    conf: &GvaConf,
-    schema: GvaSchema,
-) -> impl warp::Filter<Extract = (impl warp::Reply,), Error = Rejection> + Clone {
-    let anti_spam = AntiSpam::from(conf);
-    warp::path::path(conf.get_subscriptions_path())
-        .and(warp::addr::remote())
-        .and(warp::header::optional::<IpAddr>("X-Real-IP"))
-        .and(warp::ws())
-        .and(warp::any().map(move || schema.clone()))
-        .and(warp::any().map(move || anti_spam.clone()))
-        .and_then(
-            |remote_addr: Option<SocketAddr>,
-             x_real_ip: Option<IpAddr>,
-             ws: warp::ws::Ws,
-             schema: GvaSchema,
-             anti_spam: AntiSpam| async move {
-                let AntiSpamResponse {
-                    is_whitelisted: _,
-                    is_ok,
-                } = anti_spam
-                    .verify(x_real_ip.or_else(|| remote_addr.map(|ra| ra.ip())))
-                    .await;
-                if is_ok {
-                    Ok((ws, schema))
-                } else {
-                    Err(warp::reject::custom(BadRequest(anyhow::Error::msg(
-                        r#"{ "error": "too many requests" }"#,
-                    ))))
-                }
-            },
-        )
-        .and_then(|(ws, schema): (warp::ws::Ws, GvaSchema)| {
-            let reply = ws.on_upgrade(move |websocket| {
-                let (ws_sender, ws_receiver) = websocket.split();
-
-                async move {
-                    let _ = async_graphql::http::WebSocket::new(
-                        schema,
-                        ws_receiver
-                            .take_while(|msg| futures::future::ready(msg.is_ok()))
-                            .map(Result::unwrap)
-                            .map(warp::ws::Message::into_bytes),
-                        async_graphql::http::WebSocketProtocols::SubscriptionsTransportWS,
-                    )
-                    .map(warp::ws::Message::text)
-                    .map(Ok)
-                    .forward(ws_sender)
-                    .await;
-                }
-            });
-
-            futures::future::ready(Ok::<_, Rejection>(warp::reply::with_header(
-                reply,
-                "Sec-WebSocket-Protocol",
-                "graphql-ws",
-            )))
-        })
-}
diff --git a/rust-libs/tests/duniter-integration-tests/Cargo.toml b/rust-libs/tests/duniter-integration-tests/Cargo.toml
index 3f3bb65d2..e775f0c15 100644
--- a/rust-libs/tests/duniter-integration-tests/Cargo.toml
+++ b/rust-libs/tests/duniter-integration-tests/Cargo.toml
@@ -8,12 +8,7 @@ edition = "2018"
 [dependencies]
 anyhow = "1.0.34"
 dubp = { version = "0.51.0", features = ["duniter"] }
-duniter-conf = { path = "../../duniter-conf" }
-duniter-dbs = { path = "../../duniter-dbs" }
-duniter-bc-reader = { path = "../../duniter-bc-reader" }
-duniter-dbs-write-ops = { path = "../../duniter-dbs-write-ops" }
-duniter-mempools = { path = "../../duniter-mempools" }
-duniter-module = { path = "../../duniter-module" }
+duniter-core = { git = "https://git.duniter.org/nodes/rust/duniter-core", features = ["bc-writer"] }
 duniter-server = { path = "../../duniter-server", features = ["gva"] }
 fast-threadpool = "0.2.3"
 flume = "0.10.0"
diff --git a/rust-libs/tools/kv_typed/Cargo.toml b/rust-libs/tools/kv_typed/Cargo.toml
deleted file mode 100644
index 65554446b..000000000
--- a/rust-libs/tools/kv_typed/Cargo.toml
+++ /dev/null
@@ -1,59 +0,0 @@
-[package]
-name = "kv_typed"
-version = "0.1.0"
-authors = ["elois <c@elo.tf>"]
-description = "Strongly typed key-value storage"
-repository = "https://git.duniter.org/nodes/typescript/duniter"
-keywords = ["database", "key", "sled"]
-license = "AGPL-3.0"
-edition = "2018"
-
-[lib]
-path = "src/lib.rs"
-
-[dependencies]
-byteorder = "1.3.4"
-cfg-if = "0.1.10"
-flume = "0.10.0"
-leveldb_minimal = { version = "0.1.0", optional = true }
-lmdb-zero = { version = "0.4.4", optional = true }
-mockall = { version = "0.9.1", optional = true }
-parking_lot = "0.11.0"
-paste = "1.0.2"
-rayon = { version = "1.3.1", optional = true }
-regex = { version = "1.3.9", optional = true }
-serde_json = { version = "1.0.53", optional = true }
-sled = { version = "0.34.6", optional = true, features = ["compression"] }
-smallvec = { version = "1.4.0", features = ["serde", "write"] }
-thiserror = "1.0.20"
-uninit = "0.4.0"
-zerocopy = "0.3.0"
-
-[[bench]]
-name = "compare_backends"
-harness = false
-required-features = ["leveldb_backend", "sled_backend"]
-
-[dev-dependencies]
-async-std = { version = "1.6.3", features = ["attributes"] }
-maybe-async = "0.2.0"
-smallvec = { version = "1.4.0", features = ["serde", "write"] }
-tempfile = "3.2.0"
-unwrap = "1.2.1"
-
-# Benches dependencies
-criterion = { version = "0.3.1" }
-
-[features]
-#default = ["sled_backend"]
-
-async = []
-explorer = ["rayon", "regex", "serde_json"]
-leveldb_backend = ["leveldb_minimal"]
-lmdb_backend = ["lmdb-zero"]
-sled_backend = ["sled"]
-
-#mock = ["mockall"]
-
-default = ["sled_backend", "explorer"]
-#default = ["mock"]
diff --git a/rust-libs/tools/kv_typed/benches/compare_backends.rs b/rust-libs/tools/kv_typed/benches/compare_backends.rs
deleted file mode 100644
index d21049b49..000000000
--- a/rust-libs/tools/kv_typed/benches/compare_backends.rs
+++ /dev/null
@@ -1,146 +0,0 @@
-use criterion::{criterion_group, criterion_main, Criterion, /*, AxisScale, PlotConfiguration*/};
-use kv_typed::prelude::*;
-use std::{fmt::Debug, path::PathBuf};
-
-kv_typed::db_schema!(Test, [["c1", Col1, u32, String],]);
-//const LEVELDB_DIR_PATH: &str = "/dev/shm/kv_typed/benches/compare_backends/leveldb";
-//const LMDB_DIR_PATH: &str = "/dev/shm/kv_typed/benches/compare_backends/lmdb";
-const LEVELDB_DIR_PATH: &str = "/home/elois/tmp/kv_typed/benches/compare_backends/leveldb";
-const LMDB_DIR_PATH: &str = "/home/elois/tmp/kv_typed/benches/compare_backends/lmdb";
-const SLED_DIR_PATH: &str = "/home/elois/tmp/kv_typed/benches/compare_backends/sled";
-static SMALL_VAL: &str = "abcdefghijklmnopqrst";
-static LARGE_VAL: &str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
-
-fn read_n_entries<B: Backend>(db: &TestDb<B>, n: u32, val: String) {
-    for i in 0..n {
-        assert_eq!(db.col1().get(&i).expect("db err"), Some(val.clone()));
-    }
-    /*db.col1().iter(.., |iter| {
-        let mut iter = iter.values();
-        for _ in 0..n {
-            assert_eq!(iter.next_res().expect(""), Some(val.clone()));
-            //assert_eq!(db.col1().get(&i).expect(""), Some(val.clone()));
-        }
-        assert_eq!(iter.next_res().expect(""), None);
-    });*/
-}
-fn remove_and_write_n_entries<B: Backend>(db: &TestDb<B>, n: u32, val: String) {
-    for i in 0..n {
-        db.col1_write().remove(i).expect("fail to write");
-        db.col1_write()
-            .upsert(i, val.clone())
-            .expect("fail to write");
-    }
-}
-fn write_n_entries<B: Backend>(db: &TestDb<B>, n: u32, val: String) {
-    for i in 0..n {
-        db.col1_write()
-            .upsert(i, val.clone())
-            .expect("fail to write");
-    }
-}
-
-pub fn benchmark(c: &mut Criterion) {
-    // Read chart config
-    //let read_chart_config = PlotConfiguration::default().summary_scale(AxisScale::Logarithmic);
-
-    // Create DBs
-    std::fs::create_dir_all(LEVELDB_DIR_PATH).expect("fail to create leveldb dir");
-    let leveldb_db = TestDb::<LevelDb>::open(LevelDbConf {
-        db_path: PathBuf::from(LEVELDB_DIR_PATH),
-        ..Default::default()
-    })
-    .expect("fail to open db");
-    /*let lmdb_db =
-    TestDb::<Lmdb>::open(LmdbConf::default().folder_path(PathBuf::from(LMDB_DIR_PATH)))
-        .expect("fail to open db");*/
-    //let mem_db = TestDb::<Mem>::open(MemConf::default()).expect("fail to open db");
-    let sled_db =
-        TestDb::<Sled>::open(SledConf::default().path(SLED_DIR_PATH)).expect("fail to open db");
-
-    // Test write small values
-    let mut group = c.benchmark_group("write small values");
-    /*group.bench_function("lmdb", |b| {
-        b.iter(|| remove_and_write_n_entries(&lmdb_db, 100, String::from(SMALL_VAL)))
-    });*/
-    group.bench_function("leveldb", |b| {
-        b.iter(|| remove_and_write_n_entries(&leveldb_db, 100, String::from(SMALL_VAL)))
-    });
-    /*group.bench_function("mem", |b| {
-        b.iter(|| remove_and_write_n_entries(&mem_db, 100, String::from(SMALL_VAL)))
-    });*/
-    group.bench_function("sled", |b| {
-        b.iter(|| remove_and_write_n_entries(&sled_db, 100, String::from(SMALL_VAL)))
-    });
-    group.finish();
-
-    // Prepare read test
-    //write_n_entries(&lmdb_db, 100, String::from(SMALL_VAL));
-    write_n_entries(&leveldb_db, 100, String::from(SMALL_VAL));
-    //write_n_entries(&mem_db, 100, String::from(SMALL_VAL));
-    write_n_entries(&sled_db, 100, String::from(SMALL_VAL));
-
-    // Test read small values
-    let mut group = c.benchmark_group("read small values");
-    //group.plot_config(read_chart_config.clone());
-    /*group.bench_function("lmdb", |b| {
-        b.iter(|| read_n_entries(&lmdb_db, 100, String::from(SMALL_VAL)))
-    });*/
-    group.bench_function("leveldb", |b| {
-        b.iter(|| read_n_entries(&leveldb_db, 100, String::from(SMALL_VAL)))
-    });
-    /*group.bench_function("mem", |b| {
-        b.iter(|| read_n_entries(&mem_db, 100, String::from(SMALL_VAL)))
-    });*/
-    group.bench_function("sled", |b| {
-        b.iter(|| read_n_entries(&sled_db, 100, String::from(SMALL_VAL)))
-    });
-    group.finish();
-
-    // Test write large values
-    let mut group = c.benchmark_group("write large values");
-    /*group.bench_function("lmdb", |b| {
-        b.iter(|| remove_and_write_n_entries(&lmdb_db, 100, String::from(LARGE_VAL)))
-    });*/
-    group.bench_function("leveldb", |b| {
-        b.iter(|| remove_and_write_n_entries(&leveldb_db, 100, String::from(LARGE_VAL)))
-    });
-    /*group.bench_function("mem", |b| {
-        b.iter(|| remove_and_write_n_entries(&mem_db, 100, String::from(LARGE_VAL)))
-    });*/
-    group.bench_function("sled", |b| {
-        b.iter(|| remove_and_write_n_entries(&sled_db, 100, String::from(LARGE_VAL)))
-    });
-    group.finish();
-
-    // Prepare read test
-    //write_n_entries(&lmdb_db, 100, String::from(LARGE_VAL));
-    write_n_entries(&leveldb_db, 100, String::from(LARGE_VAL));
-    //write_n_entries(&mem_db, 100, String::from(LARGE_VAL));
-    write_n_entries(&sled_db, 100, String::from(LARGE_VAL));
-
-    // Test read large values
-    let mut group = c.benchmark_group("read large values");
-    //group.plot_config(read_chart_config);
-    /*group.bench_function("lmdb", |b| {
-        b.iter(|| read_n_entries(&lmdb_db, 100, String::from(LARGE_VAL)))
-    });*/
-    group.bench_function("leveldb", |b| {
-        b.iter(|| read_n_entries(&leveldb_db, 100, String::from(LARGE_VAL)))
-    });
-    /*group.bench_function("mem", |b| {
-        b.iter(|| read_n_entries(&mem_db, 100, String::from(LARGE_VAL)))
-    });*/
-    group.bench_function("sled", |b| {
-        b.iter(|| read_n_entries(&sled_db, 100, String::from(LARGE_VAL)))
-    });
-    group.finish();
-
-    // Close DBs
-    std::fs::remove_dir_all(LEVELDB_DIR_PATH).expect("fail to remove leveldb dir");
-    std::fs::remove_dir_all(LMDB_DIR_PATH).expect("fail to remove lmdb dir");
-    std::fs::remove_dir_all(SLED_DIR_PATH).expect("fail to remove sled dir");
-}
-
-criterion_group!(benches, benchmark);
-criterion_main!(benches);
diff --git a/rust-libs/tools/kv_typed/src/as_bytes.rs b/rust-libs/tools/kv_typed/src/as_bytes.rs
deleted file mode 100644
index 46e0e3f9f..000000000
--- a/rust-libs/tools/kv_typed/src/as_bytes.rs
+++ /dev/null
@@ -1,86 +0,0 @@
-use crate::*;
-
-pub trait AsBytes {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, f: F) -> T;
-}
-
-impl AsBytes for () {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        f(&[])
-    }
-}
-
-impl AsBytes for String {
-    fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-        f(self.as_bytes())
-    }
-}
-
-impl<T> AsBytes for Vec<T>
-where
-    T: zerocopy::AsBytes,
-{
-    fn as_bytes<D, F: FnMut(&[u8]) -> D>(&self, mut f: F) -> D {
-        use zerocopy::AsBytes as _;
-        f((&self[..]).as_bytes())
-    }
-}
-
-macro_rules! impl_as_bytes_for_smallvec {
-    ($($N:literal),*) => {$(
-        impl<T> AsBytes for SmallVec<[T; $N]>
-        where
-            T: zerocopy::AsBytes,
-        {
-            fn as_bytes<D, F: FnMut(&[u8]) -> D>(&self, mut f: F) -> D {
-                use zerocopy::AsBytes as _;
-                f((&self[..]).as_bytes())
-            }
-        }
-    )*};
-}
-impl_as_bytes_for_smallvec!(1, 2, 4, 8, 16, 32, 64);
-
-impl<T> AsBytes for BTreeSet<T>
-where
-    T: zerocopy::AsBytes + Copy,
-{
-    fn as_bytes<D, F: FnMut(&[u8]) -> D>(&self, mut f: F) -> D {
-        use zerocopy::AsBytes as _;
-        f((&self.iter().copied().collect::<SmallVec<[T; 32]>>()[..]).as_bytes())
-    }
-}
-
-impl<T> AsBytes for HashSet<T>
-where
-    T: zerocopy::AsBytes + Copy,
-{
-    fn as_bytes<D, F: FnMut(&[u8]) -> D>(&self, mut f: F) -> D {
-        use zerocopy::AsBytes as _;
-        f((&self.iter().copied().collect::<SmallVec<[T; 32]>>()[..]).as_bytes())
-    }
-}
-
-macro_rules! impl_as_bytes_for_le_numbers {
-    ($($T:ty),*) => {$(
-        impl AsBytes for $T {
-            fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-                f(&self.to_le_bytes()[..])
-            }
-        }
-    )*};
-}
-impl_as_bytes_for_le_numbers!(
-    usize, u8, u16, u32, u64, u128, isize, i8, i16, i32, i64, i128, f32, f64
-);
-
-macro_rules! impl_as_bytes_for_be_numbers {
-    ($($T:ty),*) => {$(
-        impl AsBytes for $T {
-            fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
-                f(&self.0.to_be_bytes()[..])
-            }
-        }
-    )*};
-}
-impl_as_bytes_for_be_numbers!(U32BE, U64BE);
diff --git a/rust-libs/tools/kv_typed/src/backend.rs b/rust-libs/tools/kv_typed/src/backend.rs
deleted file mode 100644
index 5e91cc21d..000000000
--- a/rust-libs/tools/kv_typed/src/backend.rs
+++ /dev/null
@@ -1,100 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-//! KV Typed Backend Trait
-
-#[cfg(feature = "leveldb_backend")]
-pub mod leveldb;
-#[cfg(feature = "lmdb_backend")]
-pub mod lmdb;
-pub mod memory;
-pub mod memory_singleton;
-#[cfg(feature = "mock")]
-pub mod mock;
-#[cfg(feature = "sled_backend")]
-pub mod sled;
-
-use crate::*;
-
-pub trait Backend: 'static + Clone + Sized {
-    const NAME: &'static str;
-    type Col: BackendCol;
-    type Conf: Default;
-
-    fn open(conf: &Self::Conf) -> KvResult<Self>;
-    fn open_col(&mut self, conf: &Self::Conf, col_name: &str) -> KvResult<Self::Col>;
-}
-
-pub trait BackendCol: 'static + Clone + Debug + Send + Sync {
-    type Batch: BackendBatch;
-    type KeyBytes: KeyBytes;
-    type ValueBytes: ValueBytes;
-    type Iter: BackendIter<Self::KeyBytes, Self::ValueBytes>;
-
-    fn get<K: Key, V: Value>(&self, k: &K) -> KvResult<Option<V>>;
-    fn get_ref<K: Key, V: ValueZc, D, F: Fn(&V::Ref) -> KvResult<D>>(
-        &self,
-        k: &K,
-        f: F,
-    ) -> KvResult<Option<D>>;
-    fn get_ref_slice<K: Key, V: ValueSliceZc, D, F: Fn(&[V::Elem]) -> KvResult<D>>(
-        &self,
-        k: &K,
-        f: F,
-    ) -> KvResult<Option<D>>;
-    fn clear(&mut self) -> KvResult<()>;
-    fn contains_key<K: Key>(&self, k: &K) -> KvResult<bool>;
-    fn count(&self) -> KvResult<usize>;
-    fn iter<K: Key, V: Value>(&self, range: RangeBytes) -> Self::Iter;
-    fn iter_ref_slice<D, K, V, F>(
-        &self,
-        range: RangeBytes,
-        f: F,
-    ) -> KvInnerIterRefSlice<Self, D, K, V, F>
-    where
-        K: KeyZc,
-        V: ValueSliceZc,
-        F: FnMut(&K::Ref, &[V::Elem]) -> KvResult<D>,
-    {
-        KvInnerIterRefSlice {
-            backend_iter: self.iter::<K, V>(range),
-            f,
-            phantom: PhantomData,
-        }
-    }
-    fn put<K: Key, V: Value>(&mut self, k: &K, value: &V) -> KvResult<()>;
-    fn delete<K: Key>(&mut self, k: &K) -> KvResult<()>;
-    fn new_batch() -> Self::Batch;
-    fn write_batch(&mut self, inner_batch: Self::Batch) -> KvResult<()>;
-    fn save(&self) -> KvResult<()>;
-}
-
-pub trait BackendIter<K: KeyBytes, V: ValueBytes>:
-    Iterator<Item = Result<(K, V), DynErr>> + ReversableIterator
-{
-}
-
-#[cfg_attr(feature = "mock", mockall::automock)]
-pub trait BackendBatch: Debug + Default {
-    fn upsert(&mut self, k: &[u8], v: &[u8]);
-    fn remove(&mut self, k: &[u8]);
-}
-
-#[cfg(feature = "mock")]
-impl Debug for MockBackendBatch {
-    fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        unimplemented!()
-    }
-}
diff --git a/rust-libs/tools/kv_typed/src/backend/leveldb.rs b/rust-libs/tools/kv_typed/src/backend/leveldb.rs
deleted file mode 100644
index 1ecd676c8..000000000
--- a/rust-libs/tools/kv_typed/src/backend/leveldb.rs
+++ /dev/null
@@ -1,364 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-//! LevelDb backend for KV Typed
-
-use crate::*;
-pub use leveldb_minimal::database::batch::{Batch as _, Writebatch as WriteBatch};
-use leveldb_minimal::database::cache::Cache as LevelDbCache;
-pub use leveldb_minimal::database::error::Error as LevelDbError;
-use leveldb_minimal::database::iterator::Iterator as LevelDbIterator;
-pub use leveldb_minimal::database::Database as LevelDbDb;
-use leveldb_minimal::iterator::{Iterable, LevelDBIterator as _};
-use leveldb_minimal::kv::KV as _;
-pub use leveldb_minimal::options::{Options as LevelDbOptions, ReadOptions, WriteOptions};
-use leveldb_minimal::Compression;
-use std::path::PathBuf;
-
-#[derive(Clone, Copy, Debug)]
-pub struct LevelDb;
-
-impl Backend for LevelDb {
-    const NAME: &'static str = "leveldb";
-    type Col = LevelDbCol;
-    type Conf = LevelDbConf;
-
-    fn open(_conf: &Self::Conf) -> KvResult<Self> {
-        Ok(LevelDb)
-    }
-    fn open_col(&mut self, conf: &Self::Conf, col_name: &str) -> KvResult<Self::Col> {
-        Ok(LevelDbCol(Arc::new(LevelDbDb::open(
-            &conf.db_path.join(col_name),
-            conf.clone().into(),
-        )?)))
-    }
-}
-
-#[derive(Clone)]
-pub struct LevelDbCol(Arc<LevelDbDb>);
-
-impl Debug for LevelDbCol {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        f.debug_struct("LevelDbCol")
-            .field("0", &"Arc<LevelDbDb>")
-            .finish()
-    }
-}
-
-#[derive(Default)]
-pub struct LevelDbBatch(WriteBatch);
-
-impl Debug for LevelDbBatch {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        f.debug_struct("LevelDbBatch")
-            .field("0", &"WriteBatch")
-            .finish()
-    }
-}
-
-impl BackendBatch for LevelDbBatch {
-    fn upsert(&mut self, k: &[u8], v: &[u8]) {
-        self.0.put(k, v)
-    }
-
-    fn remove(&mut self, k: &[u8]) {
-        self.0.delete(k)
-    }
-}
-
-#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
-pub struct LevelDbBytes(Vec<u8>);
-impl AsRef<[u8]> for LevelDbBytes {
-    fn as_ref(&self) -> &[u8] {
-        self.0.as_ref()
-    }
-}
-impl FromBytes for LevelDbBytes {
-    type Err = std::convert::Infallible;
-
-    fn from_bytes(bytes: &[u8]) -> Result<Self, Self::Err> {
-        Ok(Self(bytes.into()))
-    }
-}
-
-impl BackendCol for LevelDbCol {
-    type Batch = LevelDbBatch;
-    type KeyBytes = LevelDbBytes;
-    type ValueBytes = LevelDbBytes;
-    type Iter = LevelDbIter;
-
-    #[inline(always)]
-    fn new_batch() -> Self::Batch {
-        LevelDbBatch(WriteBatch::default())
-    }
-    fn clear(&mut self) -> KvResult<()> {
-        let keys = self
-            .0
-            .iter(ReadOptions::new())
-            .map(|(k, _v)| k)
-            .collect::<Vec<Vec<u8>>>();
-        for key in keys {
-            self.0.delete(WriteOptions::new(), key.as_ref())?;
-        }
-        Ok(())
-    }
-    #[inline(always)]
-    fn count(&self) -> KvResult<usize> {
-        Ok(self
-            .0
-            .iter(ReadOptions {
-                verify_checksums: false,
-                fill_cache: false,
-                snapshot: None,
-            })
-            .count())
-    }
-    #[inline(always)]
-    fn contains_key<K: Key>(&self, k: &K) -> KvResult<bool> {
-        k.as_bytes(|k_bytes| Ok(self.0.get(ReadOptions::new(), k_bytes)?.is_some()))
-    }
-    #[inline(always)]
-    fn get<K: Key, V: Value>(&self, k: &K) -> KvResult<Option<V>> {
-        k.as_bytes(|k_bytes| {
-            self.0
-                .get(ReadOptions::new(), k_bytes)?
-                .map(|bytes| V::from_bytes(&bytes).map_err(|e| KvError::DeserError(e.into())))
-                .transpose()
-        })
-    }
-    #[inline(always)]
-    fn get_ref<K: Key, V: ValueZc, D, F: Fn(&V::Ref) -> KvResult<D>>(
-        &self,
-        k: &K,
-        f: F,
-    ) -> KvResult<Option<D>> {
-        k.as_bytes(|k_bytes| {
-            self.0
-                .get(ReadOptions::new(), k_bytes)?
-                .map(|bytes| {
-                    if let Some(layout_verified) =
-                        zerocopy::LayoutVerified::<_, V::Ref>::new(bytes.as_ref())
-                    {
-                        f(&layout_verified)
-                    } else {
-                        Err(KvError::DeserError(
-                            "Bytes are invalid length or alignment.".into(),
-                        ))
-                    }
-                })
-                .transpose()
-        })
-    }
-    #[inline(always)]
-    fn get_ref_slice<K: Key, V: ValueSliceZc, D, F: Fn(&[V::Elem]) -> KvResult<D>>(
-        &self,
-        k: &K,
-        f: F,
-    ) -> KvResult<Option<D>> {
-        k.as_bytes(|k_bytes| {
-            self.0
-                .get(ReadOptions::new(), k_bytes)?
-                .map(|bytes| {
-                    if let Some(layout_verified) =
-                        zerocopy::LayoutVerified::<_, [V::Elem]>::new_slice(
-                            &bytes[V::prefix_len()..],
-                        )
-                    {
-                        f(&layout_verified)
-                    } else {
-                        Err(KvError::DeserError(
-                            "Bytes are invalid length or alignment.".into(),
-                        ))
-                    }
-                })
-                .transpose()
-        })
-    }
-    #[inline(always)]
-    fn delete<K: Key>(&mut self, k: &K) -> KvResult<()> {
-        k.as_bytes(|k_bytes| self.0.delete(WriteOptions::new(), k_bytes))?;
-        Ok(())
-    }
-    #[inline(always)]
-    fn put<K: Key, V: Value>(&mut self, k: &K, value: &V) -> KvResult<()> {
-        value.as_bytes(|value_bytes| {
-            k.as_bytes(|k_bytes| self.0.put(WriteOptions::new(), k_bytes, value_bytes))?;
-            Ok(())
-        })
-    }
-    #[inline(always)]
-    fn write_batch(&mut self, inner_batch: Self::Batch) -> KvResult<()> {
-        self.0.write(WriteOptions::new(), &inner_batch.0)?;
-        Ok(())
-    }
-    #[inline(always)]
-    fn iter<K: Key, V: Value>(&self, range: RangeBytes) -> Self::Iter {
-        LevelDbIter::new(self.0.iter(ReadOptions::new()), range)
-    }
-    #[inline(always)]
-    fn save(&self) -> KvResult<()> {
-        Ok(())
-    }
-}
-
-pub struct LevelDbIter {
-    inner: LevelDbIterator,
-    range_start: Bound<IVec>,
-    range_end: Bound<IVec>,
-    reversed: bool,
-}
-impl LevelDbIter {
-    fn new(inner: LevelDbIterator, range: RangeBytes) -> Self {
-        LevelDbIter {
-            inner,
-            range_start: range.0,
-            range_end: range.1,
-            reversed: false,
-        }
-    }
-}
-impl Debug for LevelDbIter {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        f.debug_struct("LevelDbIter")
-            .field("inner", &"LevelDbIterator<'db>")
-            .field("range_start", &self.range_start)
-            .field("range_end", &self.range_end)
-            .finish()
-    }
-}
-
-impl Iterator for LevelDbIter {
-    type Item = Result<(LevelDbBytes, LevelDbBytes), DynErr>;
-
-    #[inline(always)]
-    fn next(&mut self) -> Option<Self::Item> {
-        loop {
-            match self
-                .inner
-                .next()
-                .map(|(k, v)| Ok((LevelDbBytes(k), LevelDbBytes(v))))
-            {
-                Some(Ok((key_bytes, value_bytes))) => {
-                    let start_bound_ok = match &self.range_start {
-                        Bound::Included(start_bytes) => key_bytes.as_ref() >= start_bytes.as_ref(),
-                        Bound::Excluded(start_bytes) => key_bytes.as_ref() > start_bytes.as_ref(),
-                        Bound::Unbounded => true,
-                    };
-                    let end_bound_ok = match &self.range_end {
-                        Bound::Included(end_bytes) => key_bytes.as_ref() <= end_bytes.as_ref(),
-                        Bound::Excluded(end_bytes) => key_bytes.as_ref() < end_bytes.as_ref(),
-                        Bound::Unbounded => true,
-                    };
-                    if start_bound_ok {
-                        if end_bound_ok {
-                            break Some(Ok((key_bytes, value_bytes)));
-                        } else if self.reversed {
-                            // The interval has not yet begun.
-                            continue;
-                        } else {
-                            // The range has been fully traversed, the iterator is finished.
-                            break None;
-                        }
-                    } else if end_bound_ok {
-                        if self.reversed {
-                            // The range has been fully traversed, the iterator is finished.
-                            break None;
-                        } else {
-                            // The interval has not yet begun.
-                            continue;
-                        }
-                    } else {
-                        // Empty range, the iterator is finished.
-                        break None;
-                    }
-                }
-                other => break other,
-            }
-        }
-    }
-}
-impl ReversableIterator for LevelDbIter {
-    #[inline(always)]
-    fn reverse(self) -> Self {
-        LevelDbIter {
-            range_start: self.range_start,
-            range_end: self.range_end,
-            reversed: !self.reversed,
-            inner: self.inner.reverse(),
-        }
-    }
-}
-impl BackendIter<LevelDbBytes, LevelDbBytes> for LevelDbIter {}
-
-#[derive(Clone, Debug)]
-/// leveldb configuration
-pub struct LevelDbConf {
-    pub create_if_missing: bool,
-    pub db_path: PathBuf,
-    pub error_if_exists: bool,
-    pub paranoid_checks: bool,
-    pub write_buffer_size: Option<usize>,
-    pub max_open_files: Option<i32>,
-    pub block_size: Option<usize>,
-    pub block_restart_interval: Option<i32>,
-    pub compression: bool,
-    pub cache: Option<usize>,
-}
-
-impl LevelDbConf {
-    pub fn path(db_path: PathBuf) -> Self {
-        Self {
-            db_path,
-            ..Default::default()
-        }
-    }
-}
-
-impl Default for LevelDbConf {
-    fn default() -> Self {
-        LevelDbConf {
-            create_if_missing: true,
-            db_path: PathBuf::default(),
-            error_if_exists: false,
-            paranoid_checks: false,
-            write_buffer_size: None,
-            max_open_files: None,
-            block_size: None,
-            block_restart_interval: None,
-            compression: true,
-            cache: None,
-        }
-    }
-}
-
-impl Into<LevelDbOptions> for LevelDbConf {
-    fn into(self) -> LevelDbOptions {
-        LevelDbOptions {
-            create_if_missing: self.create_if_missing,
-            error_if_exists: self.error_if_exists,
-            paranoid_checks: self.paranoid_checks,
-            write_buffer_size: self.write_buffer_size,
-            max_open_files: self.max_open_files,
-            block_size: self.block_size,
-            block_restart_interval: self.block_restart_interval,
-            compression: if self.compression {
-                Compression::Snappy
-            } else {
-                Compression::No
-            },
-            cache: self.cache.map(LevelDbCache::new),
-        }
-    }
-}
diff --git a/rust-libs/tools/kv_typed/src/backend/lmdb.rs b/rust-libs/tools/kv_typed/src/backend/lmdb.rs
deleted file mode 100644
index a74d911c6..000000000
--- a/rust-libs/tools/kv_typed/src/backend/lmdb.rs
+++ /dev/null
@@ -1,404 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-//! Memory backend for KV Typed,
-
-use crate::*;
-use lmdb::{traits::CreateCursor as _, LmdbResultExt as _};
-use lmdb_zero as lmdb;
-use std::path::PathBuf;
-
-#[derive(Clone, Copy, Debug)]
-/// Be careful with this backend
-/// LMDB does not support multiple iterators in the same thread. So you need to make sure that :
-/// 1. Any iterator must be drop before any new call to the `iter()` method.
-/// 2. If you are in an asynchronous context, an async task should never yield when it to an instantiated iterator.
-pub struct Lmdb;
-
-#[derive(Clone, Debug)]
-pub struct LmdbConf {
-    folder_path: PathBuf,
-    temporary: bool,
-}
-impl Default for LmdbConf {
-    fn default() -> Self {
-        LmdbConf {
-            folder_path: PathBuf::default(),
-            temporary: false,
-        }
-    }
-}
-impl LmdbConf {
-    pub fn folder_path(mut self, folder_path: PathBuf) -> Self {
-        self.folder_path = folder_path;
-        self
-    }
-    pub fn temporary(mut self, temporary: bool) -> Self {
-        self.temporary = temporary;
-        self
-    }
-}
-
-impl Backend for Lmdb {
-    const NAME: &'static str = "lmdb";
-    type Col = LmdbCol;
-    type Conf = LmdbConf;
-
-    fn open(conf: &Self::Conf) -> KvResult<Self> {
-        std::fs::create_dir_all(conf.folder_path.as_path())?;
-        Ok(Lmdb)
-    }
-    fn open_col(&mut self, conf: &Self::Conf, col_name: &str) -> KvResult<Self::Col> {
-        let path: PathBuf = conf.folder_path.join(col_name);
-        let exist = path.as_path().exists();
-        if !exist {
-            std::fs::create_dir(path.as_path())?;
-        }
-        let path_to_remove = if conf.temporary {
-            Some(path.clone())
-        } else {
-            None
-        };
-        let path = path
-            .into_os_string()
-            .into_string()
-            .expect("Invalid DB path");
-        let mut env_flags = lmdb::open::Flags::empty();
-        env_flags.insert(lmdb::open::WRITEMAP);
-        env_flags.insert(lmdb::open::MAPASYNC);
-        env_flags.insert(lmdb::open::NOLOCK);
-        let col_options = if exist {
-            lmdb::DatabaseOptions::defaults()
-        } else {
-            lmdb::DatabaseOptions::new(lmdb::db::CREATE)
-        };
-        let env =
-            std::sync::Arc::new(unsafe { lmdb::EnvBuilder::new()?.open(&path, env_flags, 0o600)? });
-        let tree = std::sync::Arc::new(lmdb::Database::open(env.clone(), None, &col_options)?);
-        Ok(LmdbCol {
-            inner: LmdbColInner { env, tree },
-            path_to_remove,
-        })
-    }
-}
-
-#[derive(Clone, Debug)]
-pub struct LmdbCol {
-    inner: LmdbColInner,
-    path_to_remove: Option<PathBuf>,
-}
-
-impl Drop for LmdbCol {
-    fn drop(&mut self) {
-        if let Some(ref path) = self.path_to_remove {
-            let _ = std::fs::remove_dir(path);
-        }
-    }
-}
-
-#[derive(Clone, Debug)]
-struct LmdbColInner {
-    env: std::sync::Arc<lmdb::Environment>,
-    tree: std::sync::Arc<lmdb::Database<'static>>,
-}
-
-#[derive(Debug, Default)]
-pub struct LmdbBatch {
-    upsert_ops: Vec<(IVec, IVec)>,
-    remove_ops: Vec<IVec>,
-}
-
-impl BackendBatch for LmdbBatch {
-    fn upsert(&mut self, k: &[u8], v: &[u8]) {
-        self.upsert_ops.push((k.into(), v.into()));
-    }
-
-    fn remove(&mut self, k: &[u8]) {
-        self.remove_ops.push(k.into());
-    }
-}
-
-#[derive(Debug)]
-struct LmdbIterAccess {
-    env: std::sync::Arc<lmdb::Environment>,
-    access: lmdb::ConstAccessor<'static>,
-    tree: std::sync::Arc<lmdb::Database<'static>>,
-    tx: lmdb::ReadTransaction<'static>,
-}
-
-#[derive(Debug)]
-pub struct LmdbIter {
-    access: Arc<LmdbIterAccess>,
-    cursor: lmdb::Cursor<'static, 'static>,
-    reversed: bool,
-    started: bool,
-}
-
-impl LmdbIter {
-    fn new(
-        env: std::sync::Arc<lmdb::Environment>,
-        tree: std::sync::Arc<lmdb::Database<'static>>,
-    ) -> Self {
-        let tx = lmdb::ReadTransaction::new(env.clone()).expect("fail to read DB");
-        let tx_static: &'static lmdb::ReadTransaction<'static> =
-            unsafe { std::mem::transmute(&tx) };
-        let access = tx_static.access();
-        let cursor = tx_static
-            .cursor(tree.clone())
-            .expect("fail to create DB cursor");
-        LmdbIter {
-            access: Arc::new(LmdbIterAccess {
-                access,
-                env,
-                tree,
-                tx,
-            }),
-            cursor,
-            reversed: false,
-            started: false,
-        }
-    }
-}
-
-impl Iterator for LmdbIter {
-    type Item = Result<(&'static [u8], &'static [u8]), DynErr>;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        if self.reversed {
-            if self.started {
-                match self
-                    .cursor
-                    .prev::<[u8], [u8]>(unsafe {
-                        // # Safety
-                        // Lifetime of accessor is used to track db and lmdb_tx lifetimes: These are already static.
-                        // It's safe because the byte references will be transformed into K and V owned types before
-                        // being exposed to the user API.
-                        std::mem::transmute(&self.access.access)
-                    })
-                    .to_opt()
-                {
-                    Ok(Some((k, v))) => Some(Ok((k, v))),
-                    Ok(None) => None,
-                    Err(e) => Some(Err(e.into())),
-                }
-            } else {
-                self.started = true;
-                match self
-                    .cursor
-                    .last::<[u8], [u8]>(unsafe {
-                        // # Safety
-                        // Lifetime of accessor is used to track db and lmdb_tx lifetimes: These are already static.
-                        // It's safe because the byte references will be transformed into K and V owned types before
-                        // being exposed to the user API.
-                        std::mem::transmute(&self.access.access)
-                    })
-                    .to_opt()
-                {
-                    Ok(Some((k, v))) => Some(Ok((k, v))),
-                    Ok(None) => None,
-                    Err(e) => Some(Err(e.into())),
-                }
-            }
-        } else if self.started {
-            match self
-                .cursor
-                .next::<[u8], [u8]>(unsafe {
-                    // # Safety
-                    // Lifetime of accessor is used to track db and lmdb_tx lifetimes: These are already static.
-                    // It's safe because the byte references will be transformed into K and V owned types before
-                    // being exposed to the user API.
-                    std::mem::transmute(&self.access.access)
-                })
-                .to_opt()
-            {
-                Ok(Some((k, v))) => Some(Ok((k, v))),
-                Ok(None) => None,
-                Err(e) => Some(Err(e.into())),
-            }
-        } else {
-            self.started = true;
-            match self
-                .cursor
-                .first::<[u8], [u8]>(unsafe {
-                    // # Safety
-                    // Lifetime of accessor is used to track db and lmdb_tx lifetimes: These are already static.
-                    // It's safe because the byte references will be transformed into K and V owned types before
-                    // being exposed to the user API.
-                    std::mem::transmute(&self.access.access)
-                })
-                .to_opt()
-            {
-                Ok(Some((k, v))) => Some(Ok((k, v))),
-                Ok(None) => None,
-                Err(e) => Some(Err(e.into())),
-            }
-        }
-    }
-}
-
-impl ReversableIterator for LmdbIter {
-    fn reverse(mut self) -> Self {
-        self.reversed = true;
-        self
-    }
-}
-
-impl BackendIter<&'static [u8], &'static [u8]> for LmdbIter {}
-
-impl BackendCol for LmdbCol {
-    type Batch = LmdbBatch;
-    type KeyBytes = &'static [u8];
-    type ValueBytes = &'static [u8];
-    type Iter = LmdbIter;
-
-    fn get<K: Key, V: Value>(&self, k: &K) -> KvResult<Option<V>> {
-        let tx = lmdb::ReadTransaction::new(self.inner.tree.env())?;
-        let access = tx.access();
-        k.as_bytes(|k_bytes| {
-            access
-                .get(&self.inner.tree, k_bytes)
-                .to_opt()?
-                .map(|bytes| V::from_bytes(&bytes).map_err(|e| KvError::DeserError(e.into())))
-                .transpose()
-        })
-    }
-
-    fn get_ref<K: Key, V: ValueZc, D, F: Fn(&V::Ref) -> KvResult<D>>(
-        &self,
-        k: &K,
-        f: F,
-    ) -> KvResult<Option<D>> {
-        k.as_bytes(|k_bytes| {
-            let tx = lmdb::ReadTransaction::new(self.inner.tree.env())?;
-            let access = tx.access();
-            access
-                .get::<_, [u8]>(&self.inner.tree, k_bytes)
-                .to_opt()?
-                .map(|bytes| {
-                    if let Some(layout_verified) = zerocopy::LayoutVerified::<_, V::Ref>::new(bytes)
-                    {
-                        f(&layout_verified)
-                    } else {
-                        Err(KvError::DeserError(
-                            "Bytes are invalid length or alignment.".to_owned(),
-                        ))
-                    }
-                })
-                .transpose()
-        })
-    }
-
-    fn get_ref_slice<K: Key, V: ValueSliceZc, D, F: Fn(&[V::Elem]) -> KvResult<D>>(
-        &self,
-        k: &K,
-        f: F,
-    ) -> KvResult<Option<D>> {
-        k.as_bytes(|k_bytes| {
-            let tx = lmdb::ReadTransaction::new(self.inner.tree.env())?;
-            let access = tx.access();
-            access
-                .get::<_, [u8]>(&self.inner.tree, k_bytes)
-                .to_opt()?
-                .map(|bytes| {
-                    if let Some(layout_verified) =
-                        zerocopy::LayoutVerified::<_, [V::Elem]>::new_slice(
-                            &bytes[V::prefix_len()..],
-                        )
-                    {
-                        f(&layout_verified)
-                    } else {
-                        Err(KvError::DeserError(
-                            "Bytes are invalid length or alignment.".to_owned(),
-                        ))
-                    }
-                })
-                .transpose()
-        })
-    }
-
-    fn clear(&mut self) -> KvResult<()> {
-        let tx = lmdb::WriteTransaction::new(self.inner.tree.env())?;
-        {
-            let mut access = tx.access();
-            access.clear_db(&self.inner.tree)?;
-        }
-        tx.commit()?;
-        Ok(())
-    }
-
-    fn count(&self) -> KvResult<usize> {
-        let tx = lmdb::ReadTransaction::new(self.inner.tree.env())?;
-        Ok(tx.db_stat(&self.inner.tree)?.entries)
-    }
-
-    fn iter<K: Key, V: Value>(&self, _range: RangeBytes) -> Self::Iter {
-        LmdbIter::new(self.inner.env.clone(), self.inner.tree.clone())
-    }
-
-    fn put<K: Key, V: Value>(&mut self, k: &K, value: &V) -> KvResult<()> {
-        value.as_bytes(|v_bytes| {
-            let tx = lmdb::WriteTransaction::new(self.inner.tree.env())?;
-            k.as_bytes(|k_bytes| {
-                let mut access = tx.access();
-                access.put(
-                    &self.inner.tree,
-                    k_bytes,
-                    v_bytes,
-                    lmdb::put::Flags::empty(),
-                )
-            })?;
-            tx.commit()?;
-            Ok(())
-        })
-    }
-
-    fn delete<K: Key>(&mut self, k: &K) -> KvResult<()> {
-        let tx = lmdb::WriteTransaction::new(self.inner.tree.env())?;
-        k.as_bytes(|k_bytes| {
-            let mut access = tx.access();
-            access.del_key(&self.inner.tree, k_bytes).to_opt()
-        })?;
-        tx.commit()?;
-        Ok(())
-    }
-
-    fn new_batch() -> Self::Batch {
-        LmdbBatch::default()
-    }
-
-    fn write_batch(&mut self, inner_batch: Self::Batch) -> KvResult<()> {
-        let tx = lmdb::WriteTransaction::new(self.inner.tree.env())?;
-        {
-            let mut access = tx.access();
-            for (k, v) in inner_batch.upsert_ops {
-                access.put(
-                    &self.inner.tree,
-                    k.as_ref(),
-                    v.as_ref(),
-                    lmdb::put::Flags::empty(),
-                )?;
-            }
-            for k in inner_batch.remove_ops {
-                access.del_key(&self.inner.tree, k.as_ref()).to_opt()?;
-            }
-        }
-        tx.commit()?;
-        Ok(())
-    }
-
-    fn save(&self) -> KvResult<()> {
-        Ok(self.inner.tree.env().sync(true)?)
-    }
-}
diff --git a/rust-libs/tools/kv_typed/src/backend/memory.rs b/rust-libs/tools/kv_typed/src/backend/memory.rs
deleted file mode 100644
index f9c41870f..000000000
--- a/rust-libs/tools/kv_typed/src/backend/memory.rs
+++ /dev/null
@@ -1,284 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-//! Memory backend for KV Typed,
-
-use crate::*;
-use std::collections::BTreeMap;
-//use uninit::extension_traits::VecCapacity as _;
-
-#[derive(Clone, Copy, Debug)]
-pub struct Mem;
-
-#[derive(Clone, Debug, Default)]
-pub struct MemConf {
-    folder_path: Option<std::path::PathBuf>,
-}
-
-type KeyBytes = IVec;
-type ValueBytes = IVec;
-type Tree = BTreeMap<KeyBytes, ValueBytes>;
-
-impl Backend for Mem {
-    const NAME: &'static str = "mem";
-    type Col = MemCol;
-    type Conf = MemConf;
-
-    fn open(_conf: &Self::Conf) -> KvResult<Self> {
-        Ok(Mem)
-    }
-    fn open_col(&mut self, _conf: &Self::Conf, _col_name: &str) -> KvResult<Self::Col> {
-        /*if let Some(ref folder_path) = conf.folder_path {
-            MemCol::from_file(folder_path.join(col_name))
-        } else {*/
-        Ok(MemCol {
-            path: None,
-            tree: BTreeMap::new(),
-        })
-        //}
-    }
-}
-
-#[derive(Debug, Default)]
-pub struct MemBatch {
-    upsert_ops: Vec<(IVec, IVec)>,
-    remove_ops: Vec<IVec>,
-}
-
-impl BackendBatch for MemBatch {
-    fn upsert(&mut self, k: &[u8], v: &[u8]) {
-        self.upsert_ops.push((k.into(), v.into()));
-    }
-
-    fn remove(&mut self, k: &[u8]) {
-        self.remove_ops.push(k.into());
-    }
-}
-
-#[derive(Clone, Debug)]
-pub struct MemCol {
-    path: Option<std::path::PathBuf>,
-    tree: Tree,
-}
-
-impl BackendCol for MemCol {
-    type Batch = MemBatch;
-    type KeyBytes = KeyBytes;
-    type ValueBytes = ValueBytes;
-    type Iter = MemIter;
-
-    #[inline(always)]
-    fn new_batch() -> Self::Batch {
-        MemBatch::default()
-    }
-    #[inline(always)]
-    fn clear(&mut self) -> KvResult<()> {
-        self.tree.clear();
-        Ok(())
-    }
-    #[inline(always)]
-    fn count(&self) -> KvResult<usize> {
-        Ok(self.tree.len())
-    }
-    #[inline(always)]
-    fn contains_key<K: Key>(&self, k: &K) -> KvResult<bool> {
-        k.as_bytes(|k_bytes| Ok(self.tree.contains_key(k_bytes)))
-    }
-    #[inline(always)]
-    fn get<K: Key, V: Value>(&self, k: &K) -> KvResult<Option<V>> {
-        k.as_bytes(|k_bytes| {
-            self.tree
-                .get(k_bytes)
-                .map(|bytes| V::from_bytes(&bytes).map_err(|e| KvError::DeserError(e.into())))
-                .transpose()
-        })
-    }
-    #[inline(always)]
-    fn get_ref<K: Key, V: ValueZc, D, F: Fn(&V::Ref) -> KvResult<D>>(
-        &self,
-        k: &K,
-        f: F,
-    ) -> KvResult<Option<D>> {
-        k.as_bytes(|k_bytes| {
-            self.tree
-                .get(k_bytes)
-                .map(|bytes| {
-                    if let Some(layout_verified) =
-                        zerocopy::LayoutVerified::<_, V::Ref>::new(bytes.as_ref())
-                    {
-                        f(&layout_verified)
-                    } else {
-                        Err(KvError::DeserError(
-                            "Bytes are invalid length or alignment.".into(),
-                        ))
-                    }
-                })
-                .transpose()
-        })
-    }
-    #[inline(always)]
-    fn get_ref_slice<K: Key, V: ValueSliceZc, D, F: Fn(&[V::Elem]) -> KvResult<D>>(
-        &self,
-        k: &K,
-        f: F,
-    ) -> KvResult<Option<D>> {
-        k.as_bytes(|k_bytes| {
-            self.tree
-                .get(k_bytes)
-                .map(|bytes| {
-                    if let Some(layout_verified) =
-                        zerocopy::LayoutVerified::<_, [V::Elem]>::new_slice(
-                            &bytes[V::prefix_len()..],
-                        )
-                    {
-                        f(&layout_verified)
-                    } else {
-                        Err(KvError::DeserError(
-                            "Bytes are invalid length or alignment.".into(),
-                        ))
-                    }
-                })
-                .transpose()
-        })
-    }
-    #[inline(always)]
-    fn delete<K: Key>(&mut self, k: &K) -> KvResult<()> {
-        k.as_bytes(|k_bytes| self.tree.remove(k_bytes));
-        Ok(())
-    }
-    #[inline(always)]
-    fn put<K: Key, V: Value>(&mut self, k: &K, value: &V) -> KvResult<()> {
-        value.as_bytes(|value_bytes| {
-            k.as_bytes(|k_bytes| {
-                self.tree.insert(k_bytes.into(), value_bytes.into());
-            });
-            Ok(())
-        })
-    }
-    #[inline(always)]
-    fn write_batch(&mut self, inner_batch: Self::Batch) -> KvResult<()> {
-        for (k, v) in inner_batch.upsert_ops {
-            self.tree.insert(k, v);
-        }
-        for k in inner_batch.remove_ops {
-            self.tree.remove(&k);
-        }
-        Ok(())
-    }
-    #[inline(always)]
-    fn iter<K: Key, V: Value>(&self, range: RangeBytes) -> Self::Iter {
-        MemIter::new(unsafe {
-            // # Safety
-            // On front API, the iterator is given to a closure executed inside of a `ColRo` method,
-            // so that ensure borrowed tree keep alive
-            std::mem::transmute(self.tree.range(range))
-        })
-    }
-    #[inline(always)]
-    fn save(&self) -> KvResult<()> {
-        /*if let Some(ref file_path) = self.path {
-            let bytes = Self::tree_to_bytes(&self.tree);
-
-            let mut file =
-                std::fs::File::create(file_path).map_err(|e| KvError::BackendError(e.into()))?;
-            use std::io::Write as _;
-            file.write_all(&bytes[..])
-                .map_err(|e| KvError::BackendError(e.into()))?;
-        }*/
-
-        Ok(())
-    }
-}
-
-pub struct MemIter {
-    iter: std::collections::btree_map::Range<'static, KeyBytes, ValueBytes>,
-    reversed: bool,
-}
-
-impl MemIter {
-    fn new(
-        tree_iter: std::collections::btree_map::Range<'static, KeyBytes, ValueBytes>,
-    ) -> MemIter {
-        MemIter {
-            iter: tree_iter,
-            reversed: false,
-        }
-    }
-}
-
-impl Debug for MemIter {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        f.debug_struct("MemIter").field("0", &"???").finish()
-    }
-}
-impl Iterator for MemIter {
-    type Item = Result<(KeyBytes, ValueBytes), DynErr>;
-
-    #[inline(always)]
-    fn next(&mut self) -> Option<Self::Item> {
-        if self.reversed {
-            self.iter.next_back()
-        } else {
-            self.iter.next()
-        }
-        .map(|(k, v)| Ok((k.to_owned(), v.to_owned())))
-    }
-}
-
-impl ReversableIterator for MemIter {
-    #[inline(always)]
-    fn reverse(mut self) -> Self {
-        self.reversed = !self.reversed;
-        self
-    }
-}
-
-impl BackendIter<IVec, IVec> for MemIter {}
-
-#[cfg(test)]
-mod tests {
-    /*use super::*;
-
-    #[test]
-    fn test_save() -> KvResult<()> {
-        let mut tree = BTreeMap::new();
-
-        let k1 = IVec::from(&[1, 2, 3]);
-        let v1 = IVec::from(&[1, 2, 3, 4, 5]);
-        let k2 = IVec::from(&[1, 2]);
-        let v2 = IVec::from(&[]);
-        let k3 = IVec::from(&[1, 2, 3, 4, 5, 6, 7]);
-        let v3 = IVec::from(&[1, 2, 3, 4, 5, 6]);
-        let k4 = IVec::from(&[]);
-        let v4 = IVec::from(&[1, 2, 3, 4, 5, 6, 7]);
-
-        tree.insert(k1.clone(), v1.clone());
-        tree.insert(k2.clone(), v2.clone());
-        tree.insert(k3.clone(), v3.clone());
-        tree.insert(k4.clone(), v4.clone());
-
-        let bytes = MemCol::tree_to_bytes(&tree);
-
-        let tree2 = MemCol::tree_from_bytes(&bytes)?;
-
-        assert_eq!(tree2.len(), 4);
-        assert_eq!(tree2.get(&k1), Some(&v1));
-        assert_eq!(tree2.get(&k2), Some(&v2));
-        assert_eq!(tree2.get(&k3), Some(&v3));
-        assert_eq!(tree2.get(&k4), Some(&v4));
-
-        Ok(())
-    }*/
-}
diff --git a/rust-libs/tools/kv_typed/src/backend/memory_singleton.rs b/rust-libs/tools/kv_typed/src/backend/memory_singleton.rs
deleted file mode 100644
index 5f49a8cf3..000000000
--- a/rust-libs/tools/kv_typed/src/backend/memory_singleton.rs
+++ /dev/null
@@ -1,186 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-//! Memory backend for KV Typed,
-
-use crate::*;
-
-#[derive(Clone, Copy, Debug)]
-pub struct MemSingleton;
-
-#[derive(Clone, Copy, Debug, Default)]
-pub struct MemSingletonConf {
-    phantom: PhantomData<()>,
-}
-
-type KeyBytes = IVec;
-type ValueBytes = IVec;
-
-impl Backend for MemSingleton {
-    const NAME: &'static str = "mem_singleton";
-    type Col = MemCol;
-    type Conf = MemSingletonConf;
-
-    fn open(_conf: &Self::Conf) -> KvResult<Self> {
-        Ok(MemSingleton)
-    }
-    fn open_col(&mut self, _conf: &Self::Conf, _col_name: &str) -> KvResult<Self::Col> {
-        Ok(MemCol(None))
-    }
-}
-
-#[derive(Debug, Default)]
-pub struct MemBatch(Option<IVec>);
-
-impl BackendBatch for MemBatch {
-    fn upsert(&mut self, _k: &[u8], v: &[u8]) {
-        self.0 = Some(v.into());
-    }
-
-    fn remove(&mut self, _k: &[u8]) {
-        self.0 = None;
-    }
-}
-
-#[derive(Clone, Debug)]
-pub struct MemCol(Option<ValueBytes>);
-
-impl BackendCol for MemCol {
-    type Batch = MemBatch;
-    type KeyBytes = KeyBytes;
-    type ValueBytes = ValueBytes;
-    type Iter = MemIter;
-
-    #[inline(always)]
-    fn new_batch() -> Self::Batch {
-        MemBatch::default()
-    }
-    #[inline(always)]
-    fn clear(&mut self) -> KvResult<()> {
-        self.0 = None;
-        Ok(())
-    }
-    #[inline(always)]
-    fn count(&self) -> KvResult<usize> {
-        if self.0.is_some() {
-            Ok(1)
-        } else {
-            Ok(0)
-        }
-    }
-    #[inline(always)]
-    fn contains_key<K: Key>(&self, _k: &K) -> KvResult<bool> {
-        Ok(self.0.is_some())
-    }
-    #[inline(always)]
-    fn get<K: Key, V: Value>(&self, _k: &K) -> KvResult<Option<V>> {
-        self.0
-            .as_ref()
-            .map(|bytes| V::from_bytes(bytes).map_err(|e| KvError::DeserError(e.into())))
-            .transpose()
-    }
-    #[inline(always)]
-    fn get_ref<K: Key, V: ValueZc, D, F: Fn(&V::Ref) -> KvResult<D>>(
-        &self,
-        _k: &K,
-        f: F,
-    ) -> KvResult<Option<D>> {
-        self.0
-            .as_ref()
-            .map(|bytes| {
-                if let Some(layout_verified) =
-                    zerocopy::LayoutVerified::<_, V::Ref>::new(bytes.as_ref())
-                {
-                    f(&layout_verified)
-                } else {
-                    Err(KvError::DeserError(
-                        "Bytes are invalid length or alignment.".into(),
-                    ))
-                }
-            })
-            .transpose()
-    }
-    #[inline(always)]
-    fn get_ref_slice<K: Key, V: ValueSliceZc, D, F: Fn(&[V::Elem]) -> KvResult<D>>(
-        &self,
-        _k: &K,
-        f: F,
-    ) -> KvResult<Option<D>> {
-        self.0
-            .as_ref()
-            .map(|bytes| {
-                if let Some(layout_verified) =
-                    zerocopy::LayoutVerified::<_, [V::Elem]>::new_slice(&bytes[V::prefix_len()..])
-                {
-                    f(&layout_verified)
-                } else {
-                    Err(KvError::DeserError(
-                        "Bytes are invalid length or alignment.".into(),
-                    ))
-                }
-            })
-            .transpose()
-    }
-    #[inline(always)]
-    fn delete<K: Key>(&mut self, _k: &K) -> KvResult<()> {
-        self.0 = None;
-        Ok(())
-    }
-    #[inline(always)]
-    fn put<K: Key, V: Value>(&mut self, _k: &K, value: &V) -> KvResult<()> {
-        value.as_bytes(|value_bytes| {
-            self.0 = Some(value_bytes.into());
-            Ok(())
-        })
-    }
-    #[inline(always)]
-    fn write_batch(&mut self, inner_batch: Self::Batch) -> KvResult<()> {
-        self.0 = inner_batch.0;
-        Ok(())
-    }
-    #[inline(always)]
-    fn iter<K: Key, V: Value>(&self, _: RangeBytes) -> Self::Iter {
-        MemIter(self.0.clone())
-    }
-    #[inline(always)]
-    fn save(&self) -> KvResult<()> {
-        Ok(())
-    }
-}
-
-pub struct MemIter(Option<ValueBytes>);
-
-impl Debug for MemIter {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        f.debug_struct("MemIter").field("0", &"???").finish()
-    }
-}
-impl Iterator for MemIter {
-    type Item = Result<(KeyBytes, ValueBytes), DynErr>;
-
-    #[inline(always)]
-    fn next(&mut self) -> Option<Self::Item> {
-        self.0.take().map(|v| Ok((KeyBytes::default(), v)))
-    }
-}
-
-impl ReversableIterator for MemIter {
-    #[inline(always)]
-    fn reverse(self) -> Self {
-        self
-    }
-}
-
-impl BackendIter<IVec, IVec> for MemIter {}
diff --git a/rust-libs/tools/kv_typed/src/backend/mock.rs b/rust-libs/tools/kv_typed/src/backend/mock.rs
deleted file mode 100644
index 0d479a398..000000000
--- a/rust-libs/tools/kv_typed/src/backend/mock.rs
+++ /dev/null
@@ -1,85 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-//! KV Typed mock backend
-
-use super::MockBackendBatch;
-use crate::*;
-
-mockall::mock! {
-    pub BackendIter {}
-    trait Iterator {
-        type Item = Result<(IVec, IVec), DynErr>;
-
-        fn next(&mut self) -> Option<<Self as Iterator>::Item>;
-    }
-    trait ReversableIterator {
-        fn reverse(self) -> Self;
-    }
-}
-impl BackendIter<IVec, IVec> for MockBackendIter {}
-
-mockall::mock! {
-    pub BackendCol {}
-    trait Clone {
-        fn clone(&self) -> Self;
-    }
-    trait BackendCol {
-        type Batch = MockBackendBatch;
-        type KeyBytes = IVec;
-        type ValueBytes = IVec;
-        type Iter = MockBackendIter;
-
-        fn get<K: Key, V: Value>(&self, k: &K) -> KvResult<Option<V>>;
-        fn get_ref<K: Key, V: ValueZc, D, F: Fn(&V::Ref) -> KvResult<D>>(
-            &self,
-            k: &K,
-            f: F,
-        ) -> KvResult<Option<D>>;
-        fn get_ref_slice<K: Key, V: ValueSliceZc, D, F: Fn(&[V::Elem]) -> KvResult<D>>(
-            &self,
-            k: &K,
-            f: F,
-        ) -> KvResult<Option<D>>;
-        fn clear(&self) -> KvResult<()>;
-        fn count(&self) -> KvResult<usize>;
-        fn iter<K: Key, V: Value>(&self, range: RangeBytes) -> MockBackendIter;
-        fn put<K: Key, V: Value>(&self, k: &K, value: &V) -> KvResult<()>;
-        fn delete<K: Key>(&self, k: &K) -> KvResult<()>;
-        fn new_batch() -> MockBackendBatch;
-        fn write_batch(&self, inner_batch: MockBackendBatch) -> KvResult<()>;
-        fn save(&self) -> KvResult<()>;
-    }
-}
-impl Debug for MockBackendCol {
-    fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        unimplemented!()
-    }
-}
-
-mockall::mock! {
-    pub Backend {}
-    trait Clone {
-        fn clone(&self) -> Self;
-    }
-    trait Backend: 'static + Clone + Sized {
-        const NAME: &'static str = "mock";
-        type Col = MockBackendCol;
-        type Conf = ();
-
-        fn open(conf: &()) -> KvResult<Self>;
-        fn open_col(&mut self, conf: &(), col_name: &str) -> KvResult<MockBackendCol>;
-    }
-}
diff --git a/rust-libs/tools/kv_typed/src/backend/sled.rs b/rust-libs/tools/kv_typed/src/backend/sled.rs
deleted file mode 100644
index 3f97ef6de..000000000
--- a/rust-libs/tools/kv_typed/src/backend/sled.rs
+++ /dev/null
@@ -1,205 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-//! Sled backend for KV Typed,
-
-pub use sled::Config;
-
-use crate::*;
-
-#[derive(Clone, Debug)]
-pub struct Sled {
-    db: sled::Db,
-    trees: Vec<sled::Tree>,
-}
-
-impl Backend for Sled {
-    const NAME: &'static str = "sled";
-    type Col = SledCol;
-    type Conf = Config;
-
-    fn open(conf: &Self::Conf) -> KvResult<Self> {
-        Ok(Sled {
-            db: conf.open()?,
-            trees: Vec::new(),
-        })
-    }
-    fn open_col(&mut self, _conf: &Self::Conf, col_name: &str) -> KvResult<Self::Col> {
-        let tree = self.db.open_tree(col_name)?;
-        self.trees.push(tree.clone());
-        Ok(SledCol(tree))
-    }
-}
-
-impl BackendBatch for sled::Batch {
-    fn upsert(&mut self, k: &[u8], v: &[u8]) {
-        self.insert(k, v)
-    }
-
-    fn remove(&mut self, k: &[u8]) {
-        self.remove(k)
-    }
-}
-
-#[derive(Clone, Debug)]
-pub struct SledCol(sled::Tree);
-
-impl BackendCol for SledCol {
-    type Batch = sled::Batch;
-    type KeyBytes = IVec;
-    type ValueBytes = IVec;
-    type Iter = SledIter;
-
-    #[inline(always)]
-    fn new_batch() -> Self::Batch {
-        sled::Batch::default()
-    }
-    #[inline(always)]
-    fn clear(&mut self) -> KvResult<()> {
-        self.0.clear()?;
-        Ok(())
-    }
-    #[inline(always)]
-    fn count(&self) -> KvResult<usize> {
-        Ok(self.0.len())
-    }
-    #[inline(always)]
-    fn contains_key<K: Key>(&self, k: &K) -> KvResult<bool> {
-        k.as_bytes(|k_bytes| Ok(self.0.contains_key(k_bytes)?))
-    }
-    #[inline(always)]
-    fn get<K: Key, V: Value>(&self, k: &K) -> KvResult<Option<V>> {
-        k.as_bytes(|k_bytes| {
-            self.0
-                .get(k_bytes)?
-                .map(|bytes| V::from_bytes(&bytes).map_err(|e| KvError::DeserError(e.into())))
-                .transpose()
-        })
-    }
-    #[inline(always)]
-    fn get_ref<K: Key, V: ValueZc, D, F: Fn(&V::Ref) -> KvResult<D>>(
-        &self,
-        k: &K,
-        f: F,
-    ) -> KvResult<Option<D>> {
-        k.as_bytes(|k_bytes| {
-            self.0
-                .get(k_bytes)?
-                .map(|bytes| {
-                    if let Some(layout_verified) =
-                        zerocopy::LayoutVerified::<_, V::Ref>::new(bytes.as_ref())
-                    {
-                        f(&layout_verified)
-                    } else {
-                        Err(KvError::DeserError(
-                            "Bytes are invalid length or alignment.".into(),
-                        ))
-                    }
-                })
-                .transpose()
-        })
-    }
-    #[inline(always)]
-    fn get_ref_slice<K: Key, V: ValueSliceZc, D, F: Fn(&[V::Elem]) -> KvResult<D>>(
-        &self,
-        k: &K,
-        f: F,
-    ) -> KvResult<Option<D>> {
-        k.as_bytes(|k_bytes| {
-            self.0
-                .get(k_bytes)?
-                .map(|bytes| {
-                    if let Some(layout_verified) =
-                        zerocopy::LayoutVerified::<_, [V::Elem]>::new_slice(
-                            &bytes[V::prefix_len()..],
-                        )
-                    {
-                        f(&layout_verified)
-                    } else {
-                        Err(KvError::DeserError(
-                            "Bytes are invalid length or alignment.".into(),
-                        ))
-                    }
-                })
-                .transpose()
-        })
-    }
-    #[inline(always)]
-    fn delete<K: Key>(&mut self, k: &K) -> KvResult<()> {
-        k.as_bytes(|k_bytes| self.0.remove(k_bytes))?;
-        Ok(())
-    }
-    #[inline(always)]
-    fn put<K: Key, V: Value>(&mut self, k: &K, value: &V) -> KvResult<()> {
-        value.as_bytes(|value_bytes| {
-            k.as_bytes(|k_bytes| self.0.insert(k_bytes, value_bytes))?;
-            Ok(())
-        })
-    }
-    #[inline(always)]
-    fn write_batch(&mut self, inner_batch: Self::Batch) -> KvResult<()> {
-        self.0.apply_batch(inner_batch)?;
-        Ok(())
-    }
-    #[inline(always)]
-    fn iter<K: Key, V: Value>(&self, range: RangeBytes) -> Self::Iter {
-        SledIter {
-            iter: self.0.range(range),
-            reversed: false,
-        }
-    }
-    #[inline(always)]
-    fn save(&self) -> KvResult<()> {
-        self.0.flush()?;
-        Ok(())
-    }
-}
-
-pub struct SledIter {
-    iter: sled::Iter,
-    reversed: bool,
-}
-
-impl Debug for SledIter {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        f.debug_struct("SledIter")
-            .field("0", &"sled::Iter")
-            .finish()
-    }
-}
-impl Iterator for SledIter {
-    type Item = Result<(IVec, IVec), DynErr>;
-
-    #[inline(always)]
-    fn next(&mut self) -> Option<Self::Item> {
-        if self.reversed {
-            self.iter.next_back()
-        } else {
-            self.iter.next()
-        }
-        .map(|res| res.map_err(Box::new).map_err(Into::into))
-    }
-}
-impl ReversableIterator for SledIter {
-    #[inline(always)]
-    fn reverse(self) -> Self {
-        SledIter {
-            iter: self.iter,
-            reversed: !self.reversed,
-        }
-    }
-}
-
-impl BackendIter<IVec, IVec> for SledIter {}
diff --git a/rust-libs/tools/kv_typed/src/batch.rs b/rust-libs/tools/kv_typed/src/batch.rs
deleted file mode 100644
index 51d120ea6..000000000
--- a/rust-libs/tools/kv_typed/src/batch.rs
+++ /dev/null
@@ -1,106 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-use std::collections::{BTreeMap, HashMap, HashSet};
-
-#[derive(Debug)]
-pub struct Batch<BC: BackendCol, C: DbCollectionRw> {
-    phantom: PhantomData<BC>,
-    pub(crate) tree: BTreeMap<IVec, Option<IVec>>,
-    upsert_ops: HashMap<C::K, C::V>,
-    delete_ops: HashSet<C::K>,
-}
-
-#[derive(Debug, PartialEq)]
-pub enum BatchGet<'v, V: Value> {
-    None,
-    Deleted,
-    Updated(&'v V),
-}
-
-impl<BC: BackendCol, C: DbCollectionRw> Default for Batch<BC, C> {
-    fn default() -> Self {
-        Batch {
-            phantom: PhantomData,
-            tree: BTreeMap::default(),
-            upsert_ops: HashMap::default(),
-            delete_ops: HashSet::default(),
-        }
-    }
-}
-
-impl<BC: BackendCol, C: DbCollectionRw> Batch<BC, C> {
-    pub fn clear(&mut self) {
-        self.tree.clear();
-        self.upsert_ops.clear();
-        self.delete_ops.clear();
-    }
-    pub fn get(&self, k: &C::K) -> BatchGet<C::V> {
-        if self.delete_ops.contains(k) {
-            BatchGet::Deleted
-        } else if let Some(v) = self.upsert_ops.get(k) {
-            BatchGet::Updated(v)
-        } else {
-            BatchGet::None
-        }
-    }
-    pub fn upsert(&mut self, k: C::K, v: C::V) {
-        let _ = k.as_bytes(|k_bytes| {
-            v.as_bytes(|v_bytes| {
-                self.tree
-                    .insert(IVec::from(k_bytes), Some(IVec::from(v_bytes)));
-            })
-        });
-        self.upsert_ops.insert(k, v);
-    }
-    pub fn remove(&mut self, k: C::K) {
-        let _ = k.as_bytes(|k_bytes| {
-            self.tree.insert(IVec::from(k_bytes), None);
-        });
-        self.upsert_ops.remove(&k);
-        self.delete_ops.insert(k);
-    }
-    #[doc(hidden)]
-    pub fn into_backend_batch(self) -> BC::Batch {
-        let mut backend_batch = BC::Batch::default();
-        for (k_bytes, v_bytes_opt) in self.tree {
-            if let Some(v_bytes) = v_bytes_opt {
-                backend_batch.upsert(k_bytes.as_ref(), v_bytes.as_ref());
-            } else {
-                backend_batch.remove(k_bytes.as_ref());
-            }
-        }
-        backend_batch
-    }
-    #[doc(hidden)]
-    pub fn into_backend_batch_and_events(self) -> (BC::Batch, SmallVec<[C::Event; 4]>) {
-        let mut backend_batch = BC::Batch::default();
-        for (k_bytes, v_bytes_opt) in self.tree {
-            if let Some(v_bytes) = v_bytes_opt {
-                backend_batch.upsert(k_bytes.as_ref(), v_bytes.as_ref());
-            } else {
-                backend_batch.remove(k_bytes.as_ref());
-            }
-        }
-        let mut events: SmallVec<[C::Event; 4]> = self
-            .upsert_ops
-            .into_iter()
-            .map(|(k, v)| C::Event::upsert(k, v))
-            .collect();
-        events.extend(self.delete_ops.into_iter().map(C::Event::remove));
-        (backend_batch, events)
-    }
-}
diff --git a/rust-libs/tools/kv_typed/src/bytes.rs b/rust-libs/tools/kv_typed/src/bytes.rs
deleted file mode 100644
index 54a4d29dd..000000000
--- a/rust-libs/tools/kv_typed/src/bytes.rs
+++ /dev/null
@@ -1,62 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-//! KV Typed bytes
-
-use crate::*;
-
-pub trait KeyBytes: AsRef<[u8]> + Debug + Ord {}
-impl<T> KeyBytes for T where T: AsRef<[u8]> + Debug + Ord {}
-pub trait ValueBytes: AsRef<[u8]> + Debug {}
-impl<T> ValueBytes for T where T: AsRef<[u8]> + Debug {}
-
-#[derive(Debug, Eq, PartialEq)]
-pub enum CowKB<'a, B: KeyBytes> {
-    B(&'a [u8]),
-    O(B),
-}
-impl<'a, B: KeyBytes> AsRef<[u8]> for CowKB<'a, B> {
-    fn as_ref(&self) -> &[u8] {
-        match self {
-            CowKB::B(b_ref) => b_ref,
-            CowKB::O(b) => b.as_ref(),
-        }
-    }
-}
-
-impl<'a, B: KeyBytes> PartialOrd for CowKB<'a, B> {
-    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
-        self.as_ref().partial_cmp(other.as_ref())
-    }
-}
-impl<'a, B: KeyBytes> Ord for CowKB<'a, B> {
-    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
-        self.as_ref().cmp(other.as_ref())
-    }
-}
-
-#[derive(Debug)]
-pub enum CowVB<'a, B: ValueBytes> {
-    B(&'a [u8]),
-    O(B),
-}
-impl<'a, B: ValueBytes> AsRef<[u8]> for CowVB<'a, B> {
-    fn as_ref(&self) -> &[u8] {
-        match self {
-            CowVB::B(b_ref) => b_ref,
-            CowVB::O(b) => b.as_ref(),
-        }
-    }
-}
diff --git a/rust-libs/tools/kv_typed/src/collection_inner.rs b/rust-libs/tools/kv_typed/src/collection_inner.rs
deleted file mode 100644
index 452cc3f79..000000000
--- a/rust-libs/tools/kv_typed/src/collection_inner.rs
+++ /dev/null
@@ -1,43 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-use crate::*;
-
-#[derive(Debug)]
-pub struct ColInner<BC: BackendCol, E: EventTrait> {
-    pub(crate) backend_col: BC,
-    subscribers: ColSubscribers<E>,
-}
-
-impl<BC: BackendCol, E: EventTrait> ColInner<BC, E> {
-    pub(crate) fn new(backend_col: BC) -> (Self, SubscriptionsSender<E>) {
-        let subscribers = ColSubscribers::<E>::default();
-        let subscription_sender = subscribers.get_subscription_sender();
-
-        (
-            ColInner {
-                backend_col,
-                subscribers,
-            },
-            subscription_sender,
-        )
-    }
-    pub(crate) fn notify_subscribers(&mut self, events: Events<E>) {
-        // Add new subscribers, notify all subscribers them prune died subscribers
-        self.subscribers.add_new_subscribers();
-        let died_subscribers = self.subscribers.notify_subscribers(Arc::new(events));
-        self.subscribers.prune_subscribers(died_subscribers);
-    }
-}
diff --git a/rust-libs/tools/kv_typed/src/collection_ro.rs b/rust-libs/tools/kv_typed/src/collection_ro.rs
deleted file mode 100644
index 1ab536010..000000000
--- a/rust-libs/tools/kv_typed/src/collection_ro.rs
+++ /dev/null
@@ -1,267 +0,0 @@
-use crate::*;
-
-pub trait DbCollectionRo: Sized {
-    type BackendCol: BackendCol;
-    type K: Key;
-    type V: Value;
-    type Event: EventTrait<K = Self::K, V = Self::V>;
-
-    fn contains_key(&self, k: &Self::K) -> KvResult<bool>;
-    fn count(&self) -> KvResult<usize>;
-    fn get(&self, k: &Self::K) -> KvResult<Option<Self::V>>;
-    /// Don't worry about complex iter type. Use it like an `impl Iterator<Item=KvResult<(K, V)>>`.
-    fn iter<
-        D: Send + Sync,
-        R: 'static + RangeBounds<Self::K>,
-        F: FnOnce(
-            KvIter<
-                Self::BackendCol,
-                <Self::BackendCol as BackendCol>::KeyBytes,
-                <Self::BackendCol as BackendCol>::ValueBytes,
-                <Self::BackendCol as BackendCol>::Iter,
-                Self::K,
-                Self::V,
-            >,
-        ) -> D,
-    >(
-        &self,
-        range: R,
-        f: F,
-    ) -> D;
-    /// Don't worry about complex iter type. Use it like an `impl Iterator<Item=KvResult<(K, V)>>`.
-    fn iter_rev<
-        D: Send + Sync,
-        R: 'static + RangeBounds<Self::K>,
-        F: FnOnce(
-            KvIter<
-                Self::BackendCol,
-                <Self::BackendCol as BackendCol>::KeyBytes,
-                <Self::BackendCol as BackendCol>::ValueBytes,
-                <Self::BackendCol as BackendCol>::Iter,
-                Self::K,
-                Self::V,
-            >,
-        ) -> D,
-    >(
-        &self,
-        range: R,
-        f: F,
-    ) -> D;
-    fn subscribe(&self, subscriber_sender: Subscriber<Self::Event>) -> KvResult<()>;
-}
-
-#[cfg(feature = "mock")]
-mockall::mock! {
-    pub ColRo<E: EventTrait> {}
-    trait DbCollectionRo {
-        type BackendCol = MockBackendCol;
-        type K = E::K;
-        type V = E::V;
-        type Event = E;
-
-        fn count(&self) -> KvResult<usize>;
-        fn get(&self, k: &E::K) -> KvResult<Option<E::V>>;
-        fn iter<R: 'static + RangeBounds<E::K>>(&self, range: R)
-        -> KvIter<MockBackendCol, MockBackendIter, E::K, E::V>;
-        fn subscribe(&self, subscriber_sender: Subscriber<E>) -> KvResult<()>;
-    }
-}
-
-type ColRoReader<'r, BC, E> = parking_lot::RwLockReadGuard<'r, ColInner<BC, E>>;
-
-#[derive(Debug)]
-pub struct ColRo<BC: BackendCol, E: EventTrait> {
-    pub(crate) inner: Arc<parking_lot::RwLock<ColInner<BC, E>>>,
-    pub(crate) subscription_sender: SubscriptionsSender<E>,
-}
-
-impl<BC: BackendCol, E: EventTrait> Clone for ColRo<BC, E> {
-    fn clone(&self) -> Self {
-        Self {
-            inner: Arc::clone(&self.inner),
-            subscription_sender: self.subscription_sender.clone(),
-        }
-    }
-}
-impl<BC: BackendCol, E: EventTrait> DbCollectionRo for ColRo<BC, E> {
-    type BackendCol = BC;
-    type K = E::K;
-    type V = E::V;
-    type Event = E;
-
-    #[inline(always)]
-    fn contains_key(&self, k: &Self::K) -> KvResult<bool> {
-        let r = self.inner.read();
-        r.backend_col.contains_key(k)
-    }
-    #[inline(always)]
-    fn count(&self) -> KvResult<usize> {
-        let r = self.inner.read();
-        r.backend_col.count()
-    }
-    #[inline(always)]
-    fn get(&self, k: &Self::K) -> KvResult<Option<Self::V>> {
-        let r = self.inner.read();
-        r.backend_col.get(k)
-    }
-    #[inline(always)]
-    fn iter<
-        D: Send + Sync,
-        R: 'static + RangeBounds<Self::K>,
-        F: FnOnce(
-            KvIter<
-                Self::BackendCol,
-                <Self::BackendCol as BackendCol>::KeyBytes,
-                <Self::BackendCol as BackendCol>::ValueBytes,
-                <Self::BackendCol as BackendCol>::Iter,
-                Self::K,
-                Self::V,
-            >,
-        ) -> D,
-    >(
-        &self,
-        range: R,
-        f: F,
-    ) -> D {
-        let range: RangeBytes = crate::iter::convert_range::<Self::K, R>(range);
-        let r = self.inner.read();
-        let iter = r.backend_col.iter::<Self::K, Self::V>(range);
-        f(KvIter::new(iter))
-    }
-    #[inline(always)]
-    fn iter_rev<
-        D: Send + Sync,
-        R: 'static + RangeBounds<Self::K>,
-        F: FnOnce(
-            KvIter<
-                Self::BackendCol,
-                <Self::BackendCol as BackendCol>::KeyBytes,
-                <Self::BackendCol as BackendCol>::ValueBytes,
-                <Self::BackendCol as BackendCol>::Iter,
-                Self::K,
-                Self::V,
-            >,
-        ) -> D,
-    >(
-        &self,
-        range: R,
-        f: F,
-    ) -> D {
-        let range: RangeBytes = crate::iter::convert_range::<Self::K, R>(range);
-        let r = self.inner.read();
-        let iter = r.backend_col.iter::<Self::K, Self::V>(range).reverse();
-        f(KvIter::new(iter))
-    }
-    #[inline(always)]
-    fn subscribe(&self, subscriber_sender: Subscriber<Self::Event>) -> KvResult<()> {
-        self.subscription_sender
-            .try_send(subscriber_sender)
-            .map_err(|_| KvError::FailToSubscribe)
-    }
-}
-
-pub trait DbCollectionRoGetRef<V: ValueZc>: DbCollectionRo<V = V> {
-    fn get_ref<D, F: Fn(&V::Ref) -> KvResult<D>>(
-        &self,
-        k: &<Self as DbCollectionRo>::K,
-        f: F,
-    ) -> KvResult<Option<D>>;
-}
-
-impl<V: ValueZc, BC: BackendCol, E: EventTrait<V = V>> DbCollectionRoGetRef<V> for ColRo<BC, E> {
-    fn get_ref<D, F: Fn(&V::Ref) -> KvResult<D>>(&self, k: &E::K, f: F) -> KvResult<Option<D>> {
-        let r = self.inner.read();
-        r.backend_col.get_ref::<E::K, V, D, F>(k, f)
-    }
-}
-
-pub trait DbCollectionRoGetRefSlice<V: ValueSliceZc>: DbCollectionRo<V = V> {
-    fn get_ref_slice<D, F: Fn(&[V::Elem]) -> KvResult<D>>(
-        &self,
-        k: &<Self as DbCollectionRo>::K,
-        f: F,
-    ) -> KvResult<Option<D>>;
-}
-
-impl<V: ValueSliceZc, BC: BackendCol, E: EventTrait<V = V>> DbCollectionRoGetRefSlice<V>
-    for ColRo<BC, E>
-{
-    fn get_ref_slice<D, F: Fn(&[V::Elem]) -> KvResult<D>>(
-        &self,
-        k: &E::K,
-        f: F,
-    ) -> KvResult<Option<D>> {
-        let r = self.inner.read();
-        r.backend_col.get_ref_slice::<E::K, V, D, F>(k, f)
-    }
-}
-
-pub trait DbCollectionRoIterRefSlice<'r, BC: BackendCol, K: KeyZc, V: ValueSliceZc, READER>:
-    DbCollectionRo<K = K, V = V>
-{
-    fn iter_ref_slice<D, R, F>(&'r self, range: R, f: F) -> KvIterRefSlice<BC, D, K, V, F, READER>
-    where
-        K: KeyZc,
-        V: ValueSliceZc,
-        R: 'static + RangeBounds<K>,
-        F: FnMut(&K::Ref, &[V::Elem]) -> KvResult<D>;
-    fn iter_ref_slice_rev<D, R, F>(
-        &'r self,
-        range: R,
-        f: F,
-    ) -> KvIterRefSlice<BC, D, K, V, F, READER>
-    where
-        K: KeyZc,
-        V: ValueSliceZc,
-        R: 'static + RangeBounds<K>,
-        F: FnMut(&K::Ref, &[V::Elem]) -> KvResult<D>;
-}
-
-impl<'r, K: KeyZc, V: ValueSliceZc, BC: BackendCol, E: EventTrait<K = K, V = V>>
-    DbCollectionRoIterRefSlice<'r, BC, K, V, ColRoReader<'r, BC, E>> for ColRo<BC, E>
-{
-    fn iter_ref_slice<D, R, F>(
-        &'r self,
-        range: R,
-        f: F,
-    ) -> KvIterRefSlice<BC, D, K, V, F, ColRoReader<'r, BC, E>>
-    where
-        K: KeyZc,
-        V: ValueSliceZc,
-        R: 'static + RangeBounds<K>,
-        F: FnMut(&K::Ref, &[V::Elem]) -> KvResult<D>,
-    {
-        let range: RangeBytes = crate::iter::convert_range::<Self::K, R>(range);
-        let reader = self.inner.read();
-        let inner_iter = reader.backend_col.iter_ref_slice::<D, K, V, F>(range, f);
-
-        KvIterRefSlice {
-            inner: inner_iter,
-            reader: OwnedOrRef::Owned(reader),
-        }
-    }
-
-    fn iter_ref_slice_rev<D, R, F>(
-        &'r self,
-        range: R,
-        f: F,
-    ) -> KvIterRefSlice<BC, D, K, V, F, ColRoReader<'r, BC, E>>
-    where
-        K: KeyZc,
-        V: ValueSliceZc,
-        R: 'static + RangeBounds<K>,
-        F: FnMut(&K::Ref, &[V::Elem]) -> KvResult<D>,
-    {
-        let range: RangeBytes = crate::iter::convert_range::<Self::K, R>(range);
-        let reader = self.inner.read();
-        let inner_iter = reader
-            .backend_col
-            .iter_ref_slice::<D, K, V, F>(range, f)
-            .reverse();
-
-        KvIterRefSlice {
-            inner: inner_iter,
-            reader: OwnedOrRef::Owned(reader),
-        }
-    }
-}
diff --git a/rust-libs/tools/kv_typed/src/collection_rw.rs b/rust-libs/tools/kv_typed/src/collection_rw.rs
deleted file mode 100644
index 13ab15956..000000000
--- a/rust-libs/tools/kv_typed/src/collection_rw.rs
+++ /dev/null
@@ -1,100 +0,0 @@
-use crate::*;
-use parking_lot::{
-    RwLockUpgradableReadGuard as UpgradableReadGuard, RwLockWriteGuard as WriteGuard,
-};
-
-pub trait DbCollectionRw {
-    type K: Key;
-    type V: Value;
-    type Event: EventTrait<K = Self::K, V = Self::V>;
-
-    fn clear(&self) -> KvResult<()>;
-    fn remove(&self, k: Self::K) -> KvResult<()>;
-    fn save(&self) -> KvResult<()>;
-    fn upsert(&self, k: Self::K, v: Self::V) -> KvResult<()>;
-}
-
-#[derive(Debug)]
-pub struct ColRw<BC: BackendCol, E: EventTrait> {
-    pub(crate) inner: ColRo<BC, E>,
-}
-
-impl<BC: BackendCol, E: EventTrait> Clone for ColRw<BC, E> {
-    fn clone(&self) -> Self {
-        Self {
-            inner: self.inner.clone(),
-        }
-    }
-}
-
-impl<BC: BackendCol, E: EventTrait> DbCollectionRw for ColRw<BC, E> {
-    type K = E::K;
-    type V = E::V;
-    type Event = E;
-
-    fn clear(&self) -> KvResult<()> {
-        let mut w = self.inner.inner.write();
-        w.backend_col.clear()?;
-        let events = smallvec::smallvec![E::clear()];
-        w.notify_subscribers(events);
-        Ok(())
-    }
-    fn remove(&self, k: Self::K) -> KvResult<()> {
-        let mut w = self.inner.inner.write();
-        w.backend_col.delete(&k)?;
-        let events = smallvec::smallvec![E::remove(k)];
-        w.notify_subscribers(events);
-        Ok(())
-    }
-    fn save(&self) -> KvResult<()> {
-        let w = self.inner.inner.write();
-        w.backend_col.save()?;
-        Ok(())
-    }
-    fn upsert(&self, k: Self::K, v: Self::V) -> KvResult<()> {
-        let mut w = self.inner.inner.write();
-        w.backend_col.put(&k, &v)?;
-        let events = smallvec::smallvec![E::upsert(k, v)];
-        w.notify_subscribers(events);
-        Ok(())
-    }
-}
-
-impl<BC: BackendCol, E: EventTrait> ColRw<BC, E> {
-    pub fn new(backend_col: BC) -> Self {
-        let (col_inner, subscription_sender) = ColInner::new(backend_col);
-        Self {
-            inner: ColRo {
-                inner: Arc::new(parking_lot::RwLock::new(col_inner)),
-                subscription_sender,
-            },
-        }
-    }
-    pub fn to_ro(&self) -> &ColRo<BC, E> {
-        &self.inner
-    }
-    #[doc(hidden)]
-    /// For internal usage only MUST NOT USE
-    pub fn upgradable_read(&self) -> UpgradableReadGuard<'_, ColInner<BC, E>> {
-        self.inner.inner.upgradable_read()
-    }
-    pub fn write_batch(&self, batch: Batch<BC, Self>) -> KvResult<()> {
-        let (backend_batch, events) = batch.into_backend_batch_and_events();
-        let mut w = self.inner.inner.write();
-        w.backend_col.write_batch(backend_batch)?;
-        w.notify_subscribers(events);
-        Ok(())
-    }
-    #[doc(hidden)]
-    /// For internal usage only MUST NOT USE
-    pub fn write_backend_batch(
-        &self,
-        backend_batch: BC::Batch,
-        events: Events<E>,
-        write_guard: &mut WriteGuard<ColInner<BC, E>>,
-    ) -> KvResult<()> {
-        write_guard.backend_col.write_batch(backend_batch)?;
-        write_guard.notify_subscribers(events);
-        Ok(())
-    }
-}
diff --git a/rust-libs/tools/kv_typed/src/db_schema.rs b/rust-libs/tools/kv_typed/src/db_schema.rs
deleted file mode 100644
index 657d7797d..000000000
--- a/rust-libs/tools/kv_typed/src/db_schema.rs
+++ /dev/null
@@ -1,242 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-#[macro_export]
-macro_rules! db_schema {
-    ($db_name:ident, [ $([$col_path:literal, $col_name:ident, $K:ty, $V:ty]),*, ]) => {
-        paste::paste! {
-            $(
-                // Define each collection event type
-                #[derive(Debug, PartialEq)]
-                pub enum [<$col_name Event>] {
-                    Upsert { key: $K, value: $V },
-                    Remove { key: $K },
-                    RemoveAll,
-                }
-                impl kv_typed::prelude::EventTrait for [<$col_name Event>] {
-                    type K = $K;
-                    type V = $V;
-
-                    fn clear() -> Self { Self::RemoveAll }
-                    fn upsert(k: Self::K, v: Self::V) -> Self { Self::Upsert { key: k, value: v, } }
-                    fn remove(k: Self::K) -> Self { Self::Remove { key: k } }
-                }
-            )*
-            // Inner module used to hide internals types that must not be exposed on public api
-            pub use __inner::{[<$db_name Db>], [<$db_name DbRo>], [<$db_name DbWritable>], [<$db_name DbReadable>], [<$db_name DbTxRw>]};
-            mod __inner {
-                use super::*;
-                use kv_typed::prelude::*;
-                // DbCollections
-                #[derive(Clone, Debug)]
-                pub struct [<$db_name ColsRo>]<BC: BackendCol> {
-                    $([<$col_name:snake>]: ColRo<BC, [<$col_name Event>]>,)*
-                }
-                #[derive(Clone, Debug)]
-                pub struct [<$db_name ColsRw>]<BC: BackendCol> {
-                    $([<$col_name:snake>]: ColRw<BC, [<$col_name Event>]>,)*
-                }
-                impl<BC: BackendCol> [<$db_name ColsRw>]<BC> {
-                    fn to_ro(&self) -> [<$db_name ColsRo>]<BC> {
-                        [<$db_name ColsRo>] {
-                            $([<$col_name:snake>]: self.[<$col_name:snake>].to_ro().clone(),)*
-                        }
-                    }
-                }
-                // Db
-                #[derive(Debug)]
-                pub struct [<$db_name Db>]<B: Backend> {
-                    collections: [<$db_name ColsRw>]<B::Col>,
-                }
-                impl<B: Backend> [<$db_name Db>]<B> {
-                    pub const NAME: &'static str = stringify!([<$db_name:snake>]);
-                }
-                impl<B: Backend> Clone for [<$db_name Db>]<B> {
-                    fn clone(&self) -> Self {
-                        [<$db_name Db>] {
-                            collections: self.collections.clone(),
-                        }
-                    }
-                }
-                #[cfg(feature = "explorer")]
-                impl<B: Backend> kv_typed::explorer::DbExplorable for [<$db_name Db>]<B> {
-                    fn explore<'a>(
-                        &self,
-                        collection_name: &str,
-                        action: kv_typed::explorer::ExplorerAction<'a>,
-                        stringify_json_value: fn(serde_json::Value) -> serde_json::Value,
-                    ) -> KvResult<std::result::Result<kv_typed::explorer::ExplorerActionResponse, ExplorerActionErr>> {
-                        $( if stringify!([<$col_name:snake>]) == collection_name {
-                            return action.exec(&self.collections.[<$col_name:snake>], stringify_json_value);
-                        } )*
-                        Ok(Err(ExplorerActionErr(format!("collection '{}' not exist in database '{}'.", collection_name, stringify!([<$db_name Db>])).into())))
-                    }
-                    fn list_collections() -> Vec<(&'static str, &'static str, &'static str)> {
-                        vec![
-                            $((stringify!([<$col_name:snake>]), stringify!($K), stringify!($V)),)*
-                        ]
-                    }
-                }
-                // Batch
-                pub struct [<$db_name DbBatch>]<B: Backend> {
-                    $([<$col_name:snake>]: Batch<B::Col, ColRw<B::Col, [<$col_name Event>]>>,)*
-                }
-                impl<B: Backend> Default for [<$db_name DbBatch>]<B> {
-                    fn default() -> Self {
-                        [<$db_name DbBatch>] {
-                            $([<$col_name:snake>]: Batch::default(),)*
-                        }
-                    }
-                }
-                impl<B: Backend> [<$db_name DbBatch>]<B> {
-                    $(pub fn [<$col_name:snake>](&mut self) -> &mut Batch<B::Col, ColRw<B::Col, [<$col_name Event>]>> { &mut self.[<$col_name:snake>] })*
-                }
-                // impl TransactionalWrite for Db
-                #[derive(Debug)]
-                pub struct [<$db_name DbTxRw>]<'tx, BC: BackendCol> {
-                    $(pub [<$col_name:snake>]: TxColRw<'tx, BC, [<$col_name Event>]>,)*
-                }
-                impl<'tx, B: Backend> TransactionalWrite<'tx, B::Col> for &'tx [<$db_name Db>]<B> {
-                    type TxCols = [<$db_name DbTxRw>]<'tx, B::Col>;
-
-                    fn write<D, F: FnOnce(Self::TxCols) -> KvResult<D>>(&'tx self, f: F) -> KvResult<D> {
-                        $(let [<$col_name:snake _upgradable_guard>] = self.collections.[<$col_name:snake>].upgradable_read();)*
-
-                        $(let mut [<$col_name:snake _batch>] =  Batch::<B::Col, ColRw<B::Col, [<$col_name Event>]>>::default();)*
-
-                        let db_tx = [<$db_name DbTxRw>] {
-                            $([<$col_name:snake>]: TxColRw::new(
-                                unsafe { std::mem::transmute(&mut [<$col_name:snake _batch>]) },
-                                unsafe { std::mem::transmute(&[<$col_name:snake _upgradable_guard>]) },
-                            ),)*
-                        };
-
-                        let data = f(db_tx)?;
-
-                        // Prepare commit
-                        $(let ([<$col_name:snake _backend_batch>], [<$col_name:snake _events>]) = [<$col_name:snake _batch>].into_backend_batch_and_events();)*
-
-                        // Acquire exclusive lock
-                        $(let mut [<$col_name:snake _write_guard>] = parking_lot::RwLockUpgradableReadGuard::upgrade([<$col_name:snake _upgradable_guard>]);)*;
-
-                        // Commit
-                        $(self.collections.[<$col_name:snake>].write_backend_batch(
-                            [<$col_name:snake _backend_batch>],
-                            [<$col_name:snake _events>],
-                            &mut [<$col_name:snake _write_guard>],
-                        )?;)*
-
-                        Ok(data)
-                    }
-                }
-                // DbRo
-                #[derive(Debug)]
-                pub struct [<$db_name DbRo>]<B: Backend> {
-                    collections: [<$db_name ColsRo>]<B::Col>,
-                }
-                impl<B: Backend> [<$db_name DbRo>]<B> {
-                    pub const NAME: &'static str = stringify!([<$db_name:snake>]);
-                }
-                impl<B: Backend> Clone for [<$db_name DbRo>]<B> {
-                    fn clone(&self) -> Self {
-                        [<$db_name DbRo>] {
-                            collections: self.collections.clone(),
-                        }
-                    }
-                }
-                // Read operations
-                pub trait [<$db_name DbReadable>]: Sized {
-                    type Backend: Backend;
-
-                    $(fn [<$col_name:snake>](&self) -> &ColRo<<Self::Backend as Backend>::Col, [<$col_name Event>]>;)*
-                }
-                impl<B: Backend> [<$db_name DbReadable>] for [<$db_name Db>]<B> {
-                    type Backend = B;
-
-                    $(fn [<$col_name:snake>](&self) -> &ColRo<B::Col, [<$col_name Event>]> { &self.collections.[<$col_name:snake>].to_ro() })*
-                }
-                impl<B: Backend> [<$db_name DbReadable>] for [<$db_name DbRo>]<B>{
-                    type Backend = B;
-
-                    $(fn [<$col_name:snake>](&self) -> &ColRo<B::Col, [<$col_name Event>]> { &self.collections.[<$col_name:snake>] })*
-                }
-                // Write operations
-                pub trait [<$db_name DbWritable>]: [<$db_name DbReadable>] {
-                    type Backend: Backend;
-                    type Batch;
-                    $(type [<$col_name ColRw>]: DbCollectionRw;)*
-                    type DbRo: Sized;
-
-                    fn clear(&self) -> KvResult<()>;
-                    fn get_ro_handler(&self) -> Self::DbRo;
-                    fn open(
-                        backend_conf: <<Self as [<$db_name DbWritable>]>::Backend as kv_typed::backend::Backend>::Conf,
-                    ) -> KvResult <Self>;
-                    fn new_batch(&self) -> Self::Batch;
-                    fn save(&self) -> KvResult<()>;
-                    fn write_batch(&self, batch: Self::Batch) -> KvResult<()>;
-                    $(fn [<$col_name:snake _write>](&self) -> &Self::[<$col_name ColRw>];)*
-                }
-                impl<B: Backend> [<$db_name DbWritable>] for [<$db_name Db>]<B> {
-                    type Backend = B;
-                    type Batch = [<$db_name DbBatch>]<B>;
-                    $(type [<$col_name ColRw>] = ColRw<B::Col, [<$col_name Event>]>;)*
-                    type DbRo = [<$db_name DbRo>]<B>;
-
-                    #[inline(always)]
-                    fn clear(&self) -> KvResult<()> {
-                        $(self.collections.[<$col_name:snake>].clear()?;)*
-                        Ok(())
-                    }
-                    #[inline(always)]
-                    fn get_ro_handler(&self) -> Self::DbRo {
-                        [<$db_name DbRo>] {
-                            collections: self.collections.to_ro(),
-                        }
-                    }
-                    #[inline(always)]
-                    fn new_batch(&self) -> Self::Batch {
-                        <[<$db_name DbBatch>]::<B>>::default()
-                    }
-                    fn write_batch(&self, batch: Self::Batch) -> KvResult<()> {
-                        $(self.collections.[<$col_name:snake>].write_batch(batch.[<$col_name:snake>])?;)*
-                        Ok(())
-                    }
-                    fn open(
-                        backend_conf: <<Self as [<$db_name DbWritable>]>::Backend as kv_typed::backend::Backend>::Conf,
-                    ) -> KvResult <Self> {
-                        let mut db = B::open(&backend_conf)?;
-                        Ok([<$db_name Db>] {
-                            collections: [<$db_name ColsRw>] {
-                                $([<$col_name:snake>]: <ColRw<B::Col, [<$col_name Event>]>>::new(
-                                    db.open_col(&backend_conf, $col_path)?
-                                ),)*
-                            },
-                        })
-                    }
-                    #[inline(always)]
-                    fn save(&self) -> KvResult<()> {
-                        $(self.collections.[<$col_name:snake>].save()?;)*
-                        Ok(())
-                    }
-                    $(
-                        #[inline(always)]
-                        fn [<$col_name:snake _write>](&self) -> &ColRw<B::Col, [<$col_name Event>]> { &self.collections.[<$col_name:snake>] }
-                    )*
-                }
-            }
-        }
-    };
-}
diff --git a/rust-libs/tools/kv_typed/src/error.rs b/rust-libs/tools/kv_typed/src/error.rs
deleted file mode 100644
index 8762ef816..000000000
--- a/rust-libs/tools/kv_typed/src/error.rs
+++ /dev/null
@@ -1,75 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-//! KV Typed error type
-
-use crate::*;
-
-pub type DynErr = Box<dyn Error + Send + Sync + 'static>;
-
-/// KV Typed error
-pub type KvResult<T> = Result<T, KvError>;
-
-#[allow(type_alias_bounds)]
-pub(crate) type BackendResult<BC: BackendCol> =
-    Result<(<BC as BackendCol>::KeyBytes, <BC as BackendCol>::ValueBytes), DynErr>;
-
-/// KV Typed error
-#[derive(Debug, Error)]
-pub enum KvError {
-    /// Backend error
-    #[error("Backend error: {0}")]
-    BackendError(DynErr),
-    /// Custom
-    #[error("{0}")]
-    Custom(DynErr),
-    // DB corrupted
-    #[error("DB corrupted:{0}")]
-    DbCorrupted(String),
-    // Error at serialisation or deserialisation
-    #[error("DeserError: {0}")]
-    DeserError(DynErr),
-    /// FailToCreateDbFolder
-    #[error("FailToCreateDbFolder: {0}")]
-    FailToCreateDbFolder(std::io::Error),
-    /// FailToSubscribe
-    #[error("FailToSubscribe")]
-    FailToSubscribe,
-}
-
-impl From<std::io::Error> for KvError {
-    fn from(e: std::io::Error) -> Self {
-        KvError::BackendError(e.into())
-    }
-}
-
-#[cfg(feature = "leveldb_backend")]
-impl From<crate::backend::leveldb::LevelDbError> for KvError {
-    fn from(e: crate::backend::leveldb::LevelDbError) -> Self {
-        KvError::BackendError(Box::new(e).into())
-    }
-}
-#[cfg(feature = "lmdb_backend")]
-impl From<lmdb_zero::Error> for KvError {
-    fn from(e: lmdb_zero::Error) -> Self {
-        KvError::BackendError(e.into())
-    }
-}
-#[cfg(feature = "sled_backend")]
-impl From<sled::Error> for KvError {
-    fn from(e: sled::Error) -> Self {
-        KvError::BackendError(Box::new(e).into())
-    }
-}
diff --git a/rust-libs/tools/kv_typed/src/event.rs b/rust-libs/tools/kv_typed/src/event.rs
deleted file mode 100644
index 0a2c79abe..000000000
--- a/rust-libs/tools/kv_typed/src/event.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-//! KV Typed event
-
-use crate::*;
-
-/// Database events
-pub type Events<E> = SmallVec<[E; 4]>;
-
-/// Event trait
-pub trait EventTrait: 'static + Debug + PartialEq + Send + Sync {
-    type K: Key;
-    type V: Value;
-
-    fn clear() -> Self;
-    fn upsert(k: Self::K, v: Self::V) -> Self;
-    fn remove(k: Self::K) -> Self;
-}
diff --git a/rust-libs/tools/kv_typed/src/explorer.rs b/rust-libs/tools/kv_typed/src/explorer.rs
deleted file mode 100644
index e23b2a053..000000000
--- a/rust-libs/tools/kv_typed/src/explorer.rs
+++ /dev/null
@@ -1,529 +0,0 @@
-use crate::*;
-use rayon::{iter::ParallelBridge, prelude::*};
-use std::num::NonZeroUsize;
-
-pub trait DbExplorable {
-    fn explore<'a>(
-        &self,
-        collection_name: &str,
-        action: ExplorerAction<'a>,
-        stringify_json_value: fn(serde_json::Value) -> serde_json::Value,
-    ) -> KvResult<Result<ExplorerActionResponse, ExplorerActionErr>>;
-    fn list_collections() -> Vec<(&'static str, &'static str, &'static str)>;
-}
-
-#[derive(Debug, Error)]
-#[error("Fail to parse key: {0}")]
-pub struct FromExplorerKeyErr(pub DynErr);
-
-#[derive(Debug, Error)]
-#[error("Fail to parse value: {0}")]
-pub struct FromExplorerValueErr(pub DynErr);
-
-pub trait ExplorableKey: Sized {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerKeyErr>;
-    fn to_explorer_string(&self) -> KvResult<String>;
-}
-
-impl ExplorableKey for () {
-    fn from_explorer_str(_: &str) -> Result<Self, FromExplorerKeyErr> {
-        Ok(())
-    }
-
-    fn to_explorer_string(&self) -> KvResult<String> {
-        Ok(String::with_capacity(0))
-    }
-}
-
-impl ExplorableKey for String {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerKeyErr> {
-        Ok(source.to_owned())
-    }
-
-    fn to_explorer_string(&self) -> KvResult<String> {
-        Ok(self.clone())
-    }
-}
-
-macro_rules! impl_explorable_key_for_numbers {
-    ($($T:ty),*) => {$(
-        impl ExplorableKey for $T {
-            fn from_explorer_str(source: &str) -> Result<Self, FromExplorerKeyErr> {
-                source.parse().map_err(|e| FromExplorerKeyErr(Box::new(e)))
-            }
-
-            fn to_explorer_string(&self) -> KvResult<String> {
-                Ok(format!("{}", self))
-            }
-        }
-    )*};
-}
-impl_explorable_key_for_numbers!(usize, u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64);
-
-macro_rules! impl_explorable_key_for_be_numbers {
-    ($($T:ty),*) => {$(
-        impl ExplorableKey for $T {
-            fn from_explorer_str(source: &str) -> Result<Self, FromExplorerKeyErr> {
-                Ok(Self(source.parse().map_err(|e| FromExplorerKeyErr(Box::new(e)))?))
-            }
-
-            fn to_explorer_string(&self) -> KvResult<String> {
-                Ok(format!("{}", self.0))
-            }
-        }
-    )*};
-}
-impl_explorable_key_for_be_numbers!(U32BE, U64BE);
-
-pub trait ExplorableValue: Sized {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerValueErr>;
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value>;
-}
-
-impl ExplorableValue for () {
-    fn from_explorer_str(_: &str) -> Result<Self, FromExplorerValueErr> {
-        Ok(())
-    }
-
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        Ok(serde_json::Value::String(String::with_capacity(0)))
-    }
-}
-
-impl ExplorableValue for String {
-    fn from_explorer_str(source: &str) -> Result<Self, FromExplorerValueErr> {
-        Ok(source.to_owned())
-    }
-
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        Ok(serde_json::Value::String(self.clone()))
-    }
-}
-
-macro_rules! impl_explorable_value_for_numbers {
-    ($($T:ty),*) => {$(
-        impl ExplorableValue for $T {
-            fn from_explorer_str(source: &str) -> Result<Self, FromExplorerValueErr> {
-                source.parse().map_err(|e| FromExplorerValueErr(Box::new(e)))
-            }
-
-            #[allow(trivial_numeric_casts)]
-            fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-                Ok(serde_json::Value::Number(serde_json::Number::from_f64(*self as f64).expect("too large number")))
-            }
-        }
-    )*};
-}
-
-impl_explorable_value_for_numbers!(
-    usize, u8, u16, u32, u64, u128, isize, i8, i16, i32, i64, i128, f32, f64
-);
-
-impl<T, E> ExplorableValue for Vec<T>
-where
-    T: Display + FromStr<Err = E>,
-    E: Error + Send + Sync + 'static,
-{
-    fn from_explorer_str(source: &str) -> Result<Vec<T>, FromExplorerValueErr> {
-        if let serde_json::Value::Array(json_array) =
-            serde_json::Value::from_str(source).map_err(|e| FromExplorerValueErr(e.into()))?
-        {
-            let mut vec = Vec::with_capacity(json_array.len());
-            for value in json_array {
-                if let serde_json::Value::String(string) = value {
-                    vec.push(<T>::from_str(&string).map_err(|e| FromExplorerValueErr(e.into()))?);
-                } else {
-                    return Err(FromExplorerValueErr(
-                        format!("Expected array of {}.", stringify!(T)).into(),
-                    ));
-                }
-            }
-            Ok(vec)
-        } else {
-            Err(FromExplorerValueErr(
-                format!("Expected array of {}.", stringify!(T)).into(),
-            ))
-        }
-    }
-
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        Ok(serde_json::Value::Array(
-            self.iter()
-                .map(|elem| serde_json::Value::String(format!("{}", elem)))
-                .collect(),
-        ))
-    }
-}
-
-macro_rules! impl_explorable_value_for_smallvec {
-    ($($N:literal),*) => {$(
-        impl<T, E> ExplorableValue for SmallVec<[T; $N]>
-        where
-            T: Display + FromStr<Err = E>,
-            E: Error + Send + Sync + 'static,
-        {
-            fn from_explorer_str(source: &str) -> Result<SmallVec<[T; $N]>, FromExplorerValueErr> {
-                if let serde_json::Value::Array(json_array) =
-                    serde_json::Value::from_str(source).map_err(|e| FromExplorerValueErr(e.into()))?
-                {
-                    let mut svec = SmallVec::with_capacity(json_array.len());
-                    for value in json_array {
-                        if let serde_json::Value::String(string) = value {
-                            svec.push(<T>::from_str(&string).map_err(|e| FromExplorerValueErr(e.into()))?);
-                        } else {
-                            return Err(FromExplorerValueErr(format!("Expected array of {}.", stringify!(T)).into()));
-                        }
-                    }
-                    Ok(svec)
-                } else {
-                    Err(FromExplorerValueErr(format!("Expected array of {}.", stringify!(T)).into()))
-                }
-            }
-
-            fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-                Ok(serde_json::Value::Array(
-                    self.iter()
-                        .map(|elem| serde_json::Value::String(format!("{}", elem)))
-                        .collect(),
-                ))
-            }
-        }
-    )*};
-}
-impl_explorable_value_for_smallvec!(2, 4, 8, 16, 32, 64);
-
-impl<T, E> ExplorableValue for BTreeSet<T>
-where
-    T: Display + FromStr<Err = E> + Ord,
-    E: Error + Send + Sync + 'static,
-{
-    fn from_explorer_str(source: &str) -> Result<BTreeSet<T>, FromExplorerValueErr> {
-        if let serde_json::Value::Array(json_array) =
-            serde_json::Value::from_str(source).map_err(|e| FromExplorerValueErr(e.into()))?
-        {
-            let mut bt_set = BTreeSet::new();
-            for value in json_array {
-                if let serde_json::Value::String(string) = value {
-                    bt_set.insert(
-                        <T>::from_str(&string).map_err(|e| FromExplorerValueErr(e.into()))?,
-                    );
-                } else {
-                    return Err(FromExplorerValueErr(
-                        format!("Expected array of {}.", stringify!(T)).into(),
-                    ));
-                }
-            }
-            Ok(bt_set)
-        } else {
-            Err(FromExplorerValueErr(
-                format!("Expected array of {}.", stringify!(T)).into(),
-            ))
-        }
-    }
-
-    fn to_explorer_json(&self) -> KvResult<serde_json::Value> {
-        Ok(serde_json::Value::Array(
-            self.iter()
-                .map(|elem| serde_json::Value::String(format!("{}", elem)))
-                .collect(),
-        ))
-    }
-}
-
-#[derive(Debug)]
-pub enum ExplorerAction<'a> {
-    Count,
-    Get {
-        key: &'a str,
-    },
-    Find {
-        key_min: Option<String>,
-        key_max: Option<String>,
-        key_regex: Option<regex::Regex>,
-        value_regex: Option<regex::Regex>,
-        limit: Option<usize>,
-        reverse: bool,
-        step: NonZeroUsize,
-    },
-    Put {
-        key: &'a str,
-        value: &'a str,
-    },
-    Delete {
-        key: &'a str,
-    },
-}
-
-#[derive(Debug, PartialEq)]
-pub struct EntryFound {
-    pub key: String,
-    pub value: serde_json::Value,
-    pub captures: Option<ValueCaptures>,
-}
-
-#[derive(Debug, PartialEq)]
-pub struct ValueCaptures(pub SmallVec<[SmallVec<[Option<String>; 8]>; 8]>);
-
-#[derive(Debug, PartialEq)]
-pub enum ExplorerActionResponse {
-    Count(usize),
-    Get(Option<serde_json::Value>),
-    Find(Vec<EntryFound>),
-    PutOk,
-    DeleteOk,
-}
-
-#[derive(Debug, Error)]
-#[error("Fail to exec explorer action: {0}")]
-pub struct ExplorerActionErr(pub DynErr);
-impl From<FromExplorerKeyErr> for ExplorerActionErr {
-    fn from(e: FromExplorerKeyErr) -> Self {
-        ExplorerActionErr(e.0)
-    }
-}
-impl From<FromExplorerValueErr> for ExplorerActionErr {
-    fn from(e: FromExplorerValueErr) -> Self {
-        ExplorerActionErr(e.0)
-    }
-}
-
-impl<'a> ExplorerAction<'a> {
-    pub fn exec<BC: BackendCol, E: EventTrait>(
-        self,
-        col: &ColRw<BC, E>,
-        stringify_json_value: fn(serde_json::Value) -> serde_json::Value,
-    ) -> KvResult<Result<ExplorerActionResponse, ExplorerActionErr>> {
-        Ok(match self {
-            Self::Count => Ok(ExplorerActionResponse::Count(col.to_ro().count()?)),
-            Self::Get { key } => match E::K::from_explorer_str(key) {
-                Ok(k) => Ok(ExplorerActionResponse::Get(
-                    col.to_ro()
-                        .get(&k)?
-                        .map(|v| v.to_explorer_json())
-                        .transpose()?,
-                )),
-                Err(e) => Err(e.into()),
-            },
-            Self::Find {
-                key_min,
-                key_max,
-                key_regex,
-                value_regex,
-                limit,
-                reverse,
-                step,
-            } => match define_range::<E::K>(key_min, key_max) {
-                Ok(range) => Ok(ExplorerActionResponse::Find(match range {
-                    Range::Full => Self::get_range_inner(
-                        col.to_ro(),
-                        ..,
-                        key_regex,
-                        value_regex,
-                        limit,
-                        reverse,
-                        step,
-                        stringify_json_value,
-                    )?,
-                    Range::From(range) => Self::get_range_inner(
-                        col.to_ro(),
-                        range,
-                        key_regex,
-                        value_regex,
-                        limit,
-                        reverse,
-                        step,
-                        stringify_json_value,
-                    )?,
-                    Range::FromTo(range) => Self::get_range_inner(
-                        col.to_ro(),
-                        range,
-                        key_regex,
-                        value_regex,
-                        limit,
-                        reverse,
-                        step,
-                        stringify_json_value,
-                    )?,
-                    Range::To(range) => Self::get_range_inner(
-                        col.to_ro(),
-                        range,
-                        key_regex,
-                        value_regex,
-                        limit,
-                        reverse,
-                        step,
-                        stringify_json_value,
-                    )?,
-                })),
-                Err(e) => Err(ExplorerActionErr(e)),
-            },
-            Self::Put { key, value } => match E::K::from_explorer_str(key) {
-                Ok(k) => match E::V::from_explorer_str(value) {
-                    Ok(v) => {
-                        col.upsert(k, v)?;
-                        Ok(ExplorerActionResponse::PutOk)
-                    }
-                    Err(e) => Err(e.into()),
-                },
-                Err(e) => Err(e.into()),
-            },
-            Self::Delete { key } => match E::K::from_explorer_str(key) {
-                Ok(k) => {
-                    col.remove(k)?;
-                    Ok(ExplorerActionResponse::DeleteOk)
-                }
-                Err(e) => Err(e.into()),
-            },
-        })
-    }
-    #[allow(clippy::too_many_arguments)]
-    fn get_range_inner<BC: BackendCol, E: EventTrait, R: 'static + RangeBounds<E::K>>(
-        col: &ColRo<BC, E>,
-        range: R,
-        key_regex: Option<regex::Regex>,
-        value_regex: Option<regex::Regex>,
-        limit: Option<usize>,
-        reverse: bool,
-        step: NonZeroUsize,
-        stringify_json_value: fn(serde_json::Value) -> serde_json::Value,
-    ) -> KvResult<Vec<EntryFound>> {
-        let filter_map_closure = move |entry_res| {
-            stringify_and_filter_entry_res::<E::K, E::V>(
-                entry_res,
-                key_regex.as_ref(),
-                value_regex.as_ref(),
-                stringify_json_value,
-            )
-        };
-
-        if let Some(limit) = limit {
-            if reverse {
-                col.iter_rev(range, |iter| {
-                    iter.step_by(step.get())
-                        .filter_map(filter_map_closure)
-                        .take(limit)
-                        .collect()
-                })
-            } else {
-                col.iter(range, |iter| {
-                    iter.step_by(step.get())
-                        .filter_map(filter_map_closure)
-                        .take(limit)
-                        .collect()
-                })
-            }
-        } else {
-            {
-                let (send, recv) = unbounded();
-
-                let handler = std::thread::spawn(move || {
-                    let iter = recv.into_iter().step_by(step.get()).par_bridge();
-
-                    iter.filter_map(filter_map_closure).collect()
-                });
-
-                if reverse {
-                    col.iter_rev(range, |iter| {
-                        for entry_res in iter {
-                            if send.try_send(entry_res).is_err() {
-                                return handler.join().expect("child thread panic");
-                            }
-                        }
-                        drop(send);
-
-                        handler.join().expect("child thread panic")
-                    })
-                } else {
-                    col.iter(range, |iter| {
-                        for entry_res in iter {
-                            if send.try_send(entry_res).is_err() {
-                                return handler.join().expect("child thread panic");
-                            }
-                        }
-                        drop(send);
-
-                        handler.join().expect("child thread panic")
-                    })
-                }
-            }
-        }
-    }
-}
-
-enum Range<K> {
-    Full,
-    From(core::ops::RangeFrom<K>),
-    To(core::ops::RangeToInclusive<K>),
-    FromTo(core::ops::RangeInclusive<K>),
-}
-
-fn define_range<K: Key>(
-    key_min_opt: Option<String>,
-    key_max_opt: Option<String>,
-) -> Result<Range<K>, DynErr> {
-    if let Some(key_min) = key_min_opt {
-        let k_min = K::from_explorer_str(&key_min)?;
-        if let Some(key_max) = key_max_opt {
-            let k_max = K::from_explorer_str(&key_max)?;
-            Ok(Range::FromTo(core::ops::RangeInclusive::new(k_min, k_max)))
-        } else {
-            Ok(Range::From(core::ops::RangeFrom { start: k_min }))
-        }
-    } else if let Some(key_max) = key_max_opt {
-        let k_max = K::from_explorer_str(&key_max)?;
-        Ok(Range::To(core::ops::RangeToInclusive { end: k_max }))
-    } else {
-        Ok(Range::Full)
-    }
-}
-
-fn stringify_and_filter_entry_res<K: Key, V: Value>(
-    entry_res: KvResult<(K, V)>,
-    key_regex_opt: Option<&regex::Regex>,
-    value_regex_opt: Option<&regex::Regex>,
-    stringify_json_value: fn(serde_json::Value) -> serde_json::Value,
-) -> Option<KvResult<EntryFound>> {
-    match entry_res {
-        Ok((k, v)) => match k.to_explorer_string() {
-            Ok(key_string) => {
-                if let Some(key_regex) = key_regex_opt {
-                    if !key_regex.is_match(&key_string) {
-                        return None;
-                    }
-                }
-                match v.to_explorer_json() {
-                    Ok(mut value_json) => {
-                        value_json = stringify_json_value(value_json);
-                        let captures = if let Some(value_regex) = value_regex_opt {
-                            let value_string = value_json.to_string();
-                            if !value_regex.is_match(&value_string) {
-                                return None;
-                            }
-                            Some(ValueCaptures(
-                                value_regex
-                                    .captures_iter(&value_string)
-                                    .map(|caps| {
-                                        caps.iter()
-                                            .skip(1)
-                                            .map(|m_opt| m_opt.map(|m| m.as_str().to_owned()))
-                                            .collect::<SmallVec<[Option<String>; 8]>>()
-                                    })
-                                    .collect(),
-                            ))
-                        } else {
-                            None
-                        };
-                        Some(Ok(EntryFound {
-                            key: key_string,
-                            value: value_json,
-                            captures,
-                        }))
-                    }
-                    Err(e) => Some(Err(e)),
-                }
-            }
-            Err(e) => Some(Err(e)),
-        },
-        Err(e) => Some(Err(e)),
-    }
-}
diff --git a/rust-libs/tools/kv_typed/src/from_bytes.rs b/rust-libs/tools/kv_typed/src/from_bytes.rs
deleted file mode 100644
index 138f9ff8c..000000000
--- a/rust-libs/tools/kv_typed/src/from_bytes.rs
+++ /dev/null
@@ -1,127 +0,0 @@
-use crate::*;
-
-#[derive(Clone, Copy, Debug, Error)]
-#[error("Corrupted DB: {0} bytes are wrong aligned or have invalid length")]
-pub struct LayoutVerifiedErr(pub &'static str);
-
-pub trait FromBytes: Sized {
-    type Err: Error + Send + Sync + 'static;
-
-    /// Create Self from bytes.
-    fn from_bytes(bytes: &[u8]) -> Result<Self, Self::Err>;
-}
-
-impl FromBytes for () {
-    type Err = std::convert::Infallible;
-
-    fn from_bytes(_: &[u8]) -> Result<Self, Self::Err> {
-        Ok(())
-    }
-}
-
-macro_rules! impl_from_bytes_for_numbers {
-    ($($T:ty),*) => {$(
-        impl FromBytes for $T {
-            type Err = std::array::TryFromSliceError;
-
-            fn from_bytes(bytes: &[u8]) -> Result<Self, Self::Err> {
-                Ok(<$T>::from_le_bytes(bytes.try_into()?))
-            }
-        }
-    )*};
-}
-impl_from_bytes_for_numbers!(
-    usize, u8, u16, u32, u64, u128, isize, i8, i16, i32, i64, i128, f32, f64
-);
-
-macro_rules! impl_from_bytes_for_be_numbers {
-    ($(($T:ty, $INT:ty)),*) => {$(
-        impl FromBytes for $T {
-            type Err = std::array::TryFromSliceError;
-
-            fn from_bytes(bytes: &[u8]) -> Result<Self, Self::Err> {
-                Ok(Self(<$INT>::from_be_bytes(bytes.try_into()?)))
-            }
-        }
-    )*};
-}
-impl_from_bytes_for_be_numbers!((U32BE, u32), (U64BE, u64));
-
-impl FromBytes for String {
-    type Err = std::str::Utf8Error;
-
-    fn from_bytes(bytes: &[u8]) -> Result<Self, Self::Err> {
-        Ok(std::str::from_utf8(bytes)?.to_owned())
-    }
-}
-
-macro_rules! impl_from_bytes_for_smallvec {
-    ($($N:literal),*) => {$(
-        impl<T> FromBytes for SmallVec<[T; $N]>
-        where
-            T: Copy + zerocopy::FromBytes,
-        {
-            type Err = LayoutVerifiedErr;
-
-            fn from_bytes(bytes: &[u8]) -> Result<Self, Self::Err> {
-                let layout_verified = zerocopy::LayoutVerified::<_, [T]>::new_slice(bytes)
-                    .ok_or_else(|| LayoutVerifiedErr(stringify!(T)).into())?;
-                Ok(SmallVec::from_slice(layout_verified.into_slice()))
-            }
-        }
-    )*};
-}
-impl_from_bytes_for_smallvec!(1, 2, 4, 8, 16, 32, 64);
-
-impl<T> FromBytes for Vec<T>
-where
-    T: Copy + Default + zerocopy::FromBytes,
-{
-    type Err = LayoutVerifiedErr;
-
-    fn from_bytes(bytes: &[u8]) -> Result<Self, Self::Err> {
-        let layout_verified = zerocopy::LayoutVerified::<_, [T]>::new_slice(bytes)
-            .ok_or(LayoutVerifiedErr(stringify!(Vec<T>)))?;
-        let slice = layout_verified.into_slice();
-        let mut vec = Vec::with_capacity(slice.len());
-        vec.resize_with(slice.len(), Default::default);
-        vec.copy_from_slice(slice);
-        Ok(vec)
-    }
-}
-
-impl<T> FromBytes for BTreeSet<T>
-where
-    T: Copy + zerocopy::FromBytes + Ord,
-{
-    type Err = LayoutVerifiedErr;
-
-    fn from_bytes(bytes: &[u8]) -> Result<Self, Self::Err> {
-        let layout_verified = zerocopy::LayoutVerified::<_, [T]>::new_slice(bytes)
-            .ok_or(LayoutVerifiedErr(stringify!(BTreeSet<T>)))?;
-        let slice = layout_verified.into_slice();
-        Ok(slice.iter().copied().collect())
-    }
-}
-
-impl<T> FromBytes for HashSet<T>
-where
-    T: Copy + Eq + zerocopy::FromBytes + std::hash::Hash,
-{
-    type Err = LayoutVerifiedErr;
-
-    fn from_bytes(bytes: &[u8]) -> Result<Self, Self::Err> {
-        let layout_verified = zerocopy::LayoutVerified::<_, [T]>::new_slice(bytes)
-            .ok_or(LayoutVerifiedErr(stringify!(HashSet<T>)))?;
-        let slice = layout_verified.into_slice();
-        Ok(slice.iter().copied().collect())
-    }
-}
-
-impl FromBytes for IVec {
-    type Err = std::convert::Infallible;
-
-    fn from_bytes(bytes: &[u8]) -> Result<Self, Self::Err> {
-        Ok(Self::from(bytes))
-    }
-}
diff --git a/rust-libs/tools/kv_typed/src/iter.rs b/rust-libs/tools/kv_typed/src/iter.rs
deleted file mode 100644
index 8671cb182..000000000
--- a/rust-libs/tools/kv_typed/src/iter.rs
+++ /dev/null
@@ -1,214 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-//! KV Typed iterators
-
-pub mod keys;
-pub mod values;
-
-use crate::*;
-
-pub trait ReversableIterator: Iterator + Sized {
-    fn reverse(self) -> Self;
-
-    #[inline(always)]
-    fn last(self) -> Option<Self::Item> {
-        self.reverse().next()
-    }
-}
-
-pub trait ResultIter<T, E>: Iterator<Item = Result<T, E>> + Sized {
-    #[inline(always)]
-    fn next_res(&mut self) -> Result<Option<T>, E> {
-        self.next().transpose()
-    }
-}
-impl<I, T, E> ResultIter<T, E> for I where I: Iterator<Item = Result<T, E>> + Sized {}
-
-pub type RangeBytes = (Bound<IVec>, Bound<IVec>);
-
-#[derive(Debug)]
-pub struct KvIter<
-    C: BackendCol,
-    KB: KeyBytes,
-    VB: ValueBytes,
-    BI: BackendIter<KB, VB>,
-    K: Key,
-    V: Value,
-> {
-    backend_iter: BI,
-    phantom: PhantomData<(C, KB, VB, K, V)>,
-}
-
-impl<C: BackendCol, KB: KeyBytes, VB: ValueBytes, BI: BackendIter<KB, VB>, K: Key, V: Value>
-    Iterator for KvIter<C, KB, VB, BI, K, V>
-{
-    type Item = KvResult<(K, V)>;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        match self.backend_iter.next() {
-            Some(Ok((key_bytes, value_bytes))) => match K::from_bytes(key_bytes.as_ref()) {
-                Ok(key) => match V::from_bytes(value_bytes.as_ref()) {
-                    Ok(value) => Some(Ok((key, value))),
-                    Err(e) => Some(Err(KvError::DeserError(e.into()))),
-                },
-                Err(e) => Some(Err(KvError::DeserError(e.into()))),
-            },
-            Some(Err(e)) => Some(Err(KvError::BackendError(e))),
-            None => None,
-        }
-    }
-}
-
-impl<C: BackendCol, KB: KeyBytes, VB: ValueBytes, BI: BackendIter<KB, VB>, K: Key, V: Value>
-    KvIter<C, KB, VB, BI, K, V>
-{
-    pub fn new(backend_iter: BI) -> Self {
-        Self {
-            backend_iter,
-            phantom: PhantomData,
-        }
-    }
-}
-
-pub trait EntryIter {
-    type K: Key;
-    type V: Value;
-    type KeysIter: Iterator<Item = KvResult<Self::K>>;
-    type ValuesIter: Iterator<Item = KvResult<Self::V>>;
-
-    fn keys(self) -> Self::KeysIter;
-    fn values(self) -> Self::ValuesIter;
-}
-
-impl<C: BackendCol, KB: KeyBytes, VB: ValueBytes, BI: BackendIter<KB, VB>, K: Key, V: Value>
-    EntryIter for KvIter<C, KB, VB, BI, K, V>
-{
-    type K = K;
-    type V = V;
-    type KeysIter = KvIterKeys<C, KB, VB, BI, K>;
-    type ValuesIter = KvIterValues<C, KB, VB, BI, K, V>;
-
-    fn keys(self) -> KvIterKeys<C, KB, VB, BI, K> {
-        KvIterKeys::new(self.backend_iter)
-    }
-    fn values(self) -> KvIterValues<C, KB, VB, BI, K, V> {
-        KvIterValues::new(self.backend_iter)
-    }
-}
-
-pub(crate) fn convert_range<K: Key, RK: RangeBounds<K>>(range: RK) -> RangeBytes {
-    let range_start = convert_bound(range.start_bound());
-    let range_end = convert_bound(range.end_bound());
-    (range_start, range_end)
-}
-
-#[inline(always)]
-fn convert_bound<K: Key>(bound_key: Bound<&K>) -> Bound<IVec> {
-    match bound_key {
-        Bound::Included(key) => Bound::Included(key.as_bytes(|key_bytes| key_bytes.into())),
-        Bound::Excluded(key) => Bound::Excluded(key.as_bytes(|key_bytes| key_bytes.into())),
-        Bound::Unbounded => Bound::Unbounded,
-    }
-}
-
-#[allow(dead_code, missing_debug_implementations)]
-pub struct KvIterRefSlice<'db, BC, D, K, V, F, R>
-where
-    BC: BackendCol,
-    K: KeyZc,
-    V: ValueSliceZc,
-    F: FnMut(&K::Ref, &[V::Elem]) -> KvResult<D>,
-{
-    pub(crate) inner: KvInnerIterRefSlice<BC, D, K, V, F>,
-    pub(crate) reader: OwnedOrRef<'db, R>,
-}
-impl<'db, BC, D, K, V, F, R> Iterator for KvIterRefSlice<'db, BC, D, K, V, F, R>
-where
-    BC: BackendCol,
-    K: KeyZc,
-    V: ValueSliceZc,
-    F: FnMut(&K::Ref, &[V::Elem]) -> KvResult<D>,
-{
-    type Item = KvResult<D>;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        self.inner.next()
-    }
-}
-
-#[allow(missing_debug_implementations)]
-pub struct KvInnerIterRefSlice<BC, D, K, V, F>
-where
-    BC: BackendCol,
-    K: KeyZc,
-    V: ValueSliceZc,
-    F: FnMut(&K::Ref, &[V::Elem]) -> KvResult<D>,
-{
-    pub(crate) backend_iter: BC::Iter,
-    pub(crate) f: F,
-    pub(crate) phantom: PhantomData<(D, K, V)>,
-}
-impl<BC, D, K, V, F> Iterator for KvInnerIterRefSlice<BC, D, K, V, F>
-where
-    BC: BackendCol,
-    K: KeyZc,
-    V: ValueSliceZc,
-    F: FnMut(&K::Ref, &[V::Elem]) -> KvResult<D>,
-{
-    type Item = KvResult<D>;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        match self.backend_iter.next() {
-            Some(Ok((k_bytes, v_bytes))) => {
-                if let Some(k_layout) = zerocopy::LayoutVerified::<_, K::Ref>::new(k_bytes.as_ref())
-                {
-                    if let Some(v_layout) = zerocopy::LayoutVerified::<_, [V::Elem]>::new_slice(
-                        &v_bytes.as_ref()[V::prefix_len()..],
-                    ) {
-                        Some((self.f)(&k_layout, &v_layout))
-                    } else {
-                        Some(Err(KvError::DeserError(
-                            "Bytes are invalid length or alignment.".into(),
-                        )))
-                    }
-                } else {
-                    Some(Err(KvError::DeserError(
-                        "Bytes are invalid length or alignment.".into(),
-                    )))
-                }
-            }
-            Some(Err(e)) => Some(Err(KvError::BackendError(e))),
-            None => None,
-        }
-    }
-}
-
-impl<BC, D, K, V, F> ReversableIterator for KvInnerIterRefSlice<BC, D, K, V, F>
-where
-    BC: BackendCol,
-    K: KeyZc,
-    V: ValueSliceZc,
-    F: FnMut(&K::Ref, &[V::Elem]) -> KvResult<D>,
-{
-    #[inline(always)]
-    fn reverse(self) -> Self {
-        Self {
-            backend_iter: self.backend_iter.reverse(),
-            f: self.f,
-            phantom: PhantomData,
-        }
-    }
-}
diff --git a/rust-libs/tools/kv_typed/src/iter/keys.rs b/rust-libs/tools/kv_typed/src/iter/keys.rs
deleted file mode 100644
index 4e2cf10d2..000000000
--- a/rust-libs/tools/kv_typed/src/iter/keys.rs
+++ /dev/null
@@ -1,53 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-//! KV Typed iterators
-
-use crate::*;
-
-#[derive(Debug)]
-pub struct KvIterKeys<C: BackendCol, KB: KeyBytes, VB: ValueBytes, BI: BackendIter<KB, VB>, K: Key>
-{
-    backend_iter: BI,
-    phantom: PhantomData<(C, KB, VB, K)>,
-}
-
-impl<C: BackendCol, KB: KeyBytes, VB: ValueBytes, BI: BackendIter<KB, VB>, K: Key> Iterator
-    for KvIterKeys<C, KB, VB, BI, K>
-{
-    type Item = KvResult<K>;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        match self.backend_iter.next() {
-            Some(Ok((key_bytes, _value_bytes))) => match K::from_bytes(key_bytes.as_ref()) {
-                Ok(key) => Some(Ok(key)),
-                Err(e) => Some(Err(KvError::DeserError(e.into()))),
-            },
-            Some(Err(e)) => Some(Err(KvError::BackendError(e))),
-            None => None,
-        }
-    }
-}
-
-impl<C: BackendCol, KB: KeyBytes, VB: ValueBytes, BI: BackendIter<KB, VB>, K: Key>
-    KvIterKeys<C, KB, VB, BI, K>
-{
-    pub(super) fn new(backend_iter: BI) -> Self {
-        Self {
-            backend_iter,
-            phantom: PhantomData,
-        }
-    }
-}
diff --git a/rust-libs/tools/kv_typed/src/iter/values.rs b/rust-libs/tools/kv_typed/src/iter/values.rs
deleted file mode 100644
index a96f608df..000000000
--- a/rust-libs/tools/kv_typed/src/iter/values.rs
+++ /dev/null
@@ -1,59 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-//! KV Typed iterators
-
-use crate::*;
-
-#[derive(Debug)]
-pub struct KvIterValues<
-    C: BackendCol,
-    KB: KeyBytes,
-    VB: ValueBytes,
-    BI: BackendIter<KB, VB>,
-    K: Key,
-    V: Value,
-> {
-    backend_iter: BI,
-    phantom: PhantomData<(C, KB, VB, K, V)>,
-}
-
-impl<C: BackendCol, KB: KeyBytes, VB: ValueBytes, BI: BackendIter<KB, VB>, K: Key, V: Value>
-    Iterator for KvIterValues<C, KB, VB, BI, K, V>
-{
-    type Item = KvResult<V>;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        match self.backend_iter.next() {
-            Some(Ok((_key_bytes, value_bytes))) => match V::from_bytes(value_bytes.as_ref()) {
-                Ok(value) => Some(Ok(value)),
-                Err(e) => Some(Err(KvError::DeserError(e.into()))),
-            },
-            Some(Err(e)) => Some(Err(KvError::BackendError(e))),
-            None => None,
-        }
-    }
-}
-
-impl<C: BackendCol, KB: KeyBytes, VB: ValueBytes, BI: BackendIter<KB, VB>, K: Key, V: Value>
-    KvIterValues<C, KB, VB, BI, K, V>
-{
-    pub(super) fn new(backend_iter: BI) -> Self {
-        Self {
-            backend_iter,
-            phantom: PhantomData,
-        }
-    }
-}
diff --git a/rust-libs/tools/kv_typed/src/key.rs b/rust-libs/tools/kv_typed/src/key.rs
deleted file mode 100644
index 72d2bf3cb..000000000
--- a/rust-libs/tools/kv_typed/src/key.rs
+++ /dev/null
@@ -1,93 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-//! KV Typed Key trait
-
-use crate::*;
-
-/// Trait to be implemented by the collection key
-
-#[cfg(not(feature = "explorer"))]
-pub trait Key:
-    'static + AsBytes + Debug + Eq + FromBytes + std::hash::Hash + Send + Sync + Sized
-{
-}
-
-#[cfg(feature = "explorer")]
-pub trait Key:
-    'static + AsBytes + Debug + Eq + ExplorableKey + FromBytes + std::hash::Hash + Send + Sync + Sized
-{
-}
-
-#[cfg(not(feature = "explorer"))]
-impl<T> Key for T where
-    T: 'static + AsBytes + Debug + Eq + FromBytes + std::hash::Hash + Send + Sync + Sized
-{
-}
-
-#[cfg(feature = "explorer")]
-impl<T> Key for T where
-    T: 'static
-        + AsBytes
-        + Debug
-        + Eq
-        + ExplorableKey
-        + FromBytes
-        + std::hash::Hash
-        + Send
-        + Sync
-        + Sized
-{
-}
-
-pub trait KeyZc: Key {
-    type Ref: Sized + zerocopy::AsBytes + zerocopy::FromBytes;
-}
-
-impl KeyZc for () {
-    type Ref = ();
-}
-
-#[derive(
-    Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, zerocopy::AsBytes, zerocopy::FromBytes,
-)]
-#[repr(transparent)]
-pub struct U32BE(pub u32);
-
-impl From<&zerocopy::U32<byteorder::BigEndian>> for U32BE {
-    fn from(u32_zc: &zerocopy::U32<byteorder::BigEndian>) -> Self {
-        U32BE(u32_zc.get())
-    }
-}
-
-impl KeyZc for U32BE {
-    type Ref = zerocopy::U32<byteorder::BigEndian>;
-}
-
-#[derive(
-    Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, zerocopy::AsBytes, zerocopy::FromBytes,
-)]
-#[repr(transparent)]
-pub struct U64BE(pub u64);
-
-impl From<&zerocopy::U64<byteorder::BigEndian>> for U64BE {
-    fn from(u32_zc: &zerocopy::U64<byteorder::BigEndian>) -> Self {
-        U64BE(u32_zc.get())
-    }
-}
-
-impl KeyZc for U64BE {
-    type Ref = zerocopy::U64<byteorder::BigEndian>;
-}
diff --git a/rust-libs/tools/kv_typed/src/lib.rs b/rust-libs/tools/kv_typed/src/lib.rs
deleted file mode 100644
index b2487256d..000000000
--- a/rust-libs/tools/kv_typed/src/lib.rs
+++ /dev/null
@@ -1,153 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-//! Strongly typed key-value storage
-
-#![allow(clippy::upper_case_acronyms, clippy::from_over_into)]
-#![deny(
-    clippy::unwrap_used,
-    missing_copy_implementations,
-    missing_debug_implementations,
-    trivial_casts,
-    trivial_numeric_casts,
-    unstable_features,
-    unused_import_braces,
-    unused_qualifications
-)]
-
-mod as_bytes;
-pub mod backend;
-mod batch;
-mod bytes;
-mod collection_inner;
-mod collection_ro;
-mod collection_rw;
-mod db_schema;
-mod error;
-mod event;
-#[cfg(feature = "explorer")]
-pub mod explorer;
-mod from_bytes;
-mod iter;
-mod key;
-mod subscription;
-mod transactional_read;
-mod transactional_write;
-mod utils;
-mod value;
-
-// Re-export dependencies
-pub use flume as channel;
-#[cfg(feature = "explorer")]
-pub use regex;
-pub use zerocopy;
-
-/// Kv Typed prelude
-pub mod prelude {
-    pub use crate::as_bytes::AsBytes;
-    #[cfg(feature = "leveldb_backend")]
-    pub use crate::backend::leveldb::{LevelDb, LevelDbConf};
-    #[cfg(feature = "lmdb_backend")]
-    pub use crate::backend::lmdb::{Lmdb, LmdbConf};
-    pub use crate::backend::memory::{Mem, MemConf};
-    pub use crate::backend::memory_singleton::{MemSingleton, MemSingletonConf};
-    #[cfg(feature = "mock")]
-    pub use crate::backend::mock::{MockBackend, MockBackendCol, MockBackendIter};
-    #[cfg(feature = "sled_backend")]
-    pub use crate::backend::sled::{Config as SledConf, Sled};
-    pub use crate::backend::{Backend, BackendCol};
-    pub use crate::batch::{Batch, BatchGet};
-    #[cfg(feature = "mock")]
-    pub use crate::collection_ro::MockColRo;
-    pub use crate::collection_ro::{
-        ColRo, DbCollectionRo, DbCollectionRoGetRef, DbCollectionRoGetRefSlice,
-        DbCollectionRoIterRefSlice,
-    };
-    pub use crate::collection_rw::{ColRw, DbCollectionRw};
-    pub use crate::error::{DynErr, KvError, KvResult};
-    pub use crate::event::{EventTrait, Events};
-    #[cfg(feature = "explorer")]
-    pub use crate::explorer::{
-        ExplorableKey, ExplorableValue, ExplorerActionErr, FromExplorerKeyErr, FromExplorerValueErr,
-    };
-    pub use crate::from_bytes::{FromBytes, LayoutVerifiedErr};
-    pub use crate::iter::{
-        keys::KvIterKeys, values::KvIterValues, EntryIter, KvIter, KvIterRefSlice, ResultIter,
-    };
-    pub use crate::key::{Key, KeyZc, U32BE, U64BE};
-    pub use crate::subscription::{NewSubscribers, Subscriber, Subscribers};
-    pub use crate::transactional_read::{TransactionalRead, TxColRo};
-    pub use crate::transactional_write::{DbTxCollectionRw, TransactionalWrite, TxColRw};
-    pub use crate::utils::arc::Arc;
-    pub use crate::value::{Value, ValueSliceZc, ValueZc};
-    pub use crate::OwnedOrRef;
-}
-
-// Internal crate imports
-pub(crate) use crate::backend::{BackendBatch, BackendIter};
-pub(crate) use crate::bytes::{CowKB, CowVB, KeyBytes, ValueBytes};
-pub(crate) use crate::collection_inner::ColInner;
-pub(crate) use crate::error::BackendResult;
-#[cfg(feature = "explorer")]
-pub(crate) use crate::explorer::{ExplorableKey, ExplorableValue};
-pub(crate) use crate::iter::{KvInnerIterRefSlice, RangeBytes, ReversableIterator};
-pub(crate) use crate::prelude::*;
-pub(crate) use crate::subscription::{ColSubscribers, SubscriptionsSender};
-pub(crate) use crate::transactional_write::tx_iter::BackendTxIter;
-pub(crate) use crate::utils::arc::Arc;
-pub(crate) use crate::utils::ivec::IVec;
-use flume::{unbounded, Receiver, Sender, TrySendError};
-pub(crate) use smallvec::SmallVec;
-pub(crate) use std::{
-    collections::{BTreeSet, HashSet},
-    convert::TryInto,
-    error::Error,
-    fmt::{Debug, Display},
-    marker::PhantomData,
-    ops::{Bound, RangeBounds},
-    str::FromStr,
-};
-pub(crate) use thiserror::Error;
-
-pub enum OwnedOrRef<'a, T> {
-    Owned(T),
-    Borrow(&'a T),
-}
-impl<'a, T> AsRef<T> for OwnedOrRef<'a, T> {
-    fn as_ref(&self) -> &T {
-        match self {
-            Self::Owned(t) => t,
-            Self::Borrow(t) => *t,
-        }
-    }
-}
-impl<'a, T: Debug> Debug for OwnedOrRef<'a, T> {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        match self {
-            Self::Owned(t) => write!(f, "OwnedOrRef::Owned({:?})", t),
-            Self::Borrow(t) => write!(f, "OwnedOrRef::Borrow({:?})", t),
-        }
-    }
-}
-impl<'a, T> From<&'a T> for OwnedOrRef<'a, T> {
-    fn from(borrow: &'a T) -> Self {
-        Self::Borrow(borrow)
-    }
-}
-impl<T> From<T> for OwnedOrRef<'_, T> {
-    fn from(owned: T) -> Self {
-        Self::Owned(owned)
-    }
-}
diff --git a/rust-libs/tools/kv_typed/src/subscription.rs b/rust-libs/tools/kv_typed/src/subscription.rs
deleted file mode 100644
index 049aa446a..000000000
--- a/rust-libs/tools/kv_typed/src/subscription.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-//! KV Typed subscription
-
-use crate::*;
-
-/// Subscriber
-pub type Subscriber<E> = Sender<Arc<Events<E>>>;
-/// Subscriptions sender
-pub(crate) type SubscriptionsSender<E> = Sender<Subscriber<E>>;
-/// Subscribers
-pub type Subscribers<E> = std::collections::BTreeMap<usize, Subscriber<E>>;
-/// New subscribers
-pub type NewSubscribers<E> = SmallVec<[Subscriber<E>; 4]>;
-
-#[derive(Debug)]
-#[doc(hidden)]
-pub struct ColSubscribers<E: EventTrait> {
-    subscription_sender: SubscriptionsSender<E>,
-    subscription_receiver: Receiver<Subscriber<E>>,
-    subscribers: Subscribers<E>,
-    subscriber_index: usize,
-}
-
-impl<E: EventTrait> Default for ColSubscribers<E> {
-    fn default() -> Self {
-        let (subscription_sender, subscription_receiver) = unbounded();
-        ColSubscribers {
-            subscription_sender,
-            subscription_receiver,
-            subscribers: std::collections::BTreeMap::new(),
-            subscriber_index: 0,
-        }
-    }
-}
-
-impl<E: EventTrait> ColSubscribers<E> {
-    pub(crate) fn get_subscription_sender(&self) -> Sender<Subscriber<E>> {
-        self.subscription_sender.clone()
-    }
-    #[inline(always)]
-    pub(crate) fn get_new_subscribers(&self) -> NewSubscribers<E> {
-        if !self.subscription_receiver.is_empty() {
-            let mut new_subscribers = SmallVec::new();
-            while let Ok(subscriber) = self.subscription_receiver.try_recv() {
-                new_subscribers.push(subscriber)
-            }
-            new_subscribers
-        } else {
-            SmallVec::new()
-        }
-    }
-    pub(crate) fn notify_subscribers(&self, events: Arc<Events<E>>) -> Vec<usize> {
-        let mut died_subscribers = Vec::with_capacity(self.subscribers.len());
-        let mut unsend_events_opt = None;
-        for (id, subscriber) in &self.subscribers {
-            if let Err(e) = subscriber.try_send(
-                unsend_events_opt
-                    .take()
-                    .unwrap_or_else(|| Arc::clone(&events)),
-            ) {
-                match e {
-                    TrySendError::Disconnected(events_) => {
-                        unsend_events_opt = Some(events_);
-                        died_subscribers.push(*id);
-                    }
-                    TrySendError::Full(events_) => {
-                        unsend_events_opt = Some(events_);
-                    }
-                }
-            }
-        }
-        died_subscribers
-    }
-    #[inline(always)]
-    pub(crate) fn add_new_subscribers(&mut self) {
-        for new_subscriber in self.get_new_subscribers() {
-            self.subscribers
-                .insert(self.subscriber_index, new_subscriber);
-            self.subscriber_index += 1;
-        }
-    }
-    #[inline(always)]
-    pub(crate) fn prune_subscribers(&mut self, died_subscribers: Vec<usize>) {
-        for died_subscriber in died_subscribers {
-            self.subscribers.remove(&died_subscriber);
-        }
-    }
-}
diff --git a/rust-libs/tools/kv_typed/src/transactional_read.rs b/rust-libs/tools/kv_typed/src/transactional_read.rs
deleted file mode 100644
index 647861f9b..000000000
--- a/rust-libs/tools/kv_typed/src/transactional_read.rs
+++ /dev/null
@@ -1,211 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-//! KV Typed transactional read
-
-use crate::*;
-use parking_lot::RwLockReadGuard as ReadGuard;
-
-type TxColRoReader<'r, BC, E> = parking_lot::RwLockReadGuard<'r, ColInner<BC, E>>;
-
-pub struct TxColRo<'tx, BC: BackendCol, E: EventTrait> {
-    col_reader: ReadGuard<'tx, ColInner<BC, E>>,
-}
-impl<'tx, BC: BackendCol, E: EventTrait> Debug for TxColRo<'tx, BC, E> {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        f.debug_struct("LevelDbCol")
-            .field("col_reader", &format!("{:?}", self.col_reader))
-            .finish()
-    }
-}
-impl<'tx, BC: BackendCol, E: EventTrait> TxColRo<'tx, BC, E> {
-    #[inline(always)]
-    fn new(col_reader: ReadGuard<'tx, ColInner<BC, E>>) -> Self {
-        TxColRo { col_reader }
-    }
-    #[inline(always)]
-    pub fn count(&self) -> KvResult<usize> {
-        self.col_reader.backend_col.count()
-    }
-    #[inline(always)]
-    pub fn get(&self, k: &E::K) -> KvResult<Option<E::V>> {
-        self.col_reader.backend_col.get(k)
-    }
-    #[allow(clippy::type_complexity)]
-    #[inline(always)]
-    /// Don't worry about complex iter type. Use it like an `impl Iterator<Item=KvResult<(K, V)>>`.
-    pub fn iter<D, R, F>(&self, range: R, f: F) -> D
-    where
-        D: Send + Sync,
-        R: 'static + RangeBounds<E::K>,
-        F: FnOnce(KvIter<BC, BC::KeyBytes, BC::ValueBytes, BC::Iter, E::K, E::V>) -> D,
-    {
-        let range_bytes = crate::iter::convert_range::<E::K, R>(range);
-        let backend_iter = self.col_reader.backend_col.iter::<E::K, E::V>(range_bytes);
-        f(KvIter::new(backend_iter))
-    }
-    #[allow(clippy::type_complexity)]
-    #[inline(always)]
-    /// Don't worry about complex iter type. Use it like an `impl Iterator<Item=KvResult<(K, V)>>`.
-    pub fn iter_rev<D, R, F>(&self, range: R, f: F) -> D
-    where
-        D: Send + Sync,
-        R: 'static + RangeBounds<E::K>,
-        F: FnOnce(KvIter<BC, BC::KeyBytes, BC::ValueBytes, BC::Iter, E::K, E::V>) -> D,
-    {
-        let range_bytes = crate::iter::convert_range::<E::K, R>(range);
-        let backend_iter = self
-            .col_reader
-            .backend_col
-            .iter::<E::K, E::V>(range_bytes)
-            .reverse();
-        f(KvIter::new(backend_iter))
-    }
-}
-impl<'tx, V: ValueZc, BC: BackendCol, E: EventTrait<V = V>> TxColRo<'tx, BC, E> {
-    pub fn get_ref<D, F: Fn(&V::Ref) -> KvResult<D>>(&self, k: &E::K, f: F) -> KvResult<Option<D>> {
-        self.col_reader.backend_col.get_ref::<E::K, V, D, F>(k, f)
-    }
-}
-impl<'tx, K: KeyZc, V: ValueSliceZc, BC: BackendCol, E: EventTrait<K = K, V = V>>
-    TxColRo<'tx, BC, E>
-{
-    pub fn iter_ref_slice<D, R, F>(
-        &self,
-        range: R,
-        f: F,
-    ) -> KvIterRefSlice<BC, D, K, V, F, TxColRoReader<BC, E>>
-    where
-        K: KeyZc,
-        V: ValueSliceZc,
-        R: 'static + RangeBounds<K>,
-        F: FnMut(&K::Ref, &[V::Elem]) -> KvResult<D>,
-    {
-        let range: RangeBytes = crate::iter::convert_range::<K, R>(range);
-        let inner_iter = self
-            .col_reader
-            .backend_col
-            .iter_ref_slice::<D, K, V, F>(range, f);
-
-        KvIterRefSlice {
-            inner: inner_iter,
-            reader: OwnedOrRef::Borrow(&self.col_reader),
-        }
-    }
-    pub fn iter_ref_slice_rev<D, R, F>(
-        &self,
-        range: R,
-        f: F,
-    ) -> KvIterRefSlice<BC, D, K, V, F, TxColRoReader<BC, E>>
-    where
-        K: KeyZc,
-        V: ValueSliceZc,
-        R: 'static + RangeBounds<K>,
-        F: FnMut(&K::Ref, &[V::Elem]) -> KvResult<D>,
-    {
-        let range: RangeBytes = crate::iter::convert_range::<K, R>(range);
-        let inner_iter = self
-            .col_reader
-            .backend_col
-            .iter_ref_slice::<D, K, V, F>(range, f)
-            .reverse();
-
-        KvIterRefSlice {
-            inner: inner_iter,
-            reader: OwnedOrRef::Borrow(&self.col_reader),
-        }
-    }
-}
-
-impl<'tx, V: ValueSliceZc, BC: BackendCol, E: EventTrait<V = V>> TxColRo<'tx, BC, E> {
-    pub fn get_ref_slice<D, F: Fn(&[V::Elem]) -> KvResult<D>>(
-        &self,
-        k: &E::K,
-        f: F,
-    ) -> KvResult<Option<D>> {
-        self.col_reader
-            .backend_col
-            .get_ref_slice::<E::K, V, D, F>(k, f)
-    }
-}
-
-pub trait TransactionalRead<'tx, BC: BackendCol> {
-    type TxCols;
-
-    fn read<D, F: Fn(Self::TxCols) -> KvResult<D>>(&'tx self, f: F) -> KvResult<D>;
-
-    fn try_read<D, F: Fn(Self::TxCols) -> KvResult<D>>(&'tx self, f: F) -> Result<KvResult<D>, F>;
-}
-
-impl<'tx, BC: BackendCol, E: EventTrait> TransactionalRead<'tx, BC> for &'tx ColRo<BC, E> {
-    type TxCols = TxColRo<'tx, BC, E>;
-
-    fn read<D, F: Fn(Self::TxCols) -> KvResult<D>>(&'tx self, f: F) -> KvResult<D> {
-        let read_guard_0 = self.inner.read();
-
-        f(TxColRo::new(read_guard_0))
-    }
-
-    fn try_read<D, F: Fn(Self::TxCols) -> KvResult<D>>(&'tx self, f: F) -> Result<KvResult<D>, F> {
-        if let Some(read_guard_0) = self.inner.try_read() {
-            Ok(f(TxColRo::new(read_guard_0)))
-        } else {
-            Err(f)
-        }
-    }
-}
-
-macro_rules! impl_transactional_read {
-    ($($i:literal),*) => {
-        paste::paste! {
-            impl<'tx, BC: BackendCol $( ,[<E $i>]: EventTrait)*> TransactionalRead<'tx, BC>
-                for ($(&'tx ColRo<BC, [<E $i>]>, )*)
-            {
-                type TxCols = ($(TxColRo<'tx, BC,  [<E $i>]>, )*);
-
-                fn read<D, F: Fn(Self::TxCols) -> KvResult<D>>(
-                    &'tx self,
-                    f: F,
-                ) -> KvResult<D> {
-                    $(let [<read_guard_ $i>] = self.$i.inner.read();)*
-
-                    f(($(TxColRo::new([<read_guard_ $i>]), )*))
-                }
-
-                fn try_read<D, F: Fn(Self::TxCols) -> KvResult<D>>(
-                    &'tx self,
-                    f: F,
-                ) -> Result<KvResult<D>, F> {
-                    $(let [<read_guard_opt_ $i>] = self.$i.inner.try_read();)*
-
-                    if $([<read_guard_opt_ $i>].is_none() || )* false {
-                        Err(f)
-                    } else {
-                        Ok(f(($(TxColRo::new([<read_guard_opt_ $i>].expect("unreachable")), )*)))
-                    }
-                }
-            }
-        }
-    };
-}
-impl_transactional_read!(0, 1);
-impl_transactional_read!(0, 1, 2);
-impl_transactional_read!(0, 1, 2, 3);
-impl_transactional_read!(0, 1, 2, 3, 4);
-impl_transactional_read!(0, 1, 2, 3, 4, 5);
-impl_transactional_read!(0, 1, 2, 3, 4, 5, 6);
-impl_transactional_read!(0, 1, 2, 3, 4, 5, 6, 7);
-impl_transactional_read!(0, 1, 2, 3, 4, 5, 6, 7, 8);
-impl_transactional_read!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
diff --git a/rust-libs/tools/kv_typed/src/transactional_write.rs b/rust-libs/tools/kv_typed/src/transactional_write.rs
deleted file mode 100644
index 2595e6302..000000000
--- a/rust-libs/tools/kv_typed/src/transactional_write.rs
+++ /dev/null
@@ -1,237 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-//! KV Typed transactional write
-
-pub(crate) mod tx_iter;
-
-use crate::*;
-use parking_lot::RwLockUpgradableReadGuard as UpgradableReadGuard;
-
-pub struct TxColRw<'tx, BC: BackendCol, E: EventTrait> {
-    batch: &'static mut Batch<BC, ColRw<BC, E>>,
-    col_reader: &'tx UpgradableReadGuard<'tx, ColInner<BC, E>>,
-}
-
-impl<'tx, BC: BackendCol, E: EventTrait> TxColRw<'tx, BC, E> {
-    #[doc(hidden)]
-    /// For internal usage only MUST NOT USE
-    pub fn new(
-        batch: &mut Batch<BC, ColRw<BC, E>>,
-        upgradable_guard: &UpgradableReadGuard<ColInner<BC, E>>,
-    ) -> Self {
-        TxColRw {
-            batch: unsafe { std::mem::transmute(batch) },
-            col_reader: unsafe { std::mem::transmute(upgradable_guard) },
-        }
-    }
-}
-
-impl<'tx, BC: BackendCol, E: EventTrait> Debug for TxColRw<'tx, BC, E> {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        f.debug_struct("LevelDbCol")
-            .field("batch", &format!("{:?}", self.batch))
-            .field("col_reader", &format!("{:?}", self.col_reader))
-            .finish()
-    }
-}
-
-impl<'tx, V: ValueZc, BC: BackendCol, E: EventTrait<V = V>> TxColRw<'tx, BC, E> {
-    pub fn get_ref<D, F: Fn(&V::Ref) -> KvResult<D>>(&self, k: &E::K, f: F) -> KvResult<Option<D>> {
-        self.col_reader.backend_col.get_ref::<E::K, V, D, F>(k, f)
-    }
-}
-impl<'tx, V: ValueSliceZc, BC: BackendCol, E: EventTrait<V = V>> TxColRw<'tx, BC, E> {
-    pub fn get_ref_slice<D, F: Fn(&[V::Elem]) -> KvResult<D>>(
-        &self,
-        k: &E::K,
-        f: F,
-    ) -> KvResult<Option<D>> {
-        self.col_reader
-            .backend_col
-            .get_ref_slice::<E::K, V, D, F>(k, f)
-    }
-}
-
-impl<'tx, BC: BackendCol, E: EventTrait> TxColRw<'tx, BC, E> {
-    #[inline(always)]
-    pub fn count(&self) -> KvResult<usize> {
-        self.col_reader.backend_col.count()
-    }
-    #[inline(always)]
-    pub fn get(&self, k: &E::K) -> KvResult<Option<E::V>> {
-        match self.batch.get(k) {
-            batch::BatchGet::None => self.col_reader.backend_col.get(k),
-            batch::BatchGet::Deleted => Ok(None),
-            batch::BatchGet::Updated(v) => Ok(Some(v.as_bytes(|v_bytes| {
-                E::V::from_bytes(v_bytes).map_err(|e| KvError::DeserError(e.into()))
-            })?)),
-        }
-    }
-    #[allow(clippy::type_complexity)]
-    #[inline(always)]
-    /// Don't worry about complex iter type. Use it like an `impl Iterator<Item=KvResult<(K, V)>>`.
-    pub fn iter<D, R, F>(&'tx self, range: R, f: F) -> D
-    where
-        D: Send + Sync,
-        R: 'static + RangeBounds<E::K>,
-        F: FnOnce(
-            KvIter<
-                BC,
-                CowKB<'tx, BC::KeyBytes>,
-                CowVB<'tx, BC::ValueBytes>,
-                BackendTxIter<BC>,
-                E::K,
-                E::V,
-            >,
-        ) -> D,
-    {
-        let range_bytes = crate::iter::convert_range::<E::K, R>(range);
-        let backend_iter = self.col_reader.backend_col.iter::<E::K, E::V>(range_bytes);
-        f(KvIter::new(BackendTxIter::new(
-            backend_iter,
-            &self.batch.tree,
-        )))
-    }
-    #[allow(clippy::type_complexity)]
-    #[inline(always)]
-    /// Don't worry about complex iter type. Use it like an `impl Iterator<Item=KvResult<(K, V)>>`.
-    pub fn iter_rev<D, R, F>(&'tx self, range: R, f: F) -> D
-    where
-        D: Send + Sync,
-        R: 'static + RangeBounds<E::K>,
-        F: FnOnce(
-            KvIter<
-                BC,
-                CowKB<'tx, BC::KeyBytes>,
-                CowVB<'tx, BC::ValueBytes>,
-                BackendTxIter<BC>,
-                E::K,
-                E::V,
-            >,
-        ) -> D,
-    {
-        let range_bytes = crate::iter::convert_range::<E::K, R>(range);
-        let backend_iter = self.col_reader.backend_col.iter::<E::K, E::V>(range_bytes);
-        f(KvIter::new(
-            BackendTxIter::new(backend_iter, &self.batch.tree).reverse(),
-        ))
-    }
-}
-
-pub trait DbTxCollectionRw {
-    type K: Key;
-    type V: Value;
-    type Event: EventTrait<K = Self::K, V = Self::V>;
-
-    fn remove(&mut self, k: Self::K);
-    fn upsert(&mut self, k: Self::K, v: Self::V);
-}
-
-impl<'tx, BC: BackendCol, E: EventTrait> DbTxCollectionRw for TxColRw<'tx, BC, E> {
-    type K = E::K;
-    type V = E::V;
-    type Event = E;
-
-    #[inline(always)]
-    fn remove(&mut self, k: Self::K) {
-        self.batch.remove(k)
-    }
-    #[inline(always)]
-    fn upsert(&mut self, k: Self::K, v: Self::V) {
-        self.batch.upsert(k, v)
-    }
-}
-
-pub trait TransactionalWrite<'tx, BC: BackendCol> {
-    type TxCols;
-
-    fn write<D, F: FnOnce(Self::TxCols) -> KvResult<D>>(&'tx self, f: F) -> KvResult<D>;
-}
-
-impl<'tx, BC: BackendCol, E: EventTrait> TransactionalWrite<'tx, BC> for &'tx ColRw<BC, E> {
-    type TxCols = TxColRw<'tx, BC, E>;
-
-    fn write<D, F: FnOnce(Self::TxCols) -> KvResult<D>>(&'tx self, f: F) -> KvResult<D> {
-        let upgradable_guard = self.inner.inner.upgradable_read();
-
-        let mut batch = Batch::<BC, ColRw<BC, E>>::default();
-
-        let tx_col = TxColRw {
-            batch: unsafe { std::mem::transmute(&mut batch) },
-            col_reader: unsafe { std::mem::transmute(&upgradable_guard) },
-        };
-        let data = f(tx_col)?;
-
-        // Prepare commit
-        let (backend_batch, events) = batch.into_backend_batch_and_events();
-
-        // Acquire exclusive lock
-        let mut write_guard = UpgradableReadGuard::upgrade(upgradable_guard);
-
-        // Commit
-        self.write_backend_batch(backend_batch, events, &mut write_guard)?;
-
-        Ok(data)
-    }
-}
-
-macro_rules! impl_transactional_write {
-    ($($i:literal),*) => {
-        paste::paste! {
-            impl<'tx, BC: BackendCol $( ,[<E $i>]: EventTrait)*> TransactionalWrite<'tx, BC>
-                for ($(&'tx ColRw<BC, [<E $i>]>, )*)
-            {
-                type TxCols = ($(TxColRw<'tx, BC,  [<E $i>]>, )*);
-
-                fn write<D, F: FnOnce(Self::TxCols) -> KvResult<D>>(
-                    &'tx self,
-                    f: F,
-                ) -> KvResult<D> {
-                    $(let [<upgradable_guard_ $i>] = self.$i.inner.inner.upgradable_read();)*
-
-                    $(let mut [<batch_ $i>] = Batch::<BC, ColRw<BC, [<E $i>]>>::default();)*
-
-                    $(let [<tx_col $i>] = TxColRw {
-                        batch: unsafe { std::mem::transmute(&mut [<batch_ $i>]) },
-                        col_reader: unsafe { std::mem::transmute(&[<upgradable_guard_ $i>]) },
-                    };)*
-
-                    let data = f(($([<tx_col $i>], )*))?;
-
-                    // Prepare commit
-                    $(let ([<backend_batch_ $i>], [<events_ $i>]) = [<batch_ $i>].into_backend_batch_and_events();)*
-
-                    // Acquire exclusive lock
-                    $(let mut [<write_guard_ $i>] = UpgradableReadGuard::upgrade([<upgradable_guard_ $i>]);)*
-
-                    // Commit
-                    $(self.$i.write_backend_batch([<backend_batch_ $i>], [<events_ $i>], &mut [<write_guard_ $i>])?;)*
-
-                    Ok(data)
-                }
-            }
-        }
-    };
-}
-impl_transactional_write!(0, 1);
-impl_transactional_write!(0, 1, 2);
-impl_transactional_write!(0, 1, 2, 3);
-impl_transactional_write!(0, 1, 2, 3, 4);
-impl_transactional_write!(0, 1, 2, 3, 4, 5);
-impl_transactional_write!(0, 1, 2, 3, 4, 5, 6);
-impl_transactional_write!(0, 1, 2, 3, 4, 5, 6, 7);
-impl_transactional_write!(0, 1, 2, 3, 4, 5, 6, 7, 8);
-impl_transactional_write!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
diff --git a/rust-libs/tools/kv_typed/src/transactional_write/tx_iter.rs b/rust-libs/tools/kv_typed/src/transactional_write/tx_iter.rs
deleted file mode 100644
index fe1c28bcf..000000000
--- a/rust-libs/tools/kv_typed/src/transactional_write/tx_iter.rs
+++ /dev/null
@@ -1,157 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-//! KV Typed transactional iterator
-
-use crate::*;
-use std::collections::BTreeMap;
-
-#[doc(hidden)]
-#[derive(Debug)]
-pub struct BackendTxIter<'b, BC: BackendCol> {
-    batch_end_reached: bool,
-    batch_iter: std::collections::btree_map::Iter<'b, IVec, Option<IVec>>,
-    batch_tree_ref: &'b BTreeMap<IVec, Option<IVec>>,
-    backend_iter: BC::Iter,
-    db_end_reached: bool,
-    next_batch_entry_opt: Option<(&'b IVec, &'b Option<IVec>)>,
-    next_db_entry_opt: Option<(BC::KeyBytes, BC::ValueBytes)>,
-    reverted: bool,
-}
-
-impl<'b, BC: BackendCol> BackendTxIter<'b, BC> {
-    pub(crate) fn new(
-        backend_iter: BC::Iter,
-        batch_tree: &'b BTreeMap<IVec, Option<IVec>>,
-    ) -> Self {
-        Self {
-            batch_end_reached: false,
-            batch_iter: batch_tree.iter(),
-            batch_tree_ref: batch_tree,
-            backend_iter,
-            db_end_reached: false,
-            next_batch_entry_opt: None,
-            next_db_entry_opt: None,
-            reverted: false,
-        }
-    }
-}
-
-impl<'b, BC: BackendCol> BackendTxIter<'b, BC> {
-    fn get_next_db_item(&mut self) -> Option<BackendResult<BC>> {
-        match self.backend_iter.next() {
-            Some(Ok(entry)) => {
-                if self.batch_tree_ref.contains_key(entry.0.as_ref()) {
-                    self.get_next_db_item()
-                } else {
-                    Some(Ok(entry))
-                }
-            }
-            o => o,
-        }
-    }
-}
-
-#[allow(type_alias_bounds)]
-type CowBytesEntry<'a, BC: BackendCol> = (CowKB<'a, BC::KeyBytes>, CowVB<'a, BC::ValueBytes>);
-
-impl<'b, BC: BackendCol> Iterator for BackendTxIter<'b, BC> {
-    type Item = Result<CowBytesEntry<'b, BC>, DynErr>;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        if self.next_batch_entry_opt.is_none() {
-            self.next_batch_entry_opt = if self.reverted {
-                self.batch_iter.next_back()
-            } else {
-                self.batch_iter.next()
-            };
-        }
-        if self.next_batch_entry_opt.is_none() {
-            self.batch_end_reached = true;
-        }
-        if self.next_db_entry_opt.is_none() {
-            self.next_db_entry_opt = match self.get_next_db_item() {
-                Some(Ok(entry)) => Some(entry),
-                Some(Err(e)) => return Some(Err(e)),
-                None => {
-                    self.db_end_reached = true;
-                    None
-                }
-            };
-        }
-
-        if self.batch_end_reached {
-            if self.db_end_reached {
-                None
-            } else {
-                // Return db item
-                Some(Ok(self
-                    .next_db_entry_opt
-                    .take()
-                    .map(|(k, v)| (CowKB::O(k), CowVB::O(v)))
-                    .expect("unreachable")))
-            }
-        } else if self.db_end_reached {
-            // Return batch item
-            if let Some((k, v_opt)) = self.next_batch_entry_opt.take() {
-                if let Some(v) = v_opt {
-                    Some(Ok((CowKB::B(k.as_ref()), CowVB::B(v.as_ref()))))
-                } else {
-                    self.next()
-                }
-            } else {
-                // batch_end_reached = false
-                unreachable!()
-            }
-        } else if let Some((k_batch, v_batch_opt)) = self.next_batch_entry_opt.take() {
-            if let Some((k_db, v_db)) = self.next_db_entry_opt.take() {
-                if (!self.reverted && k_batch.as_ref() <= k_db.as_ref())
-                    || (self.reverted && k_batch.as_ref() >= k_db.as_ref())
-                {
-                    self.next_db_entry_opt = Some((k_db, v_db));
-                    // Return batch item
-                    if let Some(v_batch) = v_batch_opt {
-                        Some(Ok((CowKB::B(k_batch.as_ref()), CowVB::B(v_batch.as_ref()))))
-                    } else {
-                        self.next()
-                    }
-                } else {
-                    self.next_batch_entry_opt = Some((k_batch, v_batch_opt));
-                    // Return db item
-                    Some(Ok((CowKB::O(k_db), CowVB::O(v_db))))
-                }
-            } else {
-                // db_end_reached = false
-                unreachable!()
-            }
-        } else {
-            // batch_end_reached = false
-            unreachable!()
-        }
-    }
-}
-
-impl<'b, BC: BackendCol> ReversableIterator for BackendTxIter<'b, BC> {
-    fn reverse(mut self) -> Self {
-        self.backend_iter = self.backend_iter.reverse();
-        self.reverted = true;
-        self
-    }
-}
-
-impl<'b, BC: BackendCol> BackendIter<CowKB<'b, BC::KeyBytes>, CowVB<'b, BC::ValueBytes>>
-    for BackendTxIter<'b, BC>
-{
-}
diff --git a/rust-libs/tools/kv_typed/src/utils.rs b/rust-libs/tools/kv_typed/src/utils.rs
deleted file mode 100644
index 68bd74c49..000000000
--- a/rust-libs/tools/kv_typed/src/utils.rs
+++ /dev/null
@@ -1,24 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-//! KV Typed utils
-
-pub mod arc;
-#[cfg(not(feature = "sled_backend"))]
-pub mod ivec;
-#[cfg(feature = "sled_backend")]
-pub mod ivec {
-    pub use sled::IVec;
-}
diff --git a/rust-libs/tools/kv_typed/src/utils/arc.rs b/rust-libs/tools/kv_typed/src/utils/arc.rs
deleted file mode 100644
index 74a7b5856..000000000
--- a/rust-libs/tools/kv_typed/src/utils/arc.rs
+++ /dev/null
@@ -1,267 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-//! KV typed Arc
-
-#![allow(clippy::unwrap_used, dead_code, unsafe_code)]
-/// We use this because we never use the weak count on the std
-/// `Arc`, but we use a LOT of `Arc`'s, so the extra 8 bytes
-/// turn into a huge overhead.
-use std::{
-    alloc::{alloc, dealloc, Layout},
-    convert::TryFrom,
-    fmt::{self, Debug},
-    mem,
-    ops::Deref,
-    ptr,
-    sync::atomic::{AtomicUsize, Ordering},
-};
-
-// we make this repr(C) because we do a raw
-// write to the beginning where we expect
-// the rc to be.
-#[repr(C)]
-struct ArcInner<T: ?Sized> {
-    rc: AtomicUsize,
-    inner: T,
-}
-
-pub struct Arc<T: ?Sized> {
-    ptr: *mut ArcInner<T>,
-}
-
-unsafe impl<T: Send + Sync + ?Sized> Send for Arc<T> {}
-unsafe impl<T: Send + Sync + ?Sized> Sync for Arc<T> {}
-
-impl<T: Debug + ?Sized> Debug for Arc<T> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
-        Debug::fmt(&**self, f)
-    }
-}
-
-impl<T> Arc<T> {
-    pub fn new(inner: T) -> Arc<T> {
-        let bx = Box::new(ArcInner {
-            inner,
-            rc: AtomicUsize::new(1),
-        });
-        let ptr = Box::into_raw(bx);
-        Arc { ptr }
-    }
-
-    // See std::sync::arc::Arc::copy_from_slice,
-    // "Unsafe because the caller must either take ownership or bind `T: Copy`"
-    unsafe fn copy_from_slice(s: &[T]) -> Arc<[T]> {
-        let align = std::cmp::max(mem::align_of::<T>(), mem::align_of::<AtomicUsize>());
-
-        let rc_width = std::cmp::max(align, mem::size_of::<AtomicUsize>());
-        let data_width = mem::size_of::<T>().checked_mul(s.len()).unwrap();
-
-        let size_unpadded = rc_width.checked_add(data_width).unwrap();
-        // Pad size out to alignment
-        let size_padded = (size_unpadded + align - 1) & !(align - 1);
-
-        let layout = Layout::from_size_align(size_padded, align).unwrap();
-
-        let ptr = alloc(layout);
-
-        assert!(!ptr.is_null(), "failed to allocate Arc");
-        #[allow(clippy::cast_ptr_alignment)]
-        ptr::write(ptr as _, AtomicUsize::new(1));
-
-        let data_ptr = ptr.add(rc_width);
-        ptr::copy_nonoverlapping(s.as_ptr(), data_ptr as _, s.len());
-
-        let fat_ptr: *const ArcInner<[T]> = Arc::fatten(ptr, s.len());
-
-        Arc {
-            ptr: fat_ptr as *mut _,
-        }
-    }
-
-    /// <https://users.rust-lang.org/t/construct-fat-pointer-to-struct/29198/9>
-    #[allow(trivial_casts)]
-    fn fatten(data: *const u8, len: usize) -> *const ArcInner<[T]> {
-        // Requirements of slice::from_raw_parts.
-        assert!(!data.is_null());
-        assert!(isize::try_from(len).is_ok());
-
-        let slice = unsafe { core::slice::from_raw_parts(data as *const (), len) };
-        slice as *const [()] as *const _
-    }
-
-    pub fn into_raw(arc: Arc<T>) -> *const T {
-        let ptr = unsafe { &(*arc.ptr).inner };
-        #[allow(clippy::mem_forget)]
-        mem::forget(arc);
-        ptr
-    }
-
-    #[allow(clippy::missing_safety_doc)]
-    pub unsafe fn from_raw(ptr: *const T) -> Arc<T> {
-        let align = std::cmp::max(mem::align_of::<T>(), mem::align_of::<AtomicUsize>());
-
-        let rc_width = std::cmp::max(align, mem::size_of::<AtomicUsize>());
-
-        let sub_ptr = (ptr as *const u8).sub(rc_width) as *mut ArcInner<T>;
-
-        Arc { ptr: sub_ptr }
-    }
-}
-
-impl<T: ?Sized> Arc<T> {
-    pub fn strong_count(arc: &Arc<T>) -> usize {
-        unsafe { (*arc.ptr).rc.load(Ordering::Acquire) }
-    }
-
-    pub fn get_mut(arc: &mut Arc<T>) -> Option<&mut T> {
-        if Arc::strong_count(arc) == 1 {
-            Some(unsafe { &mut arc.ptr.as_mut().unwrap().inner })
-        } else {
-            None
-        }
-    }
-}
-
-impl<T: ?Sized + Clone> Arc<T> {
-    pub fn make_mut(arc: &mut Arc<T>) -> &mut T {
-        if Arc::strong_count(arc) != 1 {
-            *arc = Arc::new((**arc).clone());
-            assert_eq!(Arc::strong_count(arc), 1);
-        }
-        Arc::get_mut(arc).unwrap()
-    }
-}
-
-impl<T: Default> Default for Arc<T> {
-    fn default() -> Arc<T> {
-        Arc::new(T::default())
-    }
-}
-
-impl<T: ?Sized> Clone for Arc<T> {
-    fn clone(&self) -> Arc<T> {
-        // safe to use Relaxed ordering below because
-        // of the required synchronization for passing
-        // any objects to another thread.
-        let last_count = unsafe { (*self.ptr).rc.fetch_add(1, Ordering::Relaxed) };
-
-        if last_count == usize::max_value() {
-            std::process::abort();
-        }
-
-        Arc { ptr: self.ptr }
-    }
-}
-
-impl<T: ?Sized> Drop for Arc<T> {
-    fn drop(&mut self) {
-        unsafe {
-            let rc = (*self.ptr).rc.fetch_sub(1, Ordering::Release) - 1;
-            if rc == 0 {
-                std::sync::atomic::fence(Ordering::Acquire);
-                Box::from_raw(self.ptr);
-            }
-        }
-    }
-}
-
-impl<T: Copy> From<&[T]> for Arc<[T]> {
-    #[inline]
-    fn from(s: &[T]) -> Arc<[T]> {
-        unsafe { Arc::copy_from_slice(s) }
-    }
-}
-
-#[allow(clippy::fallible_impl_from)]
-impl<T> From<Box<[T]>> for Arc<[T]> {
-    #[inline]
-    fn from(b: Box<[T]>) -> Arc<[T]> {
-        let len = b.len();
-        unsafe {
-            let src = Box::into_raw(b);
-            let value_layout = Layout::for_value(&*src);
-            let align = std::cmp::max(value_layout.align(), mem::align_of::<AtomicUsize>());
-            let rc_width = std::cmp::max(align, mem::size_of::<AtomicUsize>());
-            let unpadded_size = rc_width.checked_add(value_layout.size()).unwrap();
-            // pad the total `Arc` allocation size to the alignment of
-            // `max(value, AtomicUsize)`
-            let size = (unpadded_size + align - 1) & !(align - 1);
-            let dst_layout = Layout::from_size_align(size, align).unwrap();
-            let dst = alloc(dst_layout);
-            assert!(!dst.is_null(), "failed to allocate Arc");
-
-            #[allow(clippy::cast_ptr_alignment)]
-            ptr::write(dst as _, AtomicUsize::new(1));
-            let data_ptr = dst.add(rc_width);
-            ptr::copy_nonoverlapping(src as *const u8, data_ptr, value_layout.size());
-
-            // free the old box memory without running Drop
-            if value_layout.size() != 0 {
-                dealloc(src as *mut u8, value_layout);
-            }
-
-            let fat_ptr: *const ArcInner<[T]> = Arc::fatten(dst, len);
-
-            Arc {
-                ptr: fat_ptr as *mut _,
-            }
-        }
-    }
-}
-
-#[test]
-fn boxed_slice_to_arc_slice() {
-    let box1: Box<[u8]> = Box::new([1, 2, 3]);
-    let arc1: Arc<[u8]> = box1.into();
-    assert_eq!(&*arc1, &*vec![1, 2, 3]);
-    let box2: Box<[u64]> = Box::new([1, 2, 3]);
-    let arc2: Arc<[u64]> = box2.into();
-    assert_eq!(&*arc2, &*vec![1, 2, 3]);
-}
-
-impl<T> From<Vec<T>> for Arc<[T]> {
-    #[inline]
-    fn from(mut v: Vec<T>) -> Arc<[T]> {
-        unsafe {
-            let arc = Arc::copy_from_slice(&v);
-
-            // Allow the Vec to free its memory, but not destroy its contents
-            v.set_len(0);
-
-            arc
-        }
-    }
-}
-
-impl<T: ?Sized> Deref for Arc<T> {
-    type Target = T;
-
-    fn deref(&self) -> &T {
-        unsafe { &(*self.ptr).inner }
-    }
-}
-
-impl<T: ?Sized> std::borrow::Borrow<T> for Arc<T> {
-    fn borrow(&self) -> &T {
-        &**self
-    }
-}
-
-impl<T: ?Sized> AsRef<T> for Arc<T> {
-    fn as_ref(&self) -> &T {
-        &**self
-    }
-}
diff --git a/rust-libs/tools/kv_typed/src/utils/ivec.rs b/rust-libs/tools/kv_typed/src/utils/ivec.rs
deleted file mode 100644
index 50a8d7528..000000000
--- a/rust-libs/tools/kv_typed/src/utils/ivec.rs
+++ /dev/null
@@ -1,314 +0,0 @@
-use std::{
-    convert::TryFrom,
-    fmt,
-    hash::{Hash, Hasher},
-    ops::{Deref, DerefMut},
-    sync::Arc,
-};
-
-const CUTOFF: usize = 22;
-
-type Inner = [u8; CUTOFF];
-
-/// A buffer that may either be inline or remote and protected
-/// by an Arc
-#[derive(Clone)]
-pub struct IVec(IVecInner);
-
-impl Default for IVec {
-    fn default() -> Self {
-        Self::from(&[])
-    }
-}
-
-impl Hash for IVec {
-    fn hash<H: Hasher>(&self, state: &mut H) {
-        self.deref().hash(state);
-    }
-}
-
-#[derive(Clone)]
-enum IVecInner {
-    Inline(u8, Inner),
-    Remote(Arc<[u8]>),
-    Subslice {
-        base: Arc<[u8]>,
-        offset: usize,
-        len: usize,
-    },
-}
-
-const fn is_inline_candidate(length: usize) -> bool {
-    length <= CUTOFF
-}
-
-impl IVec {
-    pub fn subslice(&self, slice_offset: usize, len: usize) -> Self {
-        assert!(self.len().checked_sub(slice_offset).expect("") >= len);
-
-        let inner = match self.0 {
-            IVecInner::Remote(ref base) => IVecInner::Subslice {
-                base: base.clone(),
-                offset: slice_offset,
-                len,
-            },
-            IVecInner::Inline(_, old_inner) => {
-                // old length already checked above in assertion
-                let mut new_inner = Inner::default();
-                new_inner[..len].copy_from_slice(&old_inner[slice_offset..slice_offset + len]);
-
-                IVecInner::Inline(u8::try_from(len).expect(""), new_inner)
-            }
-            IVecInner::Subslice {
-                ref base,
-                ref offset,
-                ..
-            } => IVecInner::Subslice {
-                base: base.clone(),
-                offset: offset + slice_offset,
-                len,
-            },
-        };
-
-        IVec(inner)
-    }
-
-    fn inline(slice: &[u8]) -> Self {
-        assert!(is_inline_candidate(slice.len()));
-
-        let mut data = Inner::default();
-
-        #[allow(unsafe_code)]
-        unsafe {
-            std::ptr::copy_nonoverlapping(slice.as_ptr(), data.as_mut_ptr(), slice.len());
-        }
-
-        Self(IVecInner::Inline(
-            u8::try_from(slice.len()).expect(""),
-            data,
-        ))
-    }
-
-    fn remote(arc: Arc<[u8]>) -> Self {
-        Self(IVecInner::Remote(arc))
-    }
-
-    fn make_mut(&mut self) {
-        match self.0 {
-            IVecInner::Remote(ref mut buf) if Arc::strong_count(buf) != 1 => {
-                self.0 = IVecInner::Remote(buf.to_vec().into());
-            }
-            IVecInner::Subslice {
-                ref mut base,
-                offset,
-                len,
-            } if Arc::strong_count(base) != 1 => {
-                self.0 = IVecInner::Remote(base[offset..offset + len].to_vec().into());
-            }
-            _ => {}
-        }
-    }
-}
-
-impl From<Box<[u8]>> for IVec {
-    fn from(b: Box<[u8]>) -> Self {
-        if is_inline_candidate(b.len()) {
-            Self::inline(&b)
-        } else {
-            Self::remote(Arc::from(b))
-        }
-    }
-}
-
-impl From<&[u8]> for IVec {
-    fn from(slice: &[u8]) -> Self {
-        if is_inline_candidate(slice.len()) {
-            Self::inline(slice)
-        } else {
-            Self::remote(Arc::from(slice))
-        }
-    }
-}
-
-impl From<Arc<[u8]>> for IVec {
-    fn from(arc: Arc<[u8]>) -> Self {
-        if is_inline_candidate(arc.len()) {
-            Self::inline(&arc)
-        } else {
-            Self::remote(arc)
-        }
-    }
-}
-
-impl From<&IVec> for IVec {
-    fn from(v: &Self) -> Self {
-        v.clone()
-    }
-}
-
-impl std::borrow::Borrow<[u8]> for IVec {
-    fn borrow(&self) -> &[u8] {
-        self.as_ref()
-    }
-}
-
-impl std::borrow::Borrow<[u8]> for &IVec {
-    fn borrow(&self) -> &[u8] {
-        self.as_ref()
-    }
-}
-
-macro_rules! from_array {
-    ($($s:expr),*) => {
-        $(
-            impl From<&[u8; $s]> for IVec {
-                fn from(v: &[u8; $s]) -> Self {
-                    Self::from(&v[..])
-                }
-            }
-        )*
-    }
-}
-
-from_array!(
-    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
-    26, 27, 28, 29, 30, 31, 32
-);
-
-impl Into<Arc<[u8]>> for IVec {
-    fn into(self) -> Arc<[u8]> {
-        match self.0 {
-            IVecInner::Inline(..) => Arc::from(self.as_ref()),
-            IVecInner::Remote(arc) => arc,
-            IVecInner::Subslice { .. } => self.deref().into(),
-        }
-    }
-}
-
-impl Deref for IVec {
-    type Target = [u8];
-
-    #[inline]
-    fn deref(&self) -> &[u8] {
-        self.as_ref()
-    }
-}
-
-impl AsRef<[u8]> for IVec {
-    #[inline]
-    #[allow(unsafe_code)]
-    fn as_ref(&self) -> &[u8] {
-        match &self.0 {
-            IVecInner::Inline(sz, buf) => unsafe { buf.get_unchecked(..*sz as usize) },
-            IVecInner::Remote(buf) => buf,
-            IVecInner::Subslice {
-                ref base,
-                offset,
-                len,
-            } => &base[*offset..*offset + *len],
-        }
-    }
-}
-
-impl DerefMut for IVec {
-    #[inline]
-    fn deref_mut(&mut self) -> &mut [u8] {
-        self.as_mut()
-    }
-}
-
-impl AsMut<[u8]> for IVec {
-    #[inline]
-    #[allow(unsafe_code)]
-    fn as_mut(&mut self) -> &mut [u8] {
-        self.make_mut();
-
-        match &mut self.0 {
-            IVecInner::Inline(ref sz, ref mut buf) => unsafe {
-                std::slice::from_raw_parts_mut(buf.as_mut_ptr(), *sz as usize)
-            },
-            IVecInner::Remote(ref mut buf) => Arc::get_mut(buf).expect(""),
-            IVecInner::Subslice {
-                ref mut base,
-                offset,
-                len,
-            } => &mut Arc::get_mut(base).expect("")[*offset..*offset + *len],
-        }
-    }
-}
-
-impl Ord for IVec {
-    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
-        self.as_ref().cmp(other.as_ref())
-    }
-}
-
-impl PartialOrd for IVec {
-    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
-        Some(self.cmp(other))
-    }
-}
-
-impl<T: AsRef<[u8]>> PartialEq<T> for IVec {
-    fn eq(&self, other: &T) -> bool {
-        self.as_ref() == other.as_ref()
-    }
-}
-
-impl PartialEq<[u8]> for IVec {
-    fn eq(&self, other: &[u8]) -> bool {
-        self.as_ref() == other
-    }
-}
-
-impl Eq for IVec {}
-
-impl fmt::Debug for IVec {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        self.as_ref().fmt(f)
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn ivec_usage() {
-        let iv2 = IVec::from(&[4; 128][..]);
-        assert_eq!(iv2, vec![4; 128]);
-    }
-
-    #[test]
-    fn boxed_slice_conversion() {
-        let boite1: Box<[u8]> = Box::new([1, 2, 3]);
-        let iv1: IVec = boite1.into();
-        assert_eq!(iv1, vec![1, 2, 3]);
-        let boite2: Box<[u8]> = Box::new([4; 128]);
-        let iv2: IVec = boite2.into();
-        assert_eq!(iv2, vec![4; 128]);
-    }
-
-    #[test]
-    #[should_panic]
-    fn subslice_usage_00() {
-        let iv1 = IVec::from(&[1, 2, 3][..]);
-        let _subslice = iv1.subslice(0, 4);
-    }
-
-    #[test]
-    #[should_panic]
-    fn subslice_usage_01() {
-        let iv1 = IVec::from(&[1, 2, 3][..]);
-        let _subslice = iv1.subslice(3, 1);
-    }
-
-    #[test]
-    fn ivec_as_mut_identity() {
-        let initial = &[1];
-        let mut iv = IVec::from(initial);
-        assert_eq!(&*initial, &*iv);
-        assert_eq!(&*initial, &mut *iv);
-        assert_eq!(&*initial, iv.as_mut());
-    }
-}
diff --git a/rust-libs/tools/kv_typed/src/value.rs b/rust-libs/tools/kv_typed/src/value.rs
deleted file mode 100644
index ec71f8da5..000000000
--- a/rust-libs/tools/kv_typed/src/value.rs
+++ /dev/null
@@ -1,155 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// 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.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-//! KV Typed Value trait
-
-use crate::*;
-
-/// Trait to be implemented by the collection value
-#[cfg(not(feature = "explorer"))]
-pub trait Value: 'static + AsBytes + Debug + FromBytes + PartialEq + Send + Sync + Sized {}
-
-#[cfg(feature = "explorer")]
-pub trait Value:
-    'static + AsBytes + Debug + ExplorableValue + FromBytes + PartialEq + Send + Sync + Sized
-{
-}
-
-#[cfg(not(feature = "explorer"))]
-impl<T> Value for T where T: 'static + AsBytes + Debug + FromBytes + PartialEq + Send + Sync + Sized {}
-
-#[cfg(feature = "explorer")]
-impl<T> Value for T where
-    T: 'static + AsBytes + Debug + ExplorableValue + FromBytes + PartialEq + Send + Sync + Sized
-{
-}
-
-pub trait ValueZc: Value {
-    type Ref: Sized + zerocopy::AsBytes + zerocopy::FromBytes;
-}
-
-impl ValueZc for () {
-    type Ref = ();
-}
-
-macro_rules! impl_value_zc_for_numbers {
-    ($($T:ty),*) => {$(
-        impl ValueZc for $T {
-            type Ref = Self;
-        }
-    )*};
-}
-impl_value_zc_for_numbers!(
-    usize, u8, u16, u32, u64, u128, isize, i8, i16, i32, i64, i128, f32, f64
-);
-
-pub trait ValueSliceZc: Value {
-    type Elem: Sized + zerocopy::AsBytes + zerocopy::FromBytes;
-
-    fn prefix_len() -> usize {
-        8
-    }
-}
-
-impl ValueSliceZc for () {
-    type Elem = ();
-
-    fn prefix_len() -> usize {
-        0
-    }
-}
-
-impl ValueSliceZc for String {
-    type Elem = u8;
-
-    fn prefix_len() -> usize {
-        0
-    }
-}
-
-impl<T, E> ValueSliceZc for Vec<T>
-where
-    T: 'static
-        + Copy
-        + Debug
-        + Default
-        + Display
-        + FromStr<Err = E>
-        + PartialEq
-        + Send
-        + Sized
-        + Sync
-        + zerocopy::AsBytes
-        + zerocopy::FromBytes,
-    E: Error + Send + Sync + 'static,
-{
-    type Elem = T;
-
-    fn prefix_len() -> usize {
-        0
-    }
-}
-
-macro_rules! impl_value_slice_zc_for_smallvec {
-    ($($N:literal),*) => {$(
-        impl<T, E> ValueSliceZc for SmallVec<[T; $N]>
-        where
-            T: 'static
-                + Copy
-                + Debug
-                + Default
-                + Display
-                + FromStr<Err = E>
-                + PartialEq
-                + Send
-                + Sized
-                + Sync
-                + zerocopy::AsBytes
-                + zerocopy::FromBytes,
-            E: Error + Send + Sync + 'static,
-        {
-            type Elem = T;
-
-            fn prefix_len() -> usize {
-                0
-            }
-        }
-    )*};
-}
-impl_value_slice_zc_for_smallvec!(2, 4, 8, 16, 32, 64);
-
-impl<T, E> ValueSliceZc for BTreeSet<T>
-where
-    T: 'static
-        + Copy
-        + Debug
-        + Default
-        + Display
-        + FromStr<Err = E>
-        + Ord
-        + PartialEq
-        + Send
-        + Sized
-        + Sync
-        + zerocopy::AsBytes
-        + zerocopy::FromBytes,
-    E: Error + Send + Sync + 'static,
-{
-    type Elem = T;
-
-    fn prefix_len() -> usize {
-        0
-    }
-}
diff --git a/rust-libs/tools/kv_typed/tests/test_db_schema.rs b/rust-libs/tools/kv_typed/tests/test_db_schema.rs
deleted file mode 100644
index 7f2432b61..000000000
--- a/rust-libs/tools/kv_typed/tests/test_db_schema.rs
+++ /dev/null
@@ -1,221 +0,0 @@
-use kv_typed::backend::memory::Mem;
-use kv_typed::db_schema;
-use kv_typed::prelude::*;
-use std::collections::BTreeSet;
-
-db_schema!(
-    TestV1,
-    [
-        ["c1", Col1, i32, String],
-        ["c2", Col2, usize, ()],
-        ["c3", Col3, U32BE, Vec<u128>],
-        ["c4", Col4, U64BE, BTreeSet<u128>],
-    ]
-);
-
-#[test]
-#[allow(clippy::eq_op)]
-fn test_macro_db() {
-    assert_eq!(Col1Event::RemoveAll, Col1Event::RemoveAll);
-
-    #[cfg(feature = "explorer")]
-    {
-        use kv_typed::explorer::DbExplorable as _;
-        assert_eq!(
-            TestV1Db::<Mem>::list_collections(),
-            vec![
-                ("col1", "i32", "String"),
-                ("col2", "usize", "()"),
-                ("col3", "U32BE", "Vec<u128>"),
-                ("col4", "U64BE", "BTreeSet<u128>")
-            ]
-        );
-    }
-}
-
-#[test]
-fn test_db_mem() -> KvResult<()> {
-    let db = TestV1Db::<kv_typed::backend::memory::Mem>::open(
-        kv_typed::backend::memory::MemConf::default(),
-    )?;
-
-    test_db(&db)
-}
-
-//#[cfg(feature = "sled_backend")]
-#[test]
-fn test_db_sled() -> KvResult<()> {
-    let db = TestV1Db::<Sled>::open(SledConf::default().temporary(true))?;
-
-    test_db(&db)
-}
-
-fn test_db<B: Backend>(db: &TestV1Db<B>) -> KvResult<()> {
-    let (sender, recv) = kv_typed::channel::unbounded();
-    db.col1().subscribe(sender)?;
-
-    let db2 = db.clone();
-
-    let handler = std::thread::spawn(move || db2.col1_write().upsert(3, "toto".to_owned()));
-    handler.join().expect("thread panic")?;
-
-    let expected_events: Events<Col1Event> = smallvec::smallvec![Col1Event::Upsert {
-        key: 3,
-        value: "toto".to_owned(),
-    }];
-    if let Ok(msg) = recv.recv() {
-        assert_eq!(msg.as_ref(), &expected_events,)
-    } else {
-        panic!("must be receive event")
-    }
-
-    assert_eq!(db.col1().get(&3)?, Some("toto".to_owned()),);
-    let d = db.col1().get_ref_slice(&3, |bytes| {
-        let str_ = unsafe { core::str::from_utf8_unchecked(bytes) };
-        assert_eq!("toto", str_);
-        assert_eq!(db.col2().get(&3)?, None,);
-        Ok(str_.to_owned())
-    })?;
-    assert_eq!(d, Some("toto".to_owned()));
-
-    assert_eq!(db.col2().get(&3)?, None,);
-    db.col2_write().upsert(3, ())?;
-    assert_eq!(db.col2().get(&3)?, Some(()),);
-
-    db.col1_write().upsert(5, "tutu".to_owned())?;
-
-    db.col1().iter(.., |mut iter| {
-        assert_eq!(iter.next_res()?, Some((3, "toto".to_owned())));
-        assert_eq!(iter.next_res()?, Some((5, "tutu".to_owned())));
-        assert_eq!(iter.next_res()?, None);
-        Ok::<(), KvError>(())
-    })?;
-
-    db.col1().iter_rev(.., |it| {
-        let mut iter = it.values();
-
-        assert_eq!(iter.next_res()?, Some("tutu".to_owned()));
-        assert_eq!(iter.next_res()?, Some("toto".to_owned()));
-        assert_eq!(iter.next_res()?, None);
-        Ok::<(), KvError>(())
-    })?;
-
-    db.col1_write().upsert(7, "titi".to_owned())?;
-
-    db.col1().iter_rev(.., |it| {
-        let mut iter = it.values().step_by(2);
-
-        assert_eq!(iter.next_res()?, Some("titi".to_owned()));
-        assert_eq!(iter.next_res()?, Some("toto".to_owned()));
-        assert_eq!(iter.next_res()?, None);
-
-        Ok::<(), KvError>(())
-    })?;
-
-    db.col3_write().upsert(U32BE(4), vec![1, 2, 3])?;
-    db.col3().get_ref_slice(&U32BE(4), |numbers| {
-        assert_eq!(numbers, &[1, 2, 3]);
-        Ok(())
-    })?;
-
-    // Test get_ref_slice
-    db.col4_write()
-        .upsert(U64BE(4), (&[3, 2, 4, 1]).iter().copied().collect())?;
-    db.col4().get_ref_slice(&U64BE(4), |numbers| {
-        assert_eq!(numbers, &[1, 2, 3, 4]);
-        Ok(())
-    })?;
-
-    // Test iter_ref_slice
-    let vec: Vec<(U32BE, Vec<u128>)> = db
-        .col3()
-        .iter_ref_slice(.., |k, v_slice| Ok((k.into(), Vec::from(v_slice))))
-        .collect::<KvResult<_>>()?;
-    assert_eq!(vec, vec![(U32BE(4), vec![1, 2, 3])]);
-
-    // Test transactional
-    // A read tx should be opened when write tx not commited
-    let (s1, r1) = flume::bounded::<()>(0);
-    let (s2, r2) = flume::bounded::<()>(0);
-    let db_ro = db.get_ro_handler();
-    let read_task = std::thread::spawn(move || {
-        r1.recv().expect("disconnected");
-        (db_ro.col3(), db_ro.col4(), db_ro.col2()).read(|(c3, c4, _c2)| {
-            c3.get_ref_slice(&U32BE(4), |numbers| {
-                assert_eq!(numbers, &[1, 2, 3]);
-                Ok(())
-            })?;
-            c3.iter(.., |it| {
-                let iter = it.keys();
-                s2.send(()).expect("disconnected");
-                assert_eq!(iter.collect::<KvResult<Vec<_>>>()?, vec![U32BE(4)]);
-                Ok::<(), KvError>(())
-            })?;
-            c4.get_ref_slice(&U64BE(4), |numbers| {
-                assert_eq!(numbers, &[1, 2, 3, 4]);
-                Ok(())
-            })?;
-            Ok(())
-        })
-    });
-
-    let tres: KvResult<()> =
-        (db.col3_write(), db.col4_write(), db.col2_write()).write(|(mut c3, mut c4, _c2)| {
-            s1.send(()).expect("disconnected");
-            assert_eq!(
-                c3.iter(.., |it| it.keys().collect::<KvResult<Vec<_>>>())?,
-                vec![U32BE(4)]
-            );
-            assert_eq!(
-                c3.iter(.., |it| it.values().collect::<KvResult<Vec<_>>>())?,
-                vec![vec![1, 2, 3]]
-            );
-            c3.upsert(U32BE(42), vec![5, 4, 6]);
-            assert_eq!(
-                c3.iter(.., |it| it.keys().collect::<KvResult<Vec<_>>>())?,
-                vec![U32BE(4), U32BE(42)]
-            );
-            assert_eq!(
-                c3.iter_rev(.., |it| it.keys().collect::<KvResult<Vec<_>>>())?,
-                vec![U32BE(42), U32BE(4)]
-            );
-            c3.upsert(U32BE(8), vec![11, 12, 13]);
-            c3.remove(U32BE(4));
-            assert_eq!(
-                c3.iter(.., |it| it.keys().collect::<KvResult<Vec<_>>>())?,
-                vec![U32BE(8), U32BE(42)]
-            );
-            c3.iter_rev(.., |it| {
-                let iter = it.keys();
-                r2.recv().expect("disconnected");
-                assert_eq!(
-                    iter.collect::<KvResult<Vec<_>>>()?,
-                    vec![U32BE(42), U32BE(8)]
-                );
-
-                Ok::<(), KvError>(())
-            })?;
-            c4.upsert(U64BE(4), (&[7, 8, 6, 5]).iter().copied().collect());
-            Ok(())
-        });
-    tres?;
-    read_task.join().expect("read task panic")?;
-
-    // Test clear()
-    db.col4_write().clear()?;
-    assert_eq!(db.col4().count()?, 0);
-
-    // Test transactional 2
-    db.write(|mut db_tx| {
-        db_tx
-            .col4
-            .upsert(U64BE(47), (&[5, 9, 3, 2]).iter().copied().collect());
-        Ok(())
-    })?;
-    db.col4().get_ref_slice(&U64BE(47), |numbers| {
-        assert_eq!(numbers, &[2, 3, 5, 9]);
-        Ok(())
-    })?;
-
-    Ok(())
-}
diff --git a/rust-libs/tools/kv_typed/tests/test_mock.rs b/rust-libs/tools/kv_typed/tests/test_mock.rs
deleted file mode 100644
index 8f68164a2..000000000
--- a/rust-libs/tools/kv_typed/tests/test_mock.rs
+++ /dev/null
@@ -1,54 +0,0 @@
-#[cfg(feature = "mock")]
-mod tests {
-
-    use kv_typed::prelude::*;
-    use mockall::predicate::*;
-    use std::fmt::Debug;
-    use std::ops::{Bound, RangeFull};
-
-    db_schema!(
-        Test,
-        [["c1", col_1, u32, String], ["c2", col_2, String, u64],]
-    );
-
-    fn use_readable_db<DB: TestDbReadable>(db: &DB) -> KvResult<()> {
-        let col1_reader = db.col_1();
-        assert_eq!(col1_reader.count()?, 899);
-        assert_eq!(col1_reader.get(&42)?, Some("toto".to_owned()));
-        let mut iter = col1_reader.iter(..);
-        assert_eq!(iter.next_res()?, Some((42, "toto".to_owned())));
-        assert_eq!(iter.next_res()?, None);
-        Ok(())
-    }
-
-    #[test]
-    fn test_mock_db() -> KvResult<()> {
-        let mut db = MockTestDbReadable::new();
-        db.expect_col_1().times(1).returning(|| {
-            let mut col_1 = MockColRo::<Col1Event>::new();
-            col_1.expect_count().times(1).returning(|| Ok(899));
-            col_1
-                .expect_get()
-                .times(1)
-                .returning(|_| Ok(Some("toto".to_owned())));
-            col_1.expect_iter::<RangeFull>().times(1).returning(|_| {
-                let mut b_iter = MockBackendIter::new();
-                #[allow(clippy::string_lit_as_bytes)]
-                let mut items = vec![
-                    None,
-                    Some(Ok((vec![0u8, 0, 0, 42], "toto".as_bytes().to_vec()))),
-                ];
-                b_iter
-                    .expect_next()
-                    .times(2)
-                    .returning(move || items.pop().unwrap_or(None));
-                KvIter::new(b_iter, (Bound::Unbounded, Bound::Unbounded))
-            });
-            col_1
-        });
-
-        use_readable_db(&db)?;
-
-        Ok(())
-    }
-}
-- 
GitLab