From 447c1b94b4457a3a286fd2521d1dfe2cbbc71a2f Mon Sep 17 00:00:00 2001
From: librelois <c@elo.tf>
Date: Thu, 3 Dec 2020 21:21:29 +0100
Subject: [PATCH] [ref] gva: move read ops specific to gva in gva folder

---
 Cargo.lock                                    | 13 ++++
 Cargo.toml                                    |  3 +-
 rust-libs/duniter-dbs-read-ops/src/lib.rs     | 70 +++--------------
 rust-libs/duniter-dbs-write-ops/src/bc.rs     | 24 +++++-
 rust-libs/duniter-dbs-write-ops/src/bc/txs.rs |  9 ++-
 rust-libs/duniter-dbs/src/bc_v2.rs            |  3 +-
 rust-libs/duniter-mempools/src/lib.rs         | 14 ++--
 rust-libs/duniter-server/Cargo.toml           |  3 +-
 rust-libs/duniter-server/src/lib.rs           | 10 +--
 .../modules/{duniter-gva => gva}/Cargo.toml   |  1 +
 rust-libs/modules/gva/dbs-reader/Cargo.toml   | 21 +++++
 .../gva/dbs-reader}/src/find_inputs.rs        |  2 +-
 rust-libs/modules/gva/dbs-reader/src/lib.rs   | 78 +++++++++++++++++++
 .../gva/dbs-reader}/src/pagination.rs         |  0
 .../gva/dbs-reader}/src/txs_history.rs        |  4 -
 .../gva/dbs-reader}/src/uds_of_pubkey.rs      |  0
 .../gva/dbs-reader}/src/utxos.rs              |  0
 .../{duniter-gva => gva}/src/anti_spam.rs     |  0
 .../{duniter-gva => gva}/src/entities.rs      |  0
 .../src/entities/tx_gva.rs                    |  0
 .../src/entities/ud_gva.rs                    |  0
 .../{duniter-gva => gva}/src/inputs.rs        |  0
 .../src/inputs_validators.rs                  |  0
 .../modules/{duniter-gva => gva}/src/lib.rs   | 10 +--
 .../{duniter-gva => gva}/src/mutations.rs     |  4 +-
 .../{duniter-gva => gva}/src/pagination.rs    |  4 +-
 .../{duniter-gva => gva}/src/queries.rs       |  0
 .../src/queries/account_balance.rs            |  0
 .../src/queries/gen_tx.rs                     | 16 ++--
 .../src/queries/txs_history.rs                |  2 +-
 .../{duniter-gva => gva}/src/queries/uds.rs   | 12 +--
 .../{duniter-gva => gva}/src/queries/utxos.rs | 10 ++-
 .../{duniter-gva => gva}/src/schema.rs        |  0
 .../{duniter-gva => gva}/src/subscriptions.rs |  0
 .../modules/{duniter-gva => gva}/src/warp_.rs |  0
 .../duniter-integration-tests/Cargo.toml      |  2 +-
 36 files changed, 201 insertions(+), 114 deletions(-)
 rename rust-libs/modules/{duniter-gva => gva}/Cargo.toml (95%)
 create mode 100644 rust-libs/modules/gva/dbs-reader/Cargo.toml
 rename rust-libs/{duniter-dbs-read-ops => modules/gva/dbs-reader}/src/find_inputs.rs (99%)
 create mode 100644 rust-libs/modules/gva/dbs-reader/src/lib.rs
 rename rust-libs/{duniter-dbs-read-ops => modules/gva/dbs-reader}/src/pagination.rs (100%)
 rename rust-libs/{duniter-dbs-read-ops => modules/gva/dbs-reader}/src/txs_history.rs (95%)
 rename rust-libs/{duniter-dbs-read-ops => modules/gva/dbs-reader}/src/uds_of_pubkey.rs (100%)
 rename rust-libs/{duniter-dbs-read-ops => modules/gva/dbs-reader}/src/utxos.rs (100%)
 rename rust-libs/modules/{duniter-gva => gva}/src/anti_spam.rs (100%)
 rename rust-libs/modules/{duniter-gva => gva}/src/entities.rs (100%)
 rename rust-libs/modules/{duniter-gva => gva}/src/entities/tx_gva.rs (100%)
 rename rust-libs/modules/{duniter-gva => gva}/src/entities/ud_gva.rs (100%)
 rename rust-libs/modules/{duniter-gva => gva}/src/inputs.rs (100%)
 rename rust-libs/modules/{duniter-gva => gva}/src/inputs_validators.rs (100%)
 rename rust-libs/modules/{duniter-gva => gva}/src/lib.rs (97%)
 rename rust-libs/modules/{duniter-gva => gva}/src/mutations.rs (93%)
 rename rust-libs/modules/{duniter-gva => gva}/src/pagination.rs (93%)
 rename rust-libs/modules/{duniter-gva => gva}/src/queries.rs (100%)
 rename rust-libs/modules/{duniter-gva => gva}/src/queries/account_balance.rs (100%)
 rename rust-libs/modules/{duniter-gva => gva}/src/queries/gen_tx.rs (94%)
 rename rust-libs/modules/{duniter-gva => gva}/src/queries/txs_history.rs (96%)
 rename rust-libs/modules/{duniter-gva => gva}/src/queries/uds.rs (93%)
 rename rust-libs/modules/{duniter-gva => gva}/src/queries/utxos.rs (92%)
 rename rust-libs/modules/{duniter-gva => gva}/src/schema.rs (100%)
 rename rust-libs/modules/{duniter-gva => gva}/src/subscriptions.rs (100%)
 rename rust-libs/modules/{duniter-gva => gva}/src/warp_.rs (100%)

