diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 5177bc91c4aac2ff10bed8d8975da55ea61f4889..5323b5f2863e6af92762d107b5dd1c1453f49457 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -100,8 +100,7 @@ tests:linux64:stable:
   script: 
     - cd bin/dunitrust-server
     - RUSTFLAGS="-D warnings" cargo build --features=ssl
-    - cargo test --all --exclude durs-gva
-    - cargo test --package durs-gva -- --test-threads=1
+    - cargo test --all
     - cargo test --all -- --ignored
 
 tests:arm-v7-:stable:
@@ -142,7 +141,7 @@ tests:win64:stable:
     - cargo test --package durs-blockchain --target=x86_64-pc-windows-gnu
     - cargo test --package durs-dbs-tools --target=x86_64-pc-windows-gnu
     #- cargo test --package durs-skeleton-module --target=x86_64-pc-windows-gnu
-    - cargo test --package durs-gva --target=x86_64-pc-windows-gnu -- --test-threads=1
+    - cargo test --package durs-gva --target=x86_64-pc-windows-gnu
     - cargo test --package durs-ws2p-v1-legacy --target=x86_64-pc-windows-gnu
     - cargo test --package durs-ws2p --target=x86_64-pc-windows-gnu
     - cargo test --package durs-ws2p-messages --target=x86_64-pc-windows-gnu
diff --git a/Cargo.lock b/Cargo.lock
index 2b5551845ef7fcb1b90eac95c7490173d0476893..687a33337d7c2095a90fc1e958ff6db2311dcf78 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1032,6 +1032,7 @@ name = "durs-gva"
 version = "0.1.0"
 dependencies = [
  "actix-web 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "dubp-block-doc 0.1.0",
  "dubp-blocks-tests-tools 0.1.0",
diff --git a/lib/modules-lib/bc-db-reader/src/blocks.rs b/lib/modules-lib/bc-db-reader/src/blocks.rs
index d23a149f941288fbbf4ac37b562c1a8a6bd851d4..2e2767225076f1f479d0f4f63097a1bd4f8fd0c2 100644
--- a/lib/modules-lib/bc-db-reader/src/blocks.rs
+++ b/lib/modules-lib/bc-db-reader/src/blocks.rs
@@ -185,6 +185,22 @@ pub fn get_blocks_in_local_blockchain<DB: DbReadable>(
     })
 }
 
+/// Get several blocks in local blockchain by their number
+pub fn get_blocks_in_local_blockchain_by_numbers<DB: DbReadable, R: DbReader>(
+    db: &DB,
+    r: &R,
+    numbers: Vec<BlockNumber>,
+) -> Result<Vec<DbBlock>, DbError> {
+    numbers
+        .into_iter()
+        .filter_map(|n| match get_db_block_in_local_blockchain(db, r, n) {
+            Ok(Some(db_block)) => Some(Ok(db_block)),
+            Ok(None) => None,
+            Err(e) => Some(Err(e)),
+        })
+        .collect::<Result<Vec<DbBlock>, DbError>>()
+}
+
 /// Get current frame of calculating members
 pub fn get_current_frame<DB: DbReadable>(
     current_block: &BlockDocument,
diff --git a/lib/modules-lib/bc-db-reader/src/trait.rs b/lib/modules-lib/bc-db-reader/src/trait.rs
index 928f39998175b3671f1a34bd29b73e1f040e7f5d..f01d5693c978e49cfaf7ff4f3bbbfb508404764a 100644
--- a/lib/modules-lib/bc-db-reader/src/trait.rs
+++ b/lib/modules-lib/bc-db-reader/src/trait.rs
@@ -17,7 +17,7 @@
 // ! Define read only trait
 
 use crate::blocks::DbBlock;
-use crate::{BcDbRo, DbReadable, Reader};
+use crate::{BcDbRo, Reader};
 use dubp_common_doc::{BlockNumber, Blockstamp};
 use durs_dbs_tools::DbError;
 
@@ -39,49 +39,6 @@ pub trait BcDbRoTrait {
     ) -> Result<Vec<DbBlock>, DbError>;
 }
 
-impl BcDbRoTrait for BcDbRo {
-    #[inline]
-    fn get_current_blockstamp(&self) -> Result<Option<Blockstamp>, DbError> {
-        self.read(|r| crate::current_meta_datas::get_current_blockstamp_(self, r))
-    }
-    fn get_current_block(&self) -> Result<Option<DbBlock>, DbError> {
-        self.read(|r| {
-            if let Some(current_blockstamp) =
-                crate::current_meta_datas::get_current_blockstamp_(self, r)?
-            {
-                crate::blocks::get_db_block_in_local_blockchain(self, r, current_blockstamp.id)
-            } else {
-                Ok(None)
-            }
-        })
-    }
-    #[inline]
-    fn get_db_block_in_local_blockchain(
-        &self,
-        block_number: BlockNumber,
-    ) -> Result<Option<DbBlock>, DbError> {
-        self.read(|r| crate::blocks::get_db_block_in_local_blockchain(self, r, block_number))
-    }
-    #[cfg(feature = "client-indexer")]
-    fn get_db_blocks_in_local_blockchain(
-        &self,
-        numbers: Vec<BlockNumber>,
-    ) -> Result<Vec<DbBlock>, DbError> {
-        self.read(|r| {
-            numbers
-                .into_iter()
-                .filter_map(
-                    |n| match crate::blocks::get_db_block_in_local_blockchain(self, r, n) {
-                        Ok(Some(db_block)) => Some(Ok(db_block)),
-                        Ok(None) => None,
-                        Err(e) => Some(Err(e)),
-                    },
-                )
-                .collect::<Result<Vec<DbBlock>, DbError>>()
-        })
-    }
-}
-
 pub struct BcDbRoWithReader<'r, 'db: 'r> {
     pub db: &'db BcDbRo,
     pub r: Reader<'r>,