diff --git a/Cargo.lock b/Cargo.lock
index 5f520b6ab..de8ab415d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1141,6 +1141,7 @@ dependencies = [
  "duniter-conf",
  "duniter-dbs",
  "duniter-dbs-read-ops",
+ "duniter-gva-dbs-reader",
  "duniter-mempools",
  "duniter-module",
  "fast-threadpool",
@@ -1158,6 +1159,17 @@ dependencies = [
  "warp",
 ]
 
+[[package]]
+name = "duniter-gva-dbs-reader"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "dubp",
+ "duniter-dbs",
+ "resiter",
+ "smallvec",
+]
+
 [[package]]
 name = "duniter-integration-tests"
 version = "0.1.0"
@@ -1235,6 +1247,7 @@ dependencies = [
  "duniter-dbs-read-ops",
  "duniter-dbs-write-ops",
  "duniter-gva",
+ "duniter-gva-dbs-reader",
  "duniter-mempools",
  "duniter-module",
  "fast-threadpool",
diff --git a/Cargo.toml b/Cargo.toml
index 09974e444..636eb3e9a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -41,7 +41,8 @@ members = [
     "rust-libs/duniter-mempools",
     "rust-libs/duniter-module",
     "rust-libs/duniter-server",
-    "rust-libs/modules/duniter-gva",
+    "rust-libs/modules/gva",
+    "rust-libs/modules/gva/dbs-reader",
     "rust-libs/tests/duniter-integration-tests",
     "rust-libs/tools/kv_typed"
 ]
diff --git a/rust-libs/duniter-dbs-read-ops/src/lib.rs b/rust-libs/duniter-dbs-read-ops/src/lib.rs
index 6dfa5f309..807087000 100644
--- a/rust-libs/duniter-dbs-read-ops/src/lib.rs
+++ b/rust-libs/duniter-dbs-read-ops/src/lib.rs
@@ -22,66 +22,16 @@
     unused_import_braces
 )]
 
-pub mod find_inputs;
-pub mod pagination;
-pub mod txs_history;
-pub mod uds_of_pubkey;
-pub mod utxos;
-
-pub use crate::pagination::{PageInfo, PagedData};
-
-use crate::pagination::{has_next_page, has_previous_page};
-use dubp::common::crypto::hashs::Hash;
-use dubp::common::crypto::keys::ed25519::PublicKey;
-use dubp::documents::transaction::TransactionDocumentV10;
-use dubp::{common::prelude::BlockNumber, wallet::prelude::*};
-use duniter_dbs::bc_v2::BcV2DbReadable;
-use duniter_dbs::{
-    kv_typed::prelude::*, BlockMetaV2, GvaV1DbReadable, HashKeyV2, PubKeyKeyV2, SourceAmountValV2,
-    TxDbV2, TxsMpV2DbReadable, UtxoIdDbV2,
-};
-use resiter::filter::Filter;
-use resiter::filter_map::FilterMap;
-use resiter::map::Map;
-use std::{collections::BTreeSet, str::FromStr};
-
-pub(crate) fn wrong_cursor() -> StringErr {
-    StringErr("wrong cursor".to_owned())
-}
-
-#[derive(Clone, Copy, Debug)]
-pub struct DbsReader;
-
-pub fn create_dbs_reader() -> DbsReader {
-    DbsReader
+use dubp::crypto::hashs::Hash;
+use duniter_dbs::{bc_v2::BcV2DbReadable, HashKeyV2};
+use duniter_dbs::{kv_typed::prelude::*, BlockMetaV2};
+
+pub fn get_current_block_meta<BcDb: BcV2DbReadable>(bc_db: &BcDb) -> KvResult<Option<BlockMetaV2>> {
+    bc_db
+        .blocks_meta()
+        .iter(.., |it| it.reverse().values().next_res())
 }
 
-impl DbsReader {
-    pub fn get_account_balance<GvaDb: GvaV1DbReadable>(
-        &self,
-        gva_db: &GvaDb,
-        account_script: &WalletScriptV10,
-    ) -> KvResult<Option<SourceAmountValV2>> {
-        gva_db
-            .balances()
-            .get(duniter_dbs::WalletConditionsV2::from_ref(account_script))
-    }
-
-    pub fn get_current_block_meta<BcDb: BcV2DbReadable>(
-        &self,
-        bc_db: &BcDb,
-    ) -> KvResult<Option<BlockMetaV2>> {
-        bc_db
-            .blocks_meta()
-            .iter(.., |it| it.reverse().values().next_res())
-    }
-
-    pub fn get_current_ud<BcDb: BcV2DbReadable>(
-        &self,
-        bc_db: &BcDb,
-    ) -> KvResult<Option<SourceAmount>> {
-        bc_db
-            .uds_reval()
-            .iter(.., |it| it.reverse().values().map_ok(|v| v.0).next_res())
-    }
+pub fn tx_exist<BcDb: BcV2DbReadable>(bc_db_ro: &BcDb, hash: Hash) -> KvResult<bool> {
+    Ok(bc_db_ro.txs_hashs().contains_key(&HashKeyV2(hash))?)
 }
diff --git a/rust-libs/duniter-dbs-write-ops/src/bc.rs b/rust-libs/duniter-dbs-write-ops/src/bc.rs
index 9575f6324..7bf65776c 100644
--- a/rust-libs/duniter-dbs-write-ops/src/bc.rs
+++ b/rust-libs/duniter-dbs-write-ops/src/bc.rs
@@ -45,12 +45,20 @@ pub fn apply_block<B: Backend>(
     (
         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(),
     )
         .write(
-            |(mut blocks_meta, mut identities, mut uds, mut uds_reval, mut uids_index)| {
+            |(
+                mut blocks_meta,
+                mut identities,
+                mut txs_hashs,
+                mut uds,
+                mut uds_reval,
+                mut uids_index,
+            )| {
                 blocks_meta.upsert(U32BE(block.number().0), block_meta);
                 identities::update_identities::<B>(&block, &mut identities)?;
                 for idty in block.identities() {
@@ -67,7 +75,7 @@ pub fn apply_block<B: Backend>(
                         &mut uds_reval,
                     )?;
                 }
-                txs::apply_txs::<B>(block.transactions(), &mut uds)?;
+                txs::apply_txs::<B>(block.transactions(), &mut txs_hashs, &mut uds)?;
                 Ok(())
             },
         )?;
@@ -82,13 +90,21 @@ pub fn revert_block<B: Backend>(
     (
         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(),
     )
         .write(
-            |(mut blocks_meta, mut identities, mut uds, mut uds_reval, mut uids_index)| {
-                txs::revert_txs::<B>(block.transactions(), &mut uds)?;
+            |(
+                mut blocks_meta,
+                mut identities,
+                mut txs_hashs,
+                mut uds,
+                mut uds_reval,
+                mut uids_index,
+            )| {
+                txs::revert_txs::<B>(block.transactions(), &mut txs_hashs, &mut uds)?;
                 if block.dividend().is_some() {
                     uds::revert_uds::<B>(
                         block.number(),
diff --git a/rust-libs/duniter-dbs-write-ops/src/bc/txs.rs b/rust-libs/duniter-dbs-write-ops/src/bc/txs.rs
index 07ddfe1f7..e00e4f88d 100644
--- a/rust-libs/duniter-dbs-write-ops/src/bc/txs.rs
+++ b/rust-libs/duniter-dbs-write-ops/src/bc/txs.rs
@@ -14,13 +14,18 @@
 // along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 use crate::*;
-use duniter_dbs::{bc_v2::UdsEvent, UdIdV2};
+use duniter_dbs::{
+    bc_v2::{TxsHashsEvent, UdsEvent},
+    UdIdV2,
+};
 
 pub(crate) fn apply_txs<B: Backend>(
     block_txs: &[TransactionDocumentV10],
+    txs_hashs: &mut TxColRw<B::Col, TxsHashsEvent>,
     uds: &mut TxColRw<B::Col, UdsEvent>,
 ) -> KvResult<()> {
     for tx in block_txs {
+        txs_hashs.upsert(HashKeyV2(tx.get_hash()), ());
         for input in tx.get_inputs() {
             if let SourceIdV10::Ud(UdSourceIdV10 {
                 issuer,
@@ -36,9 +41,11 @@ pub(crate) fn apply_txs<B: Backend>(
 
 pub(crate) fn revert_txs<B: Backend>(
     block_txs: &[TransactionDocumentV10],
+    txs_hashs: &mut TxColRw<B::Col, TxsHashsEvent>,
     uds: &mut TxColRw<B::Col, UdsEvent>,
 ) -> KvResult<()> {
     for tx in block_txs {
+        txs_hashs.remove(HashKeyV2(tx.get_hash()));
         for input in tx.get_inputs() {
             if let SourceIdV10::Ud(UdSourceIdV10 {
                 issuer,
diff --git a/rust-libs/duniter-dbs/src/bc_v2.rs b/rust-libs/duniter-dbs/src/bc_v2.rs
index a254e3249..81dae61f2 100644
--- a/rust-libs/duniter-dbs/src/bc_v2.rs
+++ b/rust-libs/duniter-dbs/src/bc_v2.rs
@@ -19,9 +19,10 @@ db_schema!(
     BcV2,
     [
         ["blocks_meta", BlocksMeta, U32BE, BlockMetaV2],
-        ["uds_reval", UdsReval, U32BE, SourceAmountValV2],
         ["identities", Identities, PubKeyKeyV2, IdtyDbV2],
+        ["txs_hashs", TxsHashs, HashKeyV2, ()],
         ["uds", Uds, UdIdV2, ()],
+        ["uds_reval", UdsReval, U32BE, SourceAmountValV2],
         ["uids_index", UidsIndex, String, PubKeyValV2],
     ]
 );
diff --git a/rust-libs/duniter-mempools/src/lib.rs b/rust-libs/duniter-mempools/src/lib.rs
index 9ebbc0f8c..63ecd1943 100644
--- a/rust-libs/duniter-mempools/src/lib.rs
+++ b/rust-libs/duniter-mempools/src/lib.rs
@@ -28,7 +28,7 @@ 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::{GvaV1DbReadable, TxsMpV2Db, TxsMpV2DbReadable};
+use duniter_dbs::{bc_v2::BcV2DbReadable, TxsMpV2Db, TxsMpV2DbReadable};
 use thiserror::Error;
 
 #[derive(Clone, Copy, Debug, Default)]
@@ -61,14 +61,14 @@ impl TxsMempool {
     pub fn new(max_size: usize) -> Self {
         TxsMempool { max_size }
     }
-    pub fn accept_new_tx<GvaDb: GvaV1DbReadable, TxsMpDb: TxsMpV2DbReadable>(
+    pub fn accept_new_tx<BcDb: BcV2DbReadable, TxsMpDb: TxsMpV2DbReadable>(
         &self,
-        gva_db_ro: &GvaDb,
+        bc_db_ro: &BcDb,
         server_pubkey: PublicKey,
         tx: TransactionDocumentV10,
         txs_mp_db_ro: &TxsMpDb,
     ) -> Result<(), TxMpError> {
-        if duniter_dbs_read_ops::txs_history::tx_exist(gva_db_ro, tx.get_hash())? {
+        if duniter_dbs_read_ops::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
@@ -79,14 +79,14 @@ impl TxsMempool {
         }
     }
 
-    pub fn add_pending_tx<B: Backend, GvaDb: GvaV1DbReadable>(
+    pub fn add_pending_tx<B: Backend, BcDb: BcV2DbReadable>(
         &self,
-        gva_db_ro: &GvaDb,
+        bc_db_ro: &BcDb,
         server_pubkey: PublicKey,
         txs_mp_db: &TxsMpV2Db<B>,
         tx: &TransactionDocumentV10,
     ) -> Result<(), TxMpError> {
-        if duniter_dbs_read_ops::txs_history::tx_exist(gva_db_ro, tx.get_hash())? {
+        if duniter_dbs_read_ops::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(
diff --git a/rust-libs/duniter-server/Cargo.toml b/rust-libs/duniter-server/Cargo.toml
index 0818892ff..d491ff2aa 100644
--- a/rust-libs/duniter-server/Cargo.toml
+++ b/rust-libs/duniter-server/Cargo.toml
@@ -12,7 +12,8 @@ duniter-conf = { path = "../duniter-conf" }
 duniter-dbs = { path = "../duniter-dbs" }
 duniter-dbs-read-ops = { path = "../duniter-dbs-read-ops" }
 duniter-dbs-write-ops = { path = "../duniter-dbs-write-ops" }
-duniter-gva = { path = "../modules/duniter-gva" }
+duniter-gva = { path = "../modules/gva" }
+duniter-gva-dbs-reader = { path = "../modules/gva/dbs-reader" }
 duniter-mempools = { path = "../duniter-mempools" }
 duniter-module = { path = "../duniter-module" }
 fast-threadpool = "0.2.1"
diff --git a/rust-libs/duniter-server/src/lib.rs b/rust-libs/duniter-server/src/lib.rs
index 85e5e525d..93dbb28ab 100644
--- a/rust-libs/duniter-server/src/lib.rs
+++ b/rust-libs/duniter-server/src/lib.rs
@@ -38,7 +38,7 @@ use duniter_dbs::{
     kv_typed::prelude::*, GvaV1DbReadable, HashKeyV2, PendingTxDbV2, TxsMpV2DbReadable,
 };
 use duniter_dbs::{prelude::*, BlockMetaV2, FileBackend};
-use duniter_dbs_read_ops::txs_history::TxsHistory;
+use duniter_gva_dbs_reader::txs_history::TxsHistory;
 use duniter_mempools::{Mempools, TxMpError, TxsMempool};
 use duniter_module::{plug_duniter_modules, DuniterModule as _, Endpoint};
 use fast_threadpool::ThreadPoolConfig;
@@ -74,14 +74,12 @@ impl DuniterServer {
             _ => DuniterCommand::Start,
         };
 
-        let dbs_reader = duniter_dbs_read_ops::create_dbs_reader();
         let txs_mempool = TxsMempool::new(conf.txs_mempool_size);
 
         log::info!("open duniter databases...");
         let dbs = duniter_dbs::open_dbs(home_path_opt);
         log::info!("Databases successfully opened.");
-        let current = dbs_reader
-            .get_current_block_meta(&dbs.bc_db)
+        let current = duniter_dbs_read_ops::get_current_block_meta(&dbs.bc_db)
             .context("Fail to get current")?;
         if let Some(current) = current {
             log::info!("Current block: #{}-{}", current.number, current.hash);
@@ -156,7 +154,7 @@ impl DuniterServer {
         match self
             .dbs_pool
             .execute(move |dbs| {
-                txs_mempool.accept_new_tx(&dbs.gva_db, server_pubkey, tx, &dbs.txs_mp_db)
+                txs_mempool.accept_new_tx(&dbs.bc_db, server_pubkey, tx, &dbs.txs_mp_db)
             })
             .expect("dbs pool discorrected")
         {
@@ -208,7 +206,7 @@ impl DuniterServer {
     pub fn get_transactions_history(&self, pubkey: PublicKey) -> KvResult<TxsHistory> {
         self.dbs_pool
             .execute(move |dbs| {
-                duniter_dbs_read_ops::txs_history::get_transactions_history(
+                duniter_gva_dbs_reader::txs_history::get_transactions_history(
                     &dbs.gva_db,
                     &dbs.txs_mp_db,
                     pubkey,
diff --git a/rust-libs/modules/duniter-gva/Cargo.toml b/rust-libs/modules/gva/Cargo.toml
similarity index 95%
rename from rust-libs/modules/duniter-gva/Cargo.toml
rename to rust-libs/modules/gva/Cargo.toml
index 42b07f856..4d3cdbbc8 100644
--- a/rust-libs/modules/duniter-gva/Cargo.toml
+++ b/rust-libs/modules/gva/Cargo.toml
@@ -15,6 +15,7 @@ dubp = { version = "0.32.2" }
 duniter-conf = { path = "../../duniter-conf" }
 duniter-dbs = { path = "../../duniter-dbs" }
 duniter-dbs-read-ops = { path = "../../duniter-dbs-read-ops" }
+duniter-gva-dbs-reader = { path = "./dbs-reader" }
 duniter-mempools = { path = "../../duniter-mempools" }
 duniter-module = { path = "../../duniter-module" }
 fast-threadpool = "0.2.1"
diff --git a/rust-libs/modules/gva/dbs-reader/Cargo.toml b/rust-libs/modules/gva/dbs-reader/Cargo.toml
new file mode 100644
index 000000000..4937998b1
--- /dev/null
+++ b/rust-libs/modules/gva/dbs-reader/Cargo.toml
@@ -0,0 +1,21 @@
+[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"
+
+[dependencies]
+anyhow = "1.0.34"
+duniter-dbs = { path = "../../../duniter-dbs" }
+dubp = { version = "0.32.2" }
+resiter = "0.4.0"
+
+[dev-dependencies]
+smallvec = { version = "1.4.0", features = ["serde", "write"] }
diff --git a/rust-libs/duniter-dbs-read-ops/src/find_inputs.rs b/rust-libs/modules/gva/dbs-reader/src/find_inputs.rs
similarity index 99%
rename from rust-libs/duniter-dbs-read-ops/src/find_inputs.rs
rename to rust-libs/modules/gva/dbs-reader/src/find_inputs.rs
index c311da7e4..59b52eb6c 100644
--- a/rust-libs/duniter-dbs-read-ops/src/find_inputs.rs
+++ b/rust-libs/modules/gva/dbs-reader/src/find_inputs.rs
@@ -136,7 +136,7 @@ pub fn find_inputs<BcDb: BcV2DbReadable, GvaDb: GvaV1DbReadable, TxsMpDb: TxsMpV
 mod tests {
     use super::*;
     use duniter_dbs::{
-        bc_v2::BcV2DbWritable, gva_v1::GvaV1DbWritable, txs_mp_v2::TxsMpV2DbWritable,
+        bc_v2::BcV2DbWritable, gva_v1::GvaV1DbWritable, txs_mp_v2::TxsMpV2DbWritable, BlockMetaV2,
         GvaUtxoIdDbV1, SourceAmountValV2, UdIdV2, UtxoIdDbV2, UtxoValV2, WalletConditionsV2,
     };
 
diff --git a/rust-libs/modules/gva/dbs-reader/src/lib.rs b/rust-libs/modules/gva/dbs-reader/src/lib.rs
new file mode 100644
index 000000000..9f9edb2ab
--- /dev/null
+++ b/rust-libs/modules/gva/dbs-reader/src/lib.rs
@@ -0,0 +1,78 @@
+//  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 find_inputs;
+pub mod pagination;
+pub mod txs_history;
+pub mod uds_of_pubkey;
+pub mod utxos;
+
+pub use crate::pagination::{PageInfo, PagedData};
+
+use crate::pagination::{has_next_page, has_previous_page};
+use dubp::common::crypto::hashs::Hash;
+use dubp::common::crypto::keys::ed25519::PublicKey;
+use dubp::documents::transaction::TransactionDocumentV10;
+use dubp::{common::prelude::BlockNumber, wallet::prelude::*};
+use duniter_dbs::bc_v2::BcV2DbReadable;
+use duniter_dbs::{
+    kv_typed::prelude::*, GvaV1DbReadable, HashKeyV2, PubKeyKeyV2, SourceAmountValV2, TxDbV2,
+    TxsMpV2DbReadable, UtxoIdDbV2,
+};
+use resiter::filter::Filter;
+use resiter::filter_map::FilterMap;
+use resiter::map::Map;
+use std::{collections::BTreeSet, str::FromStr};
+
+pub(crate) fn wrong_cursor() -> StringErr {
+    StringErr("wrong cursor".to_owned())
+}
+
+#[derive(Clone, Copy, Debug)]
+pub struct DbsReader;
+
+pub fn create_dbs_reader() -> DbsReader {
+    DbsReader
+}
+
+impl DbsReader {
+    pub fn get_account_balance<GvaDb: GvaV1DbReadable>(
+        &self,
+        gva_db: &GvaDb,
+        account_script: &WalletScriptV10,
+    ) -> KvResult<Option<SourceAmountValV2>> {
+        gva_db
+            .balances()
+            .get(duniter_dbs::WalletConditionsV2::from_ref(account_script))
+    }
+
+    pub fn get_current_ud<BcDb: BcV2DbReadable>(
+        &self,
+        bc_db: &BcDb,
+    ) -> KvResult<Option<SourceAmount>> {
+        bc_db
+            .uds_reval()
+            .iter(.., |it| it.reverse().values().map_ok(|v| v.0).next_res())
+    }
+}
diff --git a/rust-libs/duniter-dbs-read-ops/src/pagination.rs b/rust-libs/modules/gva/dbs-reader/src/pagination.rs
similarity index 100%
rename from rust-libs/duniter-dbs-read-ops/src/pagination.rs
rename to rust-libs/modules/gva/dbs-reader/src/pagination.rs
diff --git a/rust-libs/duniter-dbs-read-ops/src/txs_history.rs b/rust-libs/modules/gva/dbs-reader/src/txs_history.rs
similarity index 95%
rename from rust-libs/duniter-dbs-read-ops/src/txs_history.rs
rename to rust-libs/modules/gva/dbs-reader/src/txs_history.rs
index 96f75be80..c75211298 100644
--- a/rust-libs/duniter-dbs-read-ops/src/txs_history.rs
+++ b/rust-libs/modules/gva/dbs-reader/src/txs_history.rs
@@ -22,10 +22,6 @@ pub struct TxsHistory {
     pub pending: Vec<TransactionDocumentV10>,
 }
 
-pub fn tx_exist<GvaDb: GvaV1DbReadable>(gva_db_ro: &GvaDb, hash: Hash) -> KvResult<bool> {
-    Ok(gva_db_ro.txs().get(&HashKeyV2(hash))?.is_some())
-}
-
 pub fn get_transactions_history<GvaDb: GvaV1DbReadable, TxsMpDb: TxsMpV2DbReadable>(
     gva_db_ro: &GvaDb,
     txs_mp_db_ro: &TxsMpDb,
diff --git a/rust-libs/duniter-dbs-read-ops/src/uds_of_pubkey.rs b/rust-libs/modules/gva/dbs-reader/src/uds_of_pubkey.rs
similarity index 100%
rename from rust-libs/duniter-dbs-read-ops/src/uds_of_pubkey.rs
rename to rust-libs/modules/gva/dbs-reader/src/uds_of_pubkey.rs
diff --git a/rust-libs/duniter-dbs-read-ops/src/utxos.rs b/rust-libs/modules/gva/dbs-reader/src/utxos.rs
similarity index 100%
rename from rust-libs/duniter-dbs-read-ops/src/utxos.rs
rename to rust-libs/modules/gva/dbs-reader/src/utxos.rs
diff --git a/rust-libs/modules/duniter-gva/src/anti_spam.rs b/rust-libs/modules/gva/src/anti_spam.rs
similarity index 100%
rename from rust-libs/modules/duniter-gva/src/anti_spam.rs
rename to rust-libs/modules/gva/src/anti_spam.rs
diff --git a/rust-libs/modules/duniter-gva/src/entities.rs b/rust-libs/modules/gva/src/entities.rs
similarity index 100%
rename from rust-libs/modules/duniter-gva/src/entities.rs
rename to rust-libs/modules/gva/src/entities.rs
diff --git a/rust-libs/modules/duniter-gva/src/entities/tx_gva.rs b/rust-libs/modules/gva/src/entities/tx_gva.rs
similarity index 100%
rename from rust-libs/modules/duniter-gva/src/entities/tx_gva.rs
rename to rust-libs/modules/gva/src/entities/tx_gva.rs
diff --git a/rust-libs/modules/duniter-gva/src/entities/ud_gva.rs b/rust-libs/modules/gva/src/entities/ud_gva.rs
similarity index 100%
rename from rust-libs/modules/duniter-gva/src/entities/ud_gva.rs
rename to rust-libs/modules/gva/src/entities/ud_gva.rs
diff --git a/rust-libs/modules/duniter-gva/src/inputs.rs b/rust-libs/modules/gva/src/inputs.rs
similarity index 100%
rename from rust-libs/modules/duniter-gva/src/inputs.rs
rename to rust-libs/modules/gva/src/inputs.rs
diff --git a/rust-libs/modules/duniter-gva/src/inputs_validators.rs b/rust-libs/modules/gva/src/inputs_validators.rs
similarity index 100%
rename from rust-libs/modules/duniter-gva/src/inputs_validators.rs
rename to rust-libs/modules/gva/src/inputs_validators.rs
diff --git a/rust-libs/modules/duniter-gva/src/lib.rs b/rust-libs/modules/gva/src/lib.rs
similarity index 97%
rename from rust-libs/modules/duniter-gva/src/lib.rs
rename to rust-libs/modules/gva/src/lib.rs
index 2aec18bd6..374371fda 100644
--- a/rust-libs/modules/duniter-gva/src/lib.rs
+++ b/rust-libs/modules/gva/src/lib.rs
@@ -59,9 +59,9 @@ use dubp::wallet::prelude::*;
 use duniter_dbs::prelude::*;
 use duniter_dbs::{kv_typed::prelude::*, FileBackend, TxDbV2, TxsMpV2DbReadable};
 #[cfg(not(test))]
-use duniter_dbs_read_ops::create_dbs_reader;
+use duniter_gva_dbs_reader::create_dbs_reader;
 #[cfg(not(test))]
-use duniter_dbs_read_ops::DbsReader;
+use duniter_gva_dbs_reader::DbsReader;
 use duniter_mempools::{Mempools, TxsMempool};
 use futures::{StreamExt, TryStreamExt};
 use resiter::map::Map;
@@ -290,7 +290,7 @@ mod tests {
     use duniter_conf::DuniterConf;
     use duniter_dbs::bc_v2::BcV2DbReadable;
     use duniter_dbs::gva_v1::GvaV1DbReadable;
-    use duniter_dbs::{BlockMetaV2, SourceAmountValV2};
+    use duniter_dbs::SourceAmountValV2;
     use duniter_mempools::Mempools;
     use duniter_module::DuniterModule;
     use fast_threadpool::ThreadPoolConfig;
@@ -303,10 +303,6 @@ mod tests {
                 gva_db: &GvaDb,
                 account_script: &WalletScriptV10,
             ) -> KvResult<Option<SourceAmountValV2>>;
-            fn get_current_block_meta<BcDb: 'static + BcV2DbReadable>(
-                &self,
-                bc_db: &BcDb,
-            ) -> KvResult<Option<BlockMetaV2>>;
             fn get_current_ud<BcDb: 'static + BcV2DbReadable>(
                 &self,
                 bc_db: &BcDb,
diff --git a/rust-libs/modules/duniter-gva/src/mutations.rs b/rust-libs/modules/gva/src/mutations.rs
similarity index 93%
rename from rust-libs/modules/duniter-gva/src/mutations.rs
rename to rust-libs/modules/gva/src/mutations.rs
index dff0edd74..7ee8dff61 100644
--- a/rust-libs/modules/duniter-gva/src/mutations.rs
+++ b/rust-libs/modules/gva/src/mutations.rs
@@ -40,7 +40,7 @@ impl MutationRoot {
             .dbs_pool
             .execute(move |dbs| {
                 txs_mempool
-                    .add_pending_tx(&dbs.gva_db, server_pubkey, &dbs.txs_mp_db, &tx)
+                    .add_pending_tx(&dbs.bc_db, server_pubkey, &dbs.txs_mp_db, &tx)
                     .map(|()| tx)
             })
             .await??;
@@ -72,7 +72,7 @@ impl MutationRoot {
                 .dbs_pool
                 .execute(move |dbs| {
                     txs_mempool
-                        .add_pending_tx(&dbs.gva_db, server_pubkey, &dbs.txs_mp_db, &tx)
+                        .add_pending_tx(&dbs.bc_db, server_pubkey, &dbs.txs_mp_db, &tx)
                         .map(|()| tx)
                 })
                 .await??;
diff --git a/rust-libs/modules/duniter-gva/src/pagination.rs b/rust-libs/modules/gva/src/pagination.rs
similarity index 93%
rename from rust-libs/modules/duniter-gva/src/pagination.rs
rename to rust-libs/modules/gva/src/pagination.rs
index c472d102d..20b52484f 100644
--- a/rust-libs/modules/duniter-gva/src/pagination.rs
+++ b/rust-libs/modules/gva/src/pagination.rs
@@ -41,8 +41,8 @@ impl Pagination {
         T: FromStr<Err = E>,
     >(
         self,
-    ) -> anyhow::Result<duniter_dbs_read_ops::PageInfo<T>> {
-        Ok(duniter_dbs_read_ops::PageInfo::new(
+    ) -> anyhow::Result<duniter_gva_dbs_reader::PageInfo<T>> {
+        Ok(duniter_gva_dbs_reader::PageInfo::new(
             self.cursor.map(|c| T::from_str(&c)).transpose()?,
             self.ord == Order::Asc,
             self.page_size.map(|n| n as usize),
diff --git a/rust-libs/modules/duniter-gva/src/queries.rs b/rust-libs/modules/gva/src/queries.rs
similarity index 100%
rename from rust-libs/modules/duniter-gva/src/queries.rs
rename to rust-libs/modules/gva/src/queries.rs
diff --git a/rust-libs/modules/duniter-gva/src/queries/account_balance.rs b/rust-libs/modules/gva/src/queries/account_balance.rs
similarity index 100%
rename from rust-libs/modules/duniter-gva/src/queries/account_balance.rs
rename to rust-libs/modules/gva/src/queries/account_balance.rs
diff --git a/rust-libs/modules/duniter-gva/src/queries/gen_tx.rs b/rust-libs/modules/gva/src/queries/gen_tx.rs
similarity index 94%
rename from rust-libs/modules/duniter-gva/src/queries/gen_tx.rs
rename to rust-libs/modules/gva/src/queries/gen_tx.rs
index ff9df7e2c..61ce75360 100644
--- a/rust-libs/modules/duniter-gva/src/queries/gen_tx.rs
+++ b/rust-libs/modules/gva/src/queries/gen_tx.rs
@@ -112,16 +112,18 @@ impl GenTxsQuery {
         let recipient = PublicKey::from_base58(&recipient)?;
 
         let data = ctx.data::<SchemaData>()?;
-        let dbs_reader = data.dbs_reader();
+        //let dbs_reader = data.dbs_reader();
         let currency = data.server_meta_data.currency.clone();
 
         let (current_block, (inputs, inputs_sum)) = data
             .dbs_pool
             .execute(move |dbs| {
-                if let Some(current_block) = dbs_reader.get_current_block_meta(&dbs.bc_db)? {
+                if let Some(current_block) =
+                    duniter_dbs_read_ops::get_current_block_meta(&dbs.bc_db)?
+                {
                     Ok((
                         current_block,
-                        duniter_dbs_read_ops::find_inputs::find_inputs(
+                        duniter_gva_dbs_reader::find_inputs::find_inputs(
                             &dbs.bc_db,
                             &dbs.gva_db,
                             &dbs.txs_mp_db,
@@ -186,17 +188,19 @@ impl GenTxsQuery {
         }
 
         let data = ctx.data::<SchemaData>()?;
-        let dbs_reader = data.dbs_reader();
+        //let dbs_reader = data.dbs_reader();
         let currency = data.server_meta_data.currency.clone();
 
         let (current_block, issuers_inputs_with_sum) = data
             .dbs_pool
             .execute(move |dbs| {
-                if let Some(current_block) = dbs_reader.get_current_block_meta(&dbs.bc_db)? {
+                if let Some(current_block) =
+                    duniter_dbs_read_ops::get_current_block_meta(&dbs.bc_db)?
+                {
                     let mut issuers_inputs_with_sum = Vec::new();
                     for issuer in issuers {
                         issuers_inputs_with_sum.push((
-                            duniter_dbs_read_ops::find_inputs::find_inputs(
+                            duniter_gva_dbs_reader::find_inputs::find_inputs(
                                 &dbs.bc_db,
                                 &dbs.gva_db,
                                 &dbs.txs_mp_db,
diff --git a/rust-libs/modules/duniter-gva/src/queries/txs_history.rs b/rust-libs/modules/gva/src/queries/txs_history.rs
similarity index 96%
rename from rust-libs/modules/duniter-gva/src/queries/txs_history.rs
rename to rust-libs/modules/gva/src/queries/txs_history.rs
index 3da6cb661..76d623fa3 100644
--- a/rust-libs/modules/duniter-gva/src/queries/txs_history.rs
+++ b/rust-libs/modules/gva/src/queries/txs_history.rs
@@ -32,7 +32,7 @@ impl TxsHistoryQuery {
         let txs_history = data
             .dbs_pool
             .execute(move |dbs| {
-                duniter_dbs_read_ops::txs_history::get_transactions_history(
+                duniter_gva_dbs_reader::txs_history::get_transactions_history(
                     &dbs.gva_db,
                     &dbs.txs_mp_db,
                     pubkey,
diff --git a/rust-libs/modules/duniter-gva/src/queries/uds.rs b/rust-libs/modules/gva/src/queries/uds.rs
similarity index 93%
rename from rust-libs/modules/duniter-gva/src/queries/uds.rs
rename to rust-libs/modules/gva/src/queries/uds.rs
index 3ec603ee3..0a1924c11 100644
--- a/rust-libs/modules/duniter-gva/src/queries/uds.rs
+++ b/rust-libs/modules/gva/src/queries/uds.rs
@@ -16,7 +16,7 @@
 use crate::*;
 use async_graphql::connection::*;
 use duniter_dbs::{bc_v2::BcV2DbReadable, GvaV1DbReadable};
-use duniter_dbs_read_ops::{uds_of_pubkey::UdsWithSum, PagedData};
+use duniter_gva_dbs_reader::{uds_of_pubkey::UdsWithSum, PagedData};
 
 #[derive(Default)]
 pub(crate) struct UdsQuery;
@@ -54,7 +54,7 @@ impl UdsQuery {
         let pubkey = PublicKey::from_base58(&pubkey)?;
 
         let data = ctx.data::<SchemaData>()?;
-        let dbs_reader = data.dbs_reader();
+        //let dbs_reader = data.dbs_reader();
 
         let (
             PagedData {
@@ -66,16 +66,18 @@ impl UdsQuery {
         ) = data
             .dbs_pool
             .execute(move |dbs| {
-                if let Some(current_block) = dbs_reader.get_current_block_meta(&dbs.bc_db)? {
+                if let Some(current_block) =
+                    duniter_dbs_read_ops::get_current_block_meta(&dbs.bc_db)?
+                {
                     let paged_data = match filter {
-                        UdsFilter::All => duniter_dbs_read_ops::uds_of_pubkey::all_uds_of_pubkey(
+                        UdsFilter::All => duniter_gva_dbs_reader::uds_of_pubkey::all_uds_of_pubkey(
                             &dbs.bc_db,
                             &dbs.gva_db,
                             pubkey,
                             pagination,
                         ),
                         UdsFilter::Unspent => {
-                            duniter_dbs_read_ops::uds_of_pubkey::unspent_uds_of_pubkey(
+                            duniter_gva_dbs_reader::uds_of_pubkey::unspent_uds_of_pubkey(
                                 &dbs.bc_db,
                                 pubkey,
                                 pagination,
diff --git a/rust-libs/modules/duniter-gva/src/queries/utxos.rs b/rust-libs/modules/gva/src/queries/utxos.rs
similarity index 92%
rename from rust-libs/modules/duniter-gva/src/queries/utxos.rs
rename to rust-libs/modules/gva/src/queries/utxos.rs
index 982d31f74..20c0a732f 100644
--- a/rust-libs/modules/duniter-gva/src/queries/utxos.rs
+++ b/rust-libs/modules/gva/src/queries/utxos.rs
@@ -16,7 +16,7 @@
 use crate::*;
 use async_graphql::connection::*;
 use duniter_dbs::GvaV1DbReadable;
-use duniter_dbs_read_ops::{
+use duniter_gva_dbs_reader::{
     utxos::{UtxoCursor, UtxosWithSum},
     PagedData,
 };
@@ -38,7 +38,7 @@ impl UtxosQuery {
         let script = dubp::documents_parser::wallet_script_from_str(&script)?;
 
         let data = ctx.data::<SchemaData>()?;
-        let dbs_reader = data.dbs_reader();
+        //let dbs_reader = data.dbs_reader();
 
         let (
             PagedData {
@@ -50,8 +50,10 @@ impl UtxosQuery {
         ) = data
             .dbs_pool
             .execute(move |dbs| {
-                if let Some(current_block) = dbs_reader.get_current_block_meta(&dbs.bc_db)? {
-                    let paged_data = duniter_dbs_read_ops::utxos::find_script_utxos(
+                if let Some(current_block) =
+                    duniter_dbs_read_ops::get_current_block_meta(&dbs.bc_db)?
+                {
+                    let paged_data = duniter_gva_dbs_reader::utxos::find_script_utxos(
                         &dbs.gva_db,
                         &dbs.txs_mp_db,
                         amount.map(|amount| {
diff --git a/rust-libs/modules/duniter-gva/src/schema.rs b/rust-libs/modules/gva/src/schema.rs
similarity index 100%
rename from rust-libs/modules/duniter-gva/src/schema.rs
rename to rust-libs/modules/gva/src/schema.rs
diff --git a/rust-libs/modules/duniter-gva/src/subscriptions.rs b/rust-libs/modules/gva/src/subscriptions.rs
similarity index 100%
rename from rust-libs/modules/duniter-gva/src/subscriptions.rs
rename to rust-libs/modules/gva/src/subscriptions.rs
diff --git a/rust-libs/modules/duniter-gva/src/warp_.rs b/rust-libs/modules/gva/src/warp_.rs
similarity index 100%
rename from rust-libs/modules/duniter-gva/src/warp_.rs
rename to rust-libs/modules/gva/src/warp_.rs
diff --git a/rust-libs/tests/duniter-integration-tests/Cargo.toml b/rust-libs/tests/duniter-integration-tests/Cargo.toml
index 275321cf6..ed2bea409 100644
--- a/rust-libs/tests/duniter-integration-tests/Cargo.toml
+++ b/rust-libs/tests/duniter-integration-tests/Cargo.toml
@@ -12,7 +12,7 @@ duniter-conf = { path = "../../duniter-conf" }
 duniter-dbs = { path = "../../duniter-dbs" }
 duniter-dbs-read-ops = { path = "../../duniter-dbs-read-ops" }
 duniter-dbs-write-ops = { path = "../../duniter-dbs-write-ops" }
-duniter-gva = { path = "../../modules/duniter-gva" }
+duniter-gva = { path = "../../modules/gva" }
 duniter-mempools = { path = "../../duniter-mempools" }
 duniter-module = { path = "../../duniter-module" }
 duniter-server = { path = "../../duniter-server" }
-- 
GitLab