@@ -92,18 +49,24 @@ impl<'r, 'db: 'r> BcDbRoTrait for BcDbRoWithReader<'r, 'db> {
         crate::current_meta_datas::get_current_blockstamp_(self.db, self.r)
     }
     fn get_current_block(&self) -> Result<Option<DbBlock>, DbError> {
-        unimplemented!()
+        if let Some(current_blockstamp) =
+            crate::current_meta_datas::get_current_blockstamp_(self.db, self.r)?
+        {
+            crate::blocks::get_db_block_in_local_blockchain(self.db, self.r, current_blockstamp.id)
+        } else {
+            Ok(None)
+        }
     }
     fn get_db_block_in_local_blockchain(
         &self,
-        _block_number: BlockNumber,
+        block_number: BlockNumber,
     ) -> Result<Option<DbBlock>, DbError> {
-        unimplemented!()
+        crate::blocks::get_db_block_in_local_blockchain(self.db, self.r, block_number)
     }
     fn get_db_blocks_in_local_blockchain(
         &self,
-        _numbers: Vec<BlockNumber>,
+        numbers: Vec<BlockNumber>,
     ) -> Result<Vec<DbBlock>, DbError> {
-        unimplemented!()
+        crate::blocks::get_blocks_in_local_blockchain_by_numbers(self.db, self.r, numbers)
     }
 }
diff --git a/lib/modules/gva/Cargo.toml b/lib/modules/gva/Cargo.toml
index f141f1f6b751ad5982892e0b09cd94b21a85f873..e4a63861f3c14e8265198514fdc6bbb020b703a6 100644
--- a/lib/modules/gva/Cargo.toml
+++ b/lib/modules/gva/Cargo.toml
@@ -11,9 +11,10 @@ path = "src/lib.rs"
 
 [dependencies]
 actix-web = "1.0.9"
+cfg-if = "0.1.10"
 dubp-block-doc = { path = "../../dubp/block-doc"} #, version = "0.1.0" }
 dup-crypto = { path = "../../crypto" }
-durs-bc-db-reader = { path = "../../modules-lib/bc-db-reader" }
+durs-bc-db-reader = { path = "../../modules-lib/bc-db-reader", features = ["client-indexer"] }
 durs-conf = { path = "../../core/conf" }
 durs-message =  { path = "../../core/message" }
 durs-module = { path = "../../core/module" }
@@ -34,6 +35,7 @@ serde_json = "1.0.41"
 structopt= "0.3.4"
 
 [dev-dependencies]
+durs-bc-db-reader = { path = "../../modules-lib/bc-db-reader", features = ["client-indexer", "mock"] }
 dubp-blocks-tests-tools = { path = "../../tests-tools/blocks-tests-tools" }
 dup-crypto-tests-tools = { path = "../../tests-tools/crypto-tests-tools" }
 mockall = "0.5.2"
diff --git a/lib/modules/gva/src/context.rs b/lib/modules/gva/src/context.rs
index 4604812af79eafd6220341ae6b517a322cc4cb14..306f68903773001610d1327f08d748ae235b93c1 100644
--- a/lib/modules/gva/src/context.rs
+++ b/lib/modules/gva/src/context.rs
@@ -13,39 +13,54 @@
 // 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(not(test))]
-use durs_bc_db_reader::BcDbRo;
-use durs_common_tools::fatal_error;
+//! Context for graphql resolvers
 
-#[cfg(test)]
-use crate::db::MockBcDbTrait;
+use crate::db::BcDbRo;
+use crate::schema::Schema;
 
-/// GVA context (access to database)
-static mut CONTEXT: Option<Context> = None;
-
-#[cfg(not(test))]
-pub type DB = BcDbRo;
-#[cfg(test)]
-pub(crate) type DB = MockBcDbTrait;
-
-pub struct Context {
-    db: DB,
+pub struct GlobalContext {
+    db: &'static BcDbRo,
+    pub(crate) schema: Schema,
     software_name: &'static str,
     software_version: &'static str,
 }
 
-impl juniper::Context for Context {}
-
-impl Context {
-    pub(crate) fn new(db: DB, software_name: &'static str, software_version: &'static str) -> Self {
-        Context {
+impl GlobalContext {
+    pub(crate) fn new(
+        db: &'static BcDbRo,
+        schema: Schema,
+        software_name: &'static str,
+        software_version: &'static str,
+    ) -> Self {
+        GlobalContext {
             db,
+            schema,
             software_name,
             software_version,
         }
     }
+}
+
+pub struct QueryContext {
+    db: &'static BcDbRo,
+    software_name: &'static str,
+    software_version: &'static str,
+}
+
+impl juniper::Context for QueryContext {}
+
+impl From<&GlobalContext> for QueryContext {
+    fn from(global_context: &GlobalContext) -> Self {
+        QueryContext {
+            db: global_context.db,
+            software_name: global_context.software_name,
+            software_version: global_context.software_version,
+        }
+    }
+}
 
-    pub(crate) fn get_db(&self) -> &DB {
+impl QueryContext {
+    pub(crate) fn get_db(&self) -> &BcDbRo {
         &self.db
     }
 
@@ -57,19 +72,3 @@ impl Context {
         &self.software_version
     }
 }
-
-pub(crate) fn init(db: DB, soft_name: &'static str, soft_version: &'static str) {
-    unsafe {
-        CONTEXT.replace(Context::new(db, soft_name, soft_version));
-    }
-}
-
-pub fn get_context() -> &'static Context {
-    unsafe {
-        if let Some(ref context) = CONTEXT {
-            context
-        } else {
-            fatal_error!("GVA: no context");
-        }
-    }
-}
diff --git a/lib/modules/gva/src/db.rs b/lib/modules/gva/src/db.rs
index efbc0f057fbc40e20fd9acd35d7ca90720998bd3..1b492c0d07c0f0b8561185f96c7938ad54a7409f 100644
--- a/lib/modules/gva/src/db.rs
+++ b/lib/modules/gva/src/db.rs
@@ -15,75 +15,7 @@
 
 //! Gva Module: database requests
 
-pub use durs_bc_db_reader::DbError;
-
-use dubp_common_doc::{BlockNumber, Blockstamp};
-use durs_bc_db_reader::blocks::DbBlock;
-use durs_bc_db_reader::{BcDbRo, DbReadable};
-
-#[cfg(test)]
-use mockall::predicate::*;
+#[cfg(not(test))]
+pub(crate) use durs_bc_db_reader::BcDbRo;
 #[cfg(test)]
-use mockall::*;
-
-#[cfg_attr(test, automock)]
-pub(crate) trait BcDbTrait {
-    fn get_current_blockstamp(&self) -> Result<Option<Blockstamp>, DbError>;
-    fn get_current_block(&self) -> Result<Option<DbBlock>, DbError>;
-    fn get_db_block_in_local_blockchain(
-        &self,
-        block_number: BlockNumber,
-    ) -> Result<Option<DbBlock>, DbError>;
-    fn get_db_blocks_in_local_blockchain(
-        &self,
-        numbers: Vec<BlockNumber>,
-    ) -> Result<Vec<DbBlock>, DbError>;
-}
-
-impl<'a> BcDbTrait for BcDbRo {
-    #[inline]
-    fn get_current_blockstamp(&self) -> Result<Option<Blockstamp>, DbError> {
-        self.read(|r| durs_bc_db_reader::current_meta_datas::get_current_blockstamp_(self, r))
-    }
-    fn get_current_block(&self) -> Result<Option<DbBlock>, DbError> {
-        self.read(|r| {
-            if let Some(current_blockstamp) =
-                durs_bc_db_reader::current_meta_datas::get_current_blockstamp_(self, r)?
-            {
-                durs_bc_db_reader::blocks::get_db_block_in_local_blockchain(
-                    self,
-                    r,
-                    current_blockstamp.id,
-                )
-            } else {
-                Ok(None)
-            }
-        })
-    }
-    #[inline]
-    fn get_db_block_in_local_blockchain(
-        &self,
-        block_number: BlockNumber,
-    ) -> Result<Option<DbBlock>, DbError> {
-        self.read(|r| {
-            durs_bc_db_reader::blocks::get_db_block_in_local_blockchain(self, r, block_number)
-        })
-    }
-    fn get_db_blocks_in_local_blockchain(
-        &self,
-        numbers: Vec<BlockNumber>,
-    ) -> Result<Vec<DbBlock>, DbError> {
-        self.read(|r| {
-            numbers
-                .into_iter()
-                .filter_map(|n| {
-                    match durs_bc_db_reader::blocks::get_db_block_in_local_blockchain(self, r, n) {
-                        Ok(Some(db_block)) => Some(Ok(db_block)),
-                        Ok(None) => None,
-                        Err(e) => Some(Err(e)),
-                    }
-                })
-                .collect::<Result<Vec<DbBlock>, DbError>>()
-        })
-    }
-}
+pub(crate) use durs_bc_db_reader::MockBcDbRoTrait as BcDbRo;
diff --git a/lib/modules/gva/src/graphql.rs b/lib/modules/gva/src/graphql.rs
index b2fa335a752a6746e1948b7dc78431a8aa223067..3a58527fe55e95a0ac90117bebd0386263bf2040 100644
--- a/lib/modules/gva/src/graphql.rs
+++ b/lib/modules/gva/src/graphql.rs
@@ -16,19 +16,19 @@
 
 //! Module that execute graphql queries
 
-use crate::schema::Schema;
+use crate::context::{GlobalContext, QueryContext};
 use actix_web::{web, Error, HttpResponse};
 use futures::future::Future;
 use juniper::http::GraphQLRequest;
 use std::sync::Arc;
 
 pub(crate) fn graphql(
-    schema: web::Data<Arc<Schema>>,
+    global_context: web::Data<Arc<GlobalContext>>,
     data: web::Json<GraphQLRequest>,
 ) -> impl Future<Item = HttpResponse, Error = Error> {
-    let context = crate::context::get_context();
+    let query_context = QueryContext::from(global_context.as_ref());
     web::block(move || {
-        let result = data.execute(&schema, context);
+        let result = data.execute(&global_context.schema, &query_context);
         serde_json::to_string(&result)
     })
     .map_err(Error::from)
diff --git a/lib/modules/gva/src/schema.rs b/lib/modules/gva/src/schema.rs
index a2a7c0cb107c310ccb02b70632e3a51e7a65d690..92152e3ba56f51ba7a14fd11670faf59942152a7 100644
--- a/lib/modules/gva/src/schema.rs
+++ b/lib/modules/gva/src/schema.rs
@@ -21,13 +21,15 @@ mod queries;
 
 use self::entities::block::Block;
 use self::entities::node::{Node, Summary};
-use crate::context::Context;
+use crate::context::QueryContext;
+#[cfg(not(test))]
+use durs_bc_db_reader::{BcDbRoWithReader, DbReadable};
 use juniper::Executor;
 use juniper::FieldResult;
 use juniper_from_schema::graphql_schema_from_file;
 
 // generate schema from schema file
-graphql_schema_from_file!("resources/schema.gql");
+graphql_schema_from_file!("resources/schema.gql", context_type: QueryContext);
 
 pub struct Query;
 
@@ -35,32 +37,46 @@ impl QueryFields for Query {
     #[inline]
     fn field_node(
         &self,
-        executor: &Executor<'_, Context>,
+        executor: &Executor<'_, QueryContext>,
         trail: &QueryTrail<'_, Node, Walked>,
     ) -> FieldResult<Node> {
-        queries::node::execute(executor, trail)
+        queries::node::execute(executor.context(), trail)
     }
     #[inline]
     fn field_current(
         &self,
-        executor: &Executor<'_, Context>,
+        executor: &Executor<'_, QueryContext>,
         trail: &QueryTrail<'_, Block, Walked>,
     ) -> FieldResult<Option<Block>> {
-        queries::current::execute(executor, trail)
+        let db = executor.context().get_db();
+        cfg_if::cfg_if! {
+            if #[cfg(not(test))] {
+                db.read(|r| queries::current::execute(&BcDbRoWithReader { db, r }, trail)).map_err(Into::into)
+            } else {
+                queries::current::execute(db, trail).map_err(Into::into)
+            }
+        }
     }
     #[inline]
     fn field_block(
         &self,
-        executor: &Executor<'_, Context>,
+        executor: &Executor<'_, QueryContext>,
         trail: &QueryTrail<'_, Block, Walked>,
         number: i32,
     ) -> FieldResult<Option<Block>> {
-        queries::block::execute(executor, trail, number)
+        let db = executor.context().get_db();
+        cfg_if::cfg_if! {
+            if #[cfg(not(test))] {
+                db.read(|r| queries::block::execute(&BcDbRoWithReader { db, r }, trail, number)).map_err(Into::into)
+            } else {
+                queries::block::execute(db, trail, number).map_err(Into::into)
+            }
+        }
     }
     #[inline]
     fn field_blocks(
         &self,
-        executor: &Executor<'_, Context>,
+        executor: &Executor<'_, QueryContext>,
         trail: &QueryTrail<'_, Block, Walked>,
         block_interval_opt: Option<BlockInterval>,
         paging_opt: Option<Paging>,
@@ -69,20 +85,37 @@ impl QueryFields for Query {
         if step <= 0 {
             step = 1;
         }
-        queries::blocks::execute(
-            executor,
-            trail,
-            paging_opt,
-            block_interval_opt,
-            step as usize,
-        )
+        let db = executor.context().get_db();
+        cfg_if::cfg_if! {
+            if #[cfg(not(test))] {
+                db.read(|r| {
+                    queries::blocks::execute(
+                        &BcDbRoWithReader { db, r },
+                        trail,
+                        paging_opt,
+                        block_interval_opt,
+                        step as usize,
+                    )
+                })
+                .map_err(Into::into)
+            } else {
+                queries::blocks::execute(
+                    db,
+                    trail,
+                    paging_opt,
+                    block_interval_opt,
+                    step as usize,
+                )
+                .map_err(Into::into)
+            }
+        }
     }
 }
 
 pub struct Mutation;
 
 impl MutationFields for Mutation {
-    fn field_noop(&self, _executor: &Executor<'_, Context>) -> FieldResult<&bool> {
+    fn field_noop(&self, _executor: &Executor<'_, QueryContext>) -> FieldResult<&bool> {
         Ok(&true)
     }
 }
diff --git a/lib/modules/gva/src/schema/entities/block.rs b/lib/modules/gva/src/schema/entities/block.rs
index 13aeb7a81d0c9353bc52ebe55b84a39f55796dbb..9053bcb7e4692d7f204e89c4985840ee7422f7f6 100644
--- a/lib/modules/gva/src/schema/entities/block.rs
+++ b/lib/modules/gva/src/schema/entities/block.rs
@@ -15,7 +15,7 @@
 
 // ! Module define graphql Block type
 
-use crate::context::Context;
+use crate::context::QueryContext;
 use chrono::NaiveDateTime;
 use dubp_block_doc::block::BlockDocumentTrait;
 use dubp_common_doc::traits::Document;
@@ -34,31 +34,34 @@ pub struct Block {
 }
 
 impl super::super::BlockFields for Block {
-    fn field_version(&self, _executor: &Executor<'_, Context>) -> FieldResult<&i32> {
+    fn field_version(&self, _executor: &Executor<'_, QueryContext>) -> FieldResult<&i32> {
         Ok(&self.version)
     }
 
-    fn field_currency(&self, _executor: &Executor<'_, Context>) -> FieldResult<&String> {
+    fn field_currency(&self, _executor: &Executor<'_, QueryContext>) -> FieldResult<&String> {
         Ok(&self.currency)
     }
 
-    fn field_issuer(&self, _executor: &Executor<'_, Context>) -> FieldResult<&String> {
+    fn field_issuer(&self, _executor: &Executor<'_, QueryContext>) -> FieldResult<&String> {
         Ok(&self.issuer)
     }
 
-    fn field_number(&self, _executor: &Executor<'_, Context>) -> FieldResult<&i32> {
+    fn field_number(&self, _executor: &Executor<'_, QueryContext>) -> FieldResult<&i32> {
         Ok(&self.number)
     }
 
-    fn field_hash(&self, _executor: &Executor<'_, Context>) -> FieldResult<&String> {
+    fn field_hash(&self, _executor: &Executor<'_, QueryContext>) -> FieldResult<&String> {
         Ok(&self.hash)
     }
 
-    fn field_common_time(&self, _executor: &Executor<'_, Context>) -> FieldResult<&NaiveDateTime> {
+    fn field_common_time(
+        &self,
+        _executor: &Executor<'_, QueryContext>,
+    ) -> FieldResult<&NaiveDateTime> {
         Ok(&self.common_time)
     }
 
-    fn field_pow_min(&self, _executor: &Executor<'_, Context>) -> FieldResult<&i32> {
+    fn field_pow_min(&self, _executor: &Executor<'_, QueryContext>) -> FieldResult<&i32> {
         Ok(&self.pow_min)
     }
 }
diff --git a/lib/modules/gva/src/schema/entities/node.rs b/lib/modules/gva/src/schema/entities/node.rs
index be7668bc595c7ce74ced7ac8e6b683ea6fb27a8f..06d786fa4b0a31dc83db3bc5b064469dd5ebef9b 100644
--- a/lib/modules/gva/src/schema/entities/node.rs
+++ b/lib/modules/gva/src/schema/entities/node.rs
@@ -15,7 +15,7 @@
 
 // ! Module define graphql Node type and subtypes
 
-use crate::context::Context;
+use crate::context::QueryContext;
 use juniper::Executor;
 use juniper_from_schema::{QueryTrail, Walked};
 
@@ -31,7 +31,7 @@ pub struct Node {
 impl super::super::NodeFields for Node {
     fn field_summary(
         &self,
-        _executor: &Executor<'_, Context>,
+        _executor: &Executor<'_, QueryContext>,
         _trail: &QueryTrail<'_, Summary, Walked>,
     ) -> &Summary {
         &self.summary
@@ -39,10 +39,10 @@ impl super::super::NodeFields for Node {
 }
 
 impl super::super::SummaryFields for Summary {
-    fn field_software(&self, _executor: &Executor<'_, Context>) -> String {
+    fn field_software(&self, _executor: &Executor<'_, QueryContext>) -> String {
         self.software.to_owned()
     }
-    fn field_version(&self, _executor: &Executor<'_, Context>) -> String {
+    fn field_version(&self, _executor: &Executor<'_, QueryContext>) -> String {
         self.version.to_owned()
     }
 }
diff --git a/lib/modules/gva/src/schema/inputs/block_interval.rs b/lib/modules/gva/src/schema/inputs/block_interval.rs
index 8b56aad86652711aa356249e04cd44237accc26c..15f75163ae95b5ea9bd98d26e4596b84bbc6f2c4 100644
--- a/lib/modules/gva/src/schema/inputs/block_interval.rs
+++ b/lib/modules/gva/src/schema/inputs/block_interval.rs
@@ -16,22 +16,21 @@
 // ! BlockInterval input methods
 
 use super::super::BlockInterval;
-use crate::db::BcDbTrait;
-use durs_bc_db_reader::DbError;
+use durs_bc_db_reader::{BcDbRoTrait, DbError};
 use std::ops::RangeInclusive;
 
 const DEFAULT_START: usize = 0;
 const END_WHEN_EMPTY_BLOCKCHAIN: usize = 0;
 
 impl BlockInterval {
-    fn get_default_end<DB: BcDbTrait>(db: &DB) -> Result<usize, DbError> {
+    fn get_default_end<DB: BcDbRoTrait>(db: &DB) -> Result<usize, DbError> {
         if let Some(current_blockstamp) = db.get_current_blockstamp()? {
             Ok(current_blockstamp.id.0 as usize)
         } else {
             Ok(END_WHEN_EMPTY_BLOCKCHAIN)
         }
     }
-    pub(crate) fn get_range<DB: BcDbTrait>(
+    pub(crate) fn get_range<DB: BcDbRoTrait>(
         db: &DB,
         block_interval_opt: Option<BlockInterval>,
     ) -> Result<RangeInclusive<usize>, DbError> {
@@ -68,12 +67,12 @@ impl BlockInterval {
 mod tests {
 
     use super::*;
-    use crate::db::MockBcDbTrait;
+    use crate::db::BcDbRo;
     use dubp_common_doc::{BlockHash, BlockNumber, Blockstamp};
 
     #[test]
     fn test_block_interval_get_range_with_short_bc() -> Result<(), DbError> {
-        let mut mock_db = MockBcDbTrait::new();
+        let mut mock_db = BcDbRo::new();
         mock_db
             .expect_get_current_blockstamp()
             .times(1)
@@ -92,7 +91,7 @@ mod tests {
 
     #[test]
     fn test_block_interval_get_range_with_long_bc() -> Result<(), DbError> {
-        let mut mock_db = MockBcDbTrait::new();
+        let mut mock_db = BcDbRo::new();
         mock_db
             .expect_get_current_blockstamp()
             .times(2)
diff --git a/lib/modules/gva/src/schema/queries.rs b/lib/modules/gva/src/schema/queries.rs
index 6a30b6653ae34f7f1d4fd398d3410b0ee490d66f..1cf29e5abe77dc05f26efa128b928951d173b422 100644
--- a/lib/modules/gva/src/schema/queries.rs
+++ b/lib/modules/gva/src/schema/queries.rs
@@ -20,19 +20,13 @@ pub mod blocks;
 pub mod current;
 pub mod node;
 
-use durs_bc_db_reader::DbError;
-
-pub(crate) fn db_err_to_juniper_err(e: DbError) -> juniper::FieldError {
-    juniper::FieldError::from(format!("Db error: {:?}", e))
-}
-
 #[cfg(test)]
 mod tests {
 
-    use crate::context;
-    use crate::db::MockBcDbTrait;
+    use crate::context::GlobalContext;
+    use crate::db::BcDbRo;
     use crate::graphql::graphql;
-    use crate::schema::{create_schema, Schema};
+    use crate::schema::create_schema;
     use actix_web::dev::Body;
     use actix_web::http;
     use actix_web::test;
@@ -42,19 +36,29 @@ mod tests {
     use std::str::FromStr;
     use std::sync::Arc;
 
-    pub(crate) fn setup(mock_db: MockBcDbTrait) -> web::Data<Arc<Schema>> {
-        context::init(mock_db, "soft_name", "soft_version");
+    pub(crate) fn setup(
+        mock_db: BcDbRo,
+        db_container: &'static mut Option<BcDbRo>,
+    ) -> web::Data<Arc<GlobalContext>> {
+        // Give a static lifetime to the DB
+        let db = durs_common_tools::fns::r#static::to_static_ref(mock_db, db_container);
 
-        web::Data::new(std::sync::Arc::new(create_schema()))
+        // Init global context
+        web::Data::new(std::sync::Arc::new(GlobalContext::new(
+            db,
+            create_schema(),
+            "soft_name",
+            "soft_version",
+        )))
     }
 
     pub(crate) fn test_gql_query(
-        schema: web::Data<Arc<Schema>>,
+        global_context: web::Data<Arc<GlobalContext>>,
         gql_query: &str,
         expected_response: serde_json::Value,
     ) {
         let resp = test::block_on(graphql(
-            schema,
+            global_context,
             web::Json(GraphQLRequest::new(gql_query.to_owned(), None, None)),
         ))
         .unwrap();
diff --git a/lib/modules/gva/src/schema/queries/block.rs b/lib/modules/gva/src/schema/queries/block.rs
index 24ce10189cba8576315b0ee398a6004d5b1301d6..acb725b1a76f11122be8b09f34ba4d6ca3e72a14 100644
--- a/lib/modules/gva/src/schema/queries/block.rs
+++ b/lib/modules/gva/src/schema/queries/block.rs
@@ -15,37 +15,29 @@
 
 // ! Module execute GraphQl schema block query
 
-use super::db_err_to_juniper_err;
-use crate::context::Context;
-use crate::db::BcDbTrait;
 use crate::schema::entities::block::Block;
 use dubp_common_doc::BlockNumber;
-use juniper::Executor;
-use juniper::FieldResult;
+use durs_bc_db_reader::{BcDbRoTrait, DbError};
 use juniper_from_schema::{QueryTrail, Walked};
 
-pub(crate) fn execute(
-    executor: &Executor<'_, Context>,
+pub(crate) fn execute<DB: BcDbRoTrait>(
+    db: &DB,
     _trail: &QueryTrail<'_, Block, Walked>,
     number: i32,
-) -> FieldResult<Option<Block>> {
+) -> Result<Option<Block>, DbError> {
     let block_number = if number >= 0 {
         BlockNumber(number as u32)
     } else {
-        return Err(juniper::FieldError::from("Block number must be positive."));
+        BlockNumber(0)
     };
 
-    executor
-        .context()
-        .get_db()
-        .get_db_block_in_local_blockchain(block_number)
-        .map_err(db_err_to_juniper_err)
+    db.get_db_block_in_local_blockchain(block_number)
         .map(|db_block_opt| db_block_opt.map(Into::into))
 }
 
 #[cfg(test)]
 mod tests {
-    use crate::db::MockBcDbTrait;
+    use crate::db::BcDbRo;
     use crate::schema::queries::tests;
     use dubp_block_doc::block::BlockDocument;
     use dubp_blocks_tests_tools::mocks::gen_empty_timed_block_v10;
@@ -56,9 +48,11 @@ mod tests {
     use mockall::predicate::eq;
     use serde_json::json;
 
+    static mut DB_BLOCK_1: Option<BcDbRo> = None;
+
     #[test]
     fn test_graphql_block() {
-        let mut mock_db = MockBcDbTrait::new();
+        let mut mock_db = BcDbRo::new();
         mock_db
             .expect_get_db_block_in_local_blockchain()
             .with(eq(BlockNumber(42)))
@@ -79,7 +73,7 @@ mod tests {
                 }))
             });
 
-        let schema = tests::setup(mock_db);
+        let schema = tests::setup(mock_db, unsafe { &mut DB_BLOCK_1 });
 
         tests::test_gql_query(
             schema.clone(),
diff --git a/lib/modules/gva/src/schema/queries/blocks.rs b/lib/modules/gva/src/schema/queries/blocks.rs
index 5119963682bcf01ab1b66ad17b680bed1fecd0cf..be85e7fc2c393eeaec84b31d7e84938a003931d7 100644
--- a/lib/modules/gva/src/schema/queries/blocks.rs
+++ b/lib/modules/gva/src/schema/queries/blocks.rs
@@ -15,31 +15,24 @@
 
 // ! Module execute GraphQl schema blocks query
 
-use super::db_err_to_juniper_err;
-use crate::context::Context;
-use crate::db::BcDbTrait;
 use crate::schema::entities::block::Block;
 use crate::schema::inputs::paging::FilledPaging;
 use crate::schema::BlockInterval;
 use crate::schema::Paging;
 use dubp_common_doc::BlockNumber;
 use durs_bc_db_reader::blocks::DbBlock;
-use juniper::Executor;
-use juniper::FieldResult;
+use durs_bc_db_reader::{BcDbRoTrait, DbError};
 use juniper_from_schema::{QueryTrail, Walked};
 
-pub(crate) fn execute(
-    executor: &Executor<'_, Context>,
+pub(crate) fn execute<DB: BcDbRoTrait>(
+    db: &DB,
     _trail: &QueryTrail<'_, Block, Walked>,
     paging_opt: Option<Paging>,
     block_interval_opt: Option<BlockInterval>,
     step: usize,
-) -> FieldResult<Vec<Block>> {
-    let db = executor.context().get_db();
-
+) -> Result<Vec<Block>, DbError> {
     // Get interval
-    let interval =
-        BlockInterval::get_range(db, block_interval_opt).map_err(db_err_to_juniper_err)?;
+    let interval = BlockInterval::get_range(db, block_interval_opt)?;
 
     // Get blocks numbers that respect filters
     let blocks_numbers: Vec<BlockNumber> =
@@ -61,16 +54,14 @@ pub(crate) fn execute(
         .collect();
 
     // Get blocks
-    let blocks: Vec<DbBlock> = db
-        .get_db_blocks_in_local_blockchain(blocks_numbers)
-        .map_err(db_err_to_juniper_err)?;
+    let blocks: Vec<DbBlock> = db.get_db_blocks_in_local_blockchain(blocks_numbers)?;
 
     Ok(blocks.into_iter().map(Into::into).collect())
 }
 
 #[cfg(test)]
 mod tests {
-    use crate::db::MockBcDbTrait;
+    use crate::db::BcDbRo;
     use crate::schema::queries::tests;
     use dubp_block_doc::block::v10::BlockDocumentV10;
     use dubp_block_doc::block::BlockDocument;
@@ -198,9 +189,11 @@ mod tests {
         })
     }
 
+    static mut DB_TEST_BLOCKS_FROM_2: Option<BcDbRo> = None;
+
     #[test]
     fn test_graphql_blocks_from_2() {
-        let mut mock_db = MockBcDbTrait::new();
+        let mut mock_db = BcDbRo::new();
 
         let block_2 = block_2();
         let block_3 = block_3();
@@ -232,7 +225,7 @@ mod tests {
                 ])
             });
 
-        let schema = tests::setup(mock_db);
+        let schema = tests::setup(mock_db, unsafe { &mut DB_TEST_BLOCKS_FROM_2 });
 
         tests::test_gql_query(
             schema,
@@ -249,9 +242,11 @@ mod tests {
         );
     }
 
+    static mut DB_TEST_BLOCKS_STEP_2: Option<BcDbRo> = None;
+
     #[test]
     fn test_graphql_blocks_with_step_2() {
-        let mut mock_db = MockBcDbTrait::new();
+        let mut mock_db = BcDbRo::new();
 
         let block_0 = block_0();
         let current_block = block_2();
@@ -278,7 +273,7 @@ mod tests {
                 ])
             });
 
-        let schema = tests::setup(mock_db);
+        let schema = tests::setup(mock_db, unsafe { &mut DB_TEST_BLOCKS_STEP_2 });
 
         tests::test_gql_query(
             schema,
@@ -306,9 +301,11 @@ mod tests {
         );
     }
 
+    static mut DB_TEST_BLOCKS: Option<BcDbRo> = None;
+
     #[test]
     fn test_graphql_blocks() {
-        let mut mock_db = MockBcDbTrait::new();
+        let mut mock_db = BcDbRo::new();
 
         let block_0 = block_0();
         let block_1 = block_1();
@@ -340,7 +337,7 @@ mod tests {
                 ])
             });
 
-        let schema = tests::setup(mock_db);
+        let schema = tests::setup(mock_db, unsafe { &mut DB_TEST_BLOCKS });
 
         tests::test_gql_query(
             schema,
diff --git a/lib/modules/gva/src/schema/queries/current.rs b/lib/modules/gva/src/schema/queries/current.rs
index 076e702b68367f838527e31ac2b8e6932bd68cf3..6d70554efc6a579683dfc98d978c474884e1b007 100644
--- a/lib/modules/gva/src/schema/queries/current.rs
+++ b/lib/modules/gva/src/schema/queries/current.rs
@@ -15,29 +15,21 @@
 
 // ! Module execute GraphQl schema current query
 
-use super::db_err_to_juniper_err;
-use crate::context::Context;
-use crate::db::BcDbTrait;
 use crate::schema::entities::block::Block;
-use juniper::Executor;
-use juniper::FieldResult;
+use durs_bc_db_reader::{BcDbRoTrait, DbError};
 use juniper_from_schema::{QueryTrail, Walked};
 
-pub(crate) fn execute(
-    executor: &Executor<'_, Context>,
+pub(crate) fn execute<DB: BcDbRoTrait>(
+    db: &DB,
     _trail: &QueryTrail<'_, Block, Walked>,
-) -> FieldResult<Option<Block>> {
-    executor
-        .context()
-        .get_db()
-        .get_current_block()
-        .map_err(db_err_to_juniper_err)
+) -> Result<Option<Block>, DbError> {
+    db.get_current_block()
         .map(|db_block_opt| db_block_opt.map(Into::into))
 }
 
 #[cfg(test)]
 mod tests {
-    use crate::db::MockBcDbTrait;
+    use crate::db::BcDbRo;
     use crate::schema::queries::tests;
     use dubp_block_doc::block::BlockDocument;
     use dubp_blocks_tests_tools::mocks::gen_empty_timed_block_v10;
@@ -47,9 +39,11 @@ mod tests {
     use durs_bc_db_reader::blocks::DbBlock;
     use serde_json::json;
 
+    static mut DB_TEST_CURRENT_1: Option<BcDbRo> = None;
+
     #[test]
     fn test_graphql_current() {
-        let mut mock_db = MockBcDbTrait::new();
+        let mut mock_db = BcDbRo::new();
         mock_db.expect_get_current_block().returning(|| {
             let mut current_block = gen_empty_timed_block_v10(
                 Blockstamp {
@@ -67,7 +61,7 @@ mod tests {
             }))
         });
 
-        let schema = tests::setup(mock_db);
+        let schema = tests::setup(mock_db, unsafe { &mut DB_TEST_CURRENT_1 });
 
         tests::test_gql_query(
             schema,
diff --git a/lib/modules/gva/src/schema/queries/node.rs b/lib/modules/gva/src/schema/queries/node.rs
index b9b797231c327df91b5e501e9dd1c4cb02f585ba..c57bd1d715b27d385c100cffc118c9ddcab74b52 100644
--- a/lib/modules/gva/src/schema/queries/node.rs
+++ b/lib/modules/gva/src/schema/queries/node.rs
@@ -15,33 +15,34 @@
 
 // ! Module execute GraphQl schema node query
 
-use crate::context::Context;
+use crate::context::QueryContext;
 use crate::schema::entities::node::{Node, Summary};
-use juniper::Executor;
 use juniper::FieldResult;
 use juniper_from_schema::{QueryTrail, Walked};
 
 pub(crate) fn execute(
-    executor: &Executor<'_, Context>,
+    context: &QueryContext,
     _trail: &QueryTrail<'_, Node, Walked>,
 ) -> FieldResult<Node> {
     Ok(Node {
         summary: Summary {
-            software: executor.context().get_software_name(),
-            version: executor.context().get_software_version(),
+            software: context.get_software_name(),
+            version: context.get_software_version(),
         },
     })
 }
 
 #[cfg(test)]
 mod tests {
-    use crate::db::MockBcDbTrait;
+    use crate::db::BcDbRo;
     use crate::schema::queries::tests;
     use serde_json::json;
 
+    static mut DB_TEST_NODE_SUMMARY: Option<BcDbRo> = None;
+
     #[test]
-    fn test_graphql_current() {
-        let schema = tests::setup(MockBcDbTrait::new());
+    fn test_graphql_node_summary() {
+        let schema = tests::setup(BcDbRo::new(), unsafe { &mut DB_TEST_NODE_SUMMARY });
 
         tests::test_gql_query(
             schema,
diff --git a/lib/modules/gva/src/webserver.rs b/lib/modules/gva/src/webserver.rs
index 20b949eef1188be8b462777f80f6c8d1bcea4375..da7ff2bf5e21b65a9c99fb06630c717ba1a54fca 100644
--- a/lib/modules/gva/src/webserver.rs
+++ b/lib/modules/gva/src/webserver.rs
@@ -14,7 +14,8 @@
 // along with this program.  If not, see <https://www.gnu.org/licenses/>.
 // web server implementaion based on actix-web
 
-use crate::context;
+use crate::context::GlobalContext;
+use crate::db::BcDbRo;
 use crate::graphql::graphql;
 use crate::schema::create_schema;
 use actix_web::{middleware, web, App, HttpResponse, HttpServer};
@@ -27,8 +28,8 @@ use durs_network_documents::url::Url;
 use juniper::http::graphiql::graphiql_source;
 use std::net::SocketAddr;
 
-#[cfg(test)]
-use crate::db::MockBcDbTrait;
+/// Database readonly handler (access to database)
+static mut DB_RO_HANDLER: Option<BcDbRo> = None;
 
 fn graphiql() -> HttpResponse {
     let html = graphiql_source("/graphql");
@@ -44,12 +45,10 @@ pub fn start_web_server(
 ) -> std::io::Result<()> {
     info!("GVA web server start...");
 
+    // Define listen addrs
     let addrs: Vec<SocketAddr> =
         Url::from_host_port_path(host, port, None).to_listenable_addr("http")?;
 
-    // Create Juniper schema
-    let schema = std::sync::Arc::new(create_schema());
-
     // Get DB
     #[cfg(not(test))]
     let db = {
@@ -61,15 +60,23 @@ pub fn start_web_server(
         }
     };
     #[cfg(test)]
-    let db = MockBcDbTrait::new();
+    let db = BcDbRo::new();
+
+    // Give a static lifetime to the DB
+    let db = durs_common_tools::fns::r#static::to_static_ref(db, unsafe { &mut DB_RO_HANDLER });
 
-    // Instanciate the context
-    context::init(db, soft_meta_datas.soft_name, soft_meta_datas.soft_version);
+    // Create global context
+    let global_context = std::sync::Arc::new(GlobalContext::new(
+        db,
+        create_schema(),
+        soft_meta_datas.soft_name,
+        soft_meta_datas.soft_version,
+    ));
 
     // Start http server
     HttpServer::new(move || {
         App::new()
-            .data(schema.clone())
+            .data(global_context.clone())
             .wrap(middleware::Logger::default())
             .service(web::resource("/graphql").route(web::post().to_async(graphql)))
             .service(web::resource("/graphiql").route(web::get().to(graphiql)))
diff --git a/lib/tools/common-tools/src/fns/mod.rs b/lib/tools/common-tools/src/fns/mod.rs
index 572bed996ff9f4978e54ba8dca38254e068e9130..989587004c15e31986e3837ac4a8580638e29377 100644
--- a/lib/tools/common-tools/src/fns/mod.rs
+++ b/lib/tools/common-tools/src/fns/mod.rs
@@ -18,5 +18,6 @@
 pub mod _u64;
 pub mod arrays;
 pub mod bin_file;
+pub mod r#static;
 pub mod str_escape;
 pub mod time;
diff --git a/lib/tools/common-tools/src/fns/static.rs b/lib/tools/common-tools/src/fns/static.rs
new file mode 100644
index 0000000000000000000000000000000000000000..f262dd152c7d5ea17ec92081076dd77441212708
--- /dev/null
+++ b/lib/tools/common-tools/src/fns/static.rs
@@ -0,0 +1,26 @@
+//  Copyright (C) 2019  É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/>.
+
+//! Common rust functions for static lifetime.
+
+/// Transforms any object into a static reference to that object
+pub fn to_static_ref<T>(value: T, container: &'static mut Option<T>) -> &'static T {
+    container.replace(value);
+    if let Some(ref value) = container {
+        value
+    } else {
+        unreachable!()
+    }
+}