diff --git a/blockchain/lib.rs b/blockchain/lib.rs
index 7e24de3f410a18f245f41d5d71b9e45649b9a61a..8710a5214a4064bf7d46218666a320b285cb2113 100644
--- a/blockchain/lib.rs
+++ b/blockchain/lib.rs
@@ -37,6 +37,7 @@ extern crate serde;
 extern crate serde_json;
 extern crate sqlite;
 
+mod stack_up_block;
 mod sync;
 
 use std::collections::HashMap;
@@ -47,6 +48,7 @@ use std::str;
 use std::sync::mpsc;
 use std::time::{Duration, SystemTime, UNIX_EPOCH};
 
+use self::stack_up_block::try_stack_up_completed_block;
 use duniter_crypto::keys::ed25519;
 use duniter_dal::block::{DALBlock, WotEvent};
 use duniter_dal::constants::MAX_FORKS;
@@ -54,9 +56,8 @@ use duniter_dal::dal_event::DALEvent;
 use duniter_dal::dal_requests::{DALReqBlockchain, DALRequest, DALResBlockchain, DALResponse};
 use duniter_dal::identity::DALIdentity;
 use duniter_dal::parsers::memberships::MembershipParseError;
-use duniter_dal::writers::certification::write_certification;
+use duniter_dal::writers::requests::DBWriteRequest;
 use duniter_dal::{DuniterDB, ForkState};
-use duniter_documents::blockchain::v10::documents::membership::MembershipType;
 use duniter_documents::blockchain::v10::documents::{BlockDocument, V10Document};
 use duniter_documents::blockchain::{BlockchainProtocol, Document, VerificationResult};
 use duniter_documents::{BlockHash, BlockId, Blockstamp};
@@ -446,25 +447,27 @@ impl BlockchainModule {
                 "stackable_block : block {} chainable !",
                 block_doc.blockstamp()
             );
-            let (success, wot_events) = match block {
+            let (success, db_requests, wot_events) = match block {
                 &Block::NetworkBlock(network_block) => self.try_stack_up_block(
                     &network_block,
                     wotb_index,
                     wot,
                     SyncVerificationLevel::Cautious(),
                 ),
-                &Block::LocalBlock(block_doc) => self.try_stack_up_completed_block(
-                    &block_doc,
-                    wotb_index,
-                    wot,
-                    SyncVerificationLevel::Cautious(),
-                ),
+                &Block::LocalBlock(block_doc) => {
+                    try_stack_up_completed_block(&block_doc, wotb_index, wot)
+                }
             };
             debug!(
                 "stackable_block_ : block {} chainable !",
                 block_doc.blockstamp()
             );
             if success {
+                // Apply db requests
+                db_requests
+                    .iter()
+                    .map(|req| req.apply(&block_doc.currency, &self.db))
+                    .collect::<()>();
                 info!("StackUpValidBlock({})", block_doc.number.0);
                 self.send_event(DALEvent::StackUpValidBlock(Box::new(block_doc.clone())));
                 return (true, Vec::with_capacity(0), wot_events);
@@ -491,11 +494,7 @@ impl BlockchainModule {
                 },
             ) {
                 Some(fork) => if forks.len() > fork {
-                    if fork > 0 {
-                        (fork, forks[fork])
-                    } else {
-                        panic!("fork must be positive !")
-                    }
+                    (fork, forks[fork])
                 } else {
                     panic!(format!("Error: fork n° {} is indicated as non-existent whereas it exists in database !", fork));
                 },
@@ -534,9 +533,6 @@ impl BlockchainModule {
                             &network_block_v10.uncompleted_block_doc,
                             fork,
                             isolate,
-                            &network_block_v10.joiners,
-                            &network_block_v10.actives,
-                            &network_block_v10.leavers,
                             &network_block_v10.revoked,
                             &network_block_v10.certifications,
                         )
@@ -563,265 +559,17 @@ impl BlockchainModule {
         wotb_index: &HashMap<ed25519::PublicKey, NodeId>,
         wot: &W,
         verif_level: SyncVerificationLevel,
-    ) -> (bool, Vec<WotEvent>) {
-        let block_doc =
-            match self.complete_network_block(network_block, wotb_index, verif_level.clone()) {
-                Ok(block_doc) => block_doc,
-                Err(_) => return (false, Vec::with_capacity(0)),
-            };
-        self.try_stack_up_completed_block::<W>(&block_doc, wotb_index, wot, verif_level)
-    }
-    fn complete_network_block(
-        &self,
-        network_block: &NetworkBlock,
-        wotb_index: &HashMap<ed25519::PublicKey, NodeId>,
-        verif_level: SyncVerificationLevel,
-    ) -> Result<BlockDocument, CompletedBlockError> {
-        let db = &self.db;
-        if let &NetworkBlock::V10(ref network_block_v10) = network_block {
-            let mut block_doc = network_block_v10.uncompleted_block_doc.clone();
-            // Indexing block_identities
-            let mut block_identities = HashMap::new();
-            block_doc
-                .identities
-                .iter()
-                .map(|idty| {
-                    if idty.issuers().is_empty() {
-                        panic!("idty without issuer !")
-                    }
-                    block_identities.insert(idty.issuers()[0], idty.clone());
-                })
-                .collect::<()>();
-            /*for idty in block_doc.clone().identities {
-                if idty.issuers().is_empty() {
-                    panic!("idty without issuer !")
-                }
-                block_identities.insert(idty.issuers()[0], idty);
-            }*/
-            for joiner in duniter_dal::parsers::memberships::parse_memberships_from_json_value(
-                &self.currency.to_string(),
-                MembershipType::In(),
-                &network_block_v10.joiners,
-            ) {
-                block_doc.joiners.push(joiner?);
-            }
-            for active in duniter_dal::parsers::memberships::parse_memberships_from_json_value(
-                &self.currency.to_string(),
-                MembershipType::In(),
-                &network_block_v10.actives,
-            ) {
-                block_doc.actives.push(active?);
-            }
-            for leaver in duniter_dal::parsers::memberships::parse_memberships_from_json_value(
-                &self.currency.to_string(),
-                MembershipType::Out(),
-                &network_block_v10.leavers,
-            ) {
-                block_doc.leavers.push(leaver?);
-            }
-            block_doc.certifications =
-                duniter_dal::parsers::certifications::parse_certifications_from_json_value(
-                    &self.currency.to_string(),
-                    db,
-                    &wotb_index,
-                    &block_identities,
-                    &network_block_v10.certifications,
-                );
-            block_doc.revoked = duniter_dal::parsers::revoked::parse_revocations_from_json_value(
-                &self.currency.to_string(),
-                db,
-                &wotb_index,
-                &block_identities,
-                &network_block_v10.revoked,
-            );
-            // In cautions mode, verify all signatures !
-            if verif_level == SyncVerificationLevel::Cautious() {
-                for idty in block_doc.clone().identities {
-                    if idty.verify_signatures() != VerificationResult::Valid() {
-                        error!(
-                            "Fail to sync block #{} : Idty with invalid singature !",
-                            block_doc.number
-                        );
-                        panic!("Idty with invalid singature !");
-                    }
-                }
-            }
-            let inner_hash = block_doc.inner_hash.expect("BlockchainModule : complete_network_block() : fatal error : block.inner_hash = None");
-            if block_doc.number.0 > 0 {
-                block_doc.compute_inner_hash();
-            }
-            let hash = block_doc.hash;
-            block_doc.compute_hash();
-            if block_doc.inner_hash.expect("BlockchainModule : complete_network_block() : fatal error : block.inner_hash = None") == inner_hash {
-                let nonce = block_doc.nonce;
-                block_doc.change_nonce(nonce);
-                if verif_level == SyncVerificationLevel::FastSync()
-                || block_doc.verify_signatures() == VerificationResult::Valid()
-                || block_doc.number.0 <= 1 {
-                    if block_doc.hash == hash {
-                        Ok(block_doc)
-                    } else {
-                        warn!("BlockchainModule : Refuse Bloc : invalid hash !");
-                        Err(CompletedBlockError::InvalidHash())
-                    }
-                } else {
-                    warn!("BlockchainModule : Refuse Bloc : invalid signature !");
-                    Err(CompletedBlockError::InvalidSig())
-                }
-            } else {
-                warn!("BlockchainModule : Refuse Bloc : invalid inner hash !");
-                Err(CompletedBlockError::InvalidInnerHash())
-            }
-        } else {
-            Err(CompletedBlockError::InvalidVersion())
-        }
-    }
-    fn try_stack_up_completed_block<W: WebOfTrust + Sync>(
-        &self,
-        block: &BlockDocument,
-        wotb_index: &HashMap<ed25519::PublicKey, NodeId>,
-        wot: &W,
-        _verif_level: SyncVerificationLevel,
-    ) -> (bool, Vec<WotEvent>) {
-        debug!(
-            "BlockchainModule : try stack up block {}",
-            block.blockstamp()
-        );
-        let db = &self.db;
-        let mut wot_events = Vec::new();
-        let mut wot_copy: W = wot.clone();
-        let mut wotb_index_copy: HashMap<ed25519::PublicKey, NodeId> = wotb_index.clone();
-        let current_blockstamp = block.blockstamp();
-        let mut identities = HashMap::with_capacity(block.identities.len());
-        for identity in block.identities.clone() {
-            identities.insert(identity.issuers()[0], identity);
-        }
-        for joiner in block.joiners.clone() {
-            let pubkey = joiner.clone().issuers()[0];
-            if let Some(compact_idty) = identities.get(&pubkey) {
-                // Newcomer
-                let wotb_id = NodeId(wot_copy.size());
-                wot_events.push(WotEvent::AddNode(pubkey, wotb_id));
-                wot_copy.add_node();
-                wotb_index_copy.insert(pubkey, wotb_id);
-                let idty = DALIdentity::create_identity(
-                    db,
-                    wotb_id,
-                    compact_idty,
-                    current_blockstamp.clone(),
-                );
-                duniter_dal::writers::identity::write(
-                    &idty,
-                    db,
-                    current_blockstamp.clone(),
-                    block.median_time,
-                );
-            } else {
-                // Renewer
-                let wotb_id = wotb_index_copy[&joiner.issuers()[0]];
-                wot_events.push(WotEvent::EnableNode(wotb_id));
-                wot_copy.set_enabled(wotb_id, true);
-                let mut idty =
-                    DALIdentity::get_identity(&self.currency.to_string(), db, &wotb_id).unwrap();
-                idty.renewal_identity(
-                    db,
-                    &wotb_index_copy,
-                    &block.blockstamp(),
-                    block.median_time,
-                    false,
-                );
-            }
-        }
-        for active in block.actives.clone() {
-            let wotb_id = wotb_index_copy[&active.issuers()[0]];
-            wot_events.push(WotEvent::EnableNode(wotb_id));
-            wot_copy.set_enabled(wotb_id, true);
-            let mut idty =
-                DALIdentity::get_identity(&self.currency.to_string(), db, &wotb_id).unwrap();
-            idty.renewal_identity(
-                db,
-                &wotb_index_copy,
-                &block.blockstamp(),
-                block.median_time,
-                false,
-            );
-        }
-        for exclusion in block.excluded.clone() {
-            let wotb_id = wotb_index_copy[&exclusion];
-            wot_events.push(WotEvent::DisableNode(wotb_id));
-            wot_copy.set_enabled(wotb_id, false);
-            DALIdentity::exclude_identity(db, wotb_id, block.blockstamp(), false);
-        }
-        for revocation in block.revoked.clone() {
-            let wotb_id = wotb_index_copy[&revocation.issuers()[0]];
-            wot_events.push(WotEvent::DisableNode(wotb_id));
-            wot_copy.set_enabled(wotb_id, false);
-            DALIdentity::revoke_identity(db, wotb_id, &block.blockstamp(), false);
-        }
-        for certification in block.certifications.clone() {
-            let wotb_node_from = wotb_index_copy[&certification.issuers()[0]];
-            let wotb_node_to = wotb_index_copy[&certification.target()];
-            wot_events.push(WotEvent::AddLink(wotb_node_from, wotb_node_to));
-            wot_copy.add_link(wotb_node_from, wotb_node_to);
-            write_certification(
-                &certification,
-                db,
-                current_blockstamp.clone(),
-                block.median_time,
-            );
-        }
-
-        /*// Calculate the state of the wot
-        if !wot_events.is_empty() && verif_level != SyncVerificationLevel::FastSync() {
-            // Calculate sentries_count
-            let sentries_count = wot_copy.get_sentries(3).len();
-            // Calculate average_density
-            let average_density = calculate_average_density::<W>(&wot_copy);
-            let sentry_requirement =
-                get_sentry_requirement(block.members_count, G1_PARAMS.step_max);
-            // Calculate distances and connectivities
-            let (average_distance, distances, average_connectivity, connectivities) =
-                compute_distances::<W>(
-                    &wot_copy,
-                    sentry_requirement,
-                    G1_PARAMS.step_max,
-                    G1_PARAMS.x_percent,
-                );
-            // Calculate centralities and average_centrality
-            let centralities =
-                calculate_distance_stress_centralities::<W>(&wot_copy, G1_PARAMS.step_max);
-            let average_centrality =
-                (centralities.iter().sum::<u64>() as f64 / centralities.len() as f64) as usize;
-            // Register the state of the wot
-            duniter_dal::register_wot_state(
-                db,
-                &WotState {
-                    block_number: block.number.0,
-                    block_hash: block.hash.unwrap().to_string(),
-                    sentries_count,
-                    average_density,
-                    average_distance,
-                    distances,
-                    average_connectivity,
-                    connectivities: connectivities
-                        .iter()
-                        .map(|c| {
-                            if *c > *G1_CONNECTIVITY_MAX {
-                                *G1_CONNECTIVITY_MAX
-                            } else {
-                                *c
-                            }
-                        })
-                        .collect(),
-                    average_centrality,
-                    centralities,
-                },
-            );
-        }*/
-        // Write block in bdd
-        duniter_dal::writers::block::write(db, block, 0, false);
-
-        (true, wot_events)
+    ) -> (bool, Vec<DBWriteRequest>, Vec<WotEvent>) {
+        let block_doc = match complete_network_block(
+            &self.currency.to_string(),
+            Some(&self.db),
+            network_block,
+            verif_level.clone(),
+        ) {
+            Ok(block_doc) => block_doc,
+            Err(_) => return (false, Vec::with_capacity(0), Vec::with_capacity(0)),
+        };
+        try_stack_up_completed_block::<W>(&block_doc, wotb_index, wot)
     }
     /// Start blockchain module.
     pub fn start_blockchain(&mut self, blockchain_receiver: mpsc::Receiver<DuniterMessage>) -> () {
@@ -926,7 +674,6 @@ impl BlockchainModule {
                                     if let Some(current_block) = DALBlock::get_block(
                                         &self.currency.to_string(),
                                         &self.db,
-                                        &wotb_index,
                                         &current_blockstamp,
                                     ) {
                                         debug!("BlockchainModule : send_req_response(CurrentBlock({}))", current_block.block.blockstamp());
@@ -1052,7 +799,6 @@ impl BlockchainModule {
                     let stackable_blocks = duniter_dal::block::DALBlock::get_stackables_blocks(
                         &self.currency.to_string(),
                         &self.db,
-                        &wotb_index,
                         &current_blockstamp,
                     );
                     if stackable_blocks.is_empty() {
@@ -1154,3 +900,107 @@ impl BlockchainModule {
         }
     }
 }
+
+/// Complete Network Block
+pub fn complete_network_block(
+    currency: &str,
+    db: Option<&DuniterDB>,
+    network_block: &NetworkBlock,
+    verif_level: SyncVerificationLevel,
+) -> Result<BlockDocument, CompletedBlockError> {
+    if let &NetworkBlock::V10(ref network_block_v10) = network_block {
+        let mut block_doc = network_block_v10.uncompleted_block_doc.clone();
+        trace!("complete_network_block #{}...", block_doc.number);
+        if verif_level == SyncVerificationLevel::Cautious() {
+            // Indexing block_identities
+            let mut block_identities = HashMap::new();
+            block_doc
+                .identities
+                .iter()
+                .map(|idty| {
+                    if idty.issuers().is_empty() {
+                        panic!("idty without issuer !")
+                    }
+                    block_identities.insert(idty.issuers()[0], idty.clone());
+                })
+                .collect::<()>();
+            block_doc.certifications =
+                    duniter_dal::parsers::certifications::parse_certifications_from_json_value(
+                        currency,
+                        db.expect("complete_network_block() : Cautious mode need access to blockchain database !"),
+                        &block_identities,
+                        &network_block_v10.certifications,
+                    );
+            trace!("Success to complete certs.");
+            block_doc.revoked = duniter_dal::parsers::revoked::parse_revocations_from_json_value(
+                currency,
+                db.expect(
+                    "complete_network_block() : Cautious mode need access to blockchain database !",
+                ),
+                &block_identities,
+                &network_block_v10.revoked,
+            );
+        } else {
+            block_doc.certifications =
+                duniter_dal::parsers::certifications::parse_certifications_into_compact(
+                    &network_block_v10.certifications,
+                );
+            trace!("Success to complete certs.");
+            block_doc.revoked = duniter_dal::parsers::revoked::parse_revocations_into_compact(
+                &network_block_v10.revoked,
+            );
+        }
+        trace!("Success to complete certs & revocations.");
+        // In cautions mode, verify all signatures !
+        if verif_level == SyncVerificationLevel::Cautious() {
+            for idty in block_doc.clone().identities {
+                if idty.verify_signatures() != VerificationResult::Valid() {
+                    error!(
+                        "Fail to sync block #{} : Idty with invalid singature !",
+                        block_doc.number
+                    );
+                    panic!("Idty with invalid singature !");
+                }
+            }
+        }
+        let inner_hash = block_doc.inner_hash.expect(
+            "BlockchainModule : complete_network_block() : fatal error : block.inner_hash = None",
+        );
+        if block_doc.number.0 > 0 {
+            block_doc.compute_inner_hash();
+        }
+        let hash = block_doc.hash;
+        block_doc.compute_hash();
+        if block_doc.inner_hash.expect(
+            "BlockchainModule : complete_network_block() : fatal error : block.inner_hash = None",
+        ) == inner_hash
+        {
+            let nonce = block_doc.nonce;
+            block_doc.change_nonce(nonce);
+            if verif_level == SyncVerificationLevel::FastSync()
+                || block_doc.verify_signatures() == VerificationResult::Valid()
+                || block_doc.number.0 <= 1
+            {
+                if block_doc.hash == hash {
+                    trace!("Succes to complete_network_block #{}", block_doc.number.0);
+                    Ok(block_doc)
+                } else {
+                    warn!("BlockchainModule : Refuse Bloc : invalid hash !");
+                    Err(CompletedBlockError::InvalidHash())
+                }
+            } else {
+                warn!("BlockchainModule : Refuse Bloc : invalid signature !");
+                Err(CompletedBlockError::InvalidSig())
+            }
+        } else {
+            warn!("BlockchainModule : Refuse Bloc : invalid inner hash !");
+            debug!(
+                "BlockInnerFormat={}",
+                block_doc.generate_compact_inner_text()
+            );
+            Err(CompletedBlockError::InvalidInnerHash())
+        }
+    } else {
+        Err(CompletedBlockError::InvalidVersion())
+    }
+}
diff --git a/blockchain/stack_up_block.rs b/blockchain/stack_up_block.rs
new file mode 100644
index 0000000000000000000000000000000000000000..bcc7b15d316dc45d6afde7600e9d00a4fa84d934
--- /dev/null
+++ b/blockchain/stack_up_block.rs
@@ -0,0 +1,178 @@
+//  Copyright (C) 2018  The Duniter Project Developers.
+//
+// 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/>.
+
+extern crate duniter_crypto;
+extern crate duniter_dal;
+extern crate duniter_documents;
+extern crate duniter_wotb;
+
+use duniter_crypto::keys::ed25519;
+use duniter_dal::block::{DALBlock, WotEvent};
+use duniter_dal::writers::requests::DBWriteRequest;
+use duniter_documents::blockchain::v10::documents::BlockDocument;
+use duniter_documents::blockchain::Document;
+use duniter_wotb::{NodeId, WebOfTrust};
+
+use std::collections::HashMap;
+
+pub fn try_stack_up_completed_block<W: WebOfTrust + Sync>(
+    block: &BlockDocument,
+    wotb_index: &HashMap<ed25519::PublicKey, NodeId>,
+    wot: &W,
+) -> (bool, Vec<DBWriteRequest>, Vec<WotEvent>) {
+    debug!(
+        "BlockchainModule : try stack up complete block {}",
+        block.blockstamp()
+    );
+    let mut db_requests = Vec::new();
+    let mut wot_events = Vec::new();
+    let mut wot_copy: W = wot.clone();
+    let mut wotb_index_copy: HashMap<ed25519::PublicKey, NodeId> = wotb_index.clone();
+    let current_blockstamp = block.blockstamp();
+    let mut identities = HashMap::with_capacity(block.identities.len());
+    for identity in block.identities.clone() {
+        identities.insert(identity.issuers()[0], identity);
+    }
+    for joiner in block.joiners.clone() {
+        let pubkey = joiner.clone().issuers()[0];
+        if let Some(idty_doc) = identities.get(&pubkey) {
+            // Newcomer
+            let wotb_id = NodeId(wot_copy.size());
+            wot_events.push(WotEvent::AddNode(pubkey, wotb_id));
+            wot_copy.add_node();
+            wotb_index_copy.insert(pubkey, wotb_id);
+            db_requests.push(DBWriteRequest::CreateIdentity(
+                wotb_id,
+                current_blockstamp.clone(),
+                block.median_time,
+                idty_doc.clone(),
+            ));
+        } else {
+            // Renewer
+            let wotb_id = wotb_index_copy[&joiner.issuers()[0]];
+            wot_events.push(WotEvent::EnableNode(wotb_id));
+            wot_copy.set_enabled(wotb_id, true);
+            db_requests.push(DBWriteRequest::RenewalIdentity(
+                joiner.issuers()[0],
+                block.blockstamp(),
+                block.median_time,
+            ));
+        }
+    }
+    for active in block.actives.clone() {
+        let pubkey = active.issuers()[0];
+        if !identities.contains_key(&pubkey) {
+            let wotb_id = wotb_index_copy[&pubkey];
+            wot_events.push(WotEvent::EnableNode(wotb_id));
+            wot_copy.set_enabled(wotb_id, true);
+            db_requests.push(DBWriteRequest::RenewalIdentity(
+                pubkey,
+                block.blockstamp(),
+                block.median_time,
+            ));
+        }
+    }
+    for exclusion in block.excluded.clone() {
+        let wotb_id = wotb_index_copy[&exclusion];
+        wot_events.push(WotEvent::DisableNode(wotb_id));
+        wot_copy.set_enabled(wotb_id, false);
+        db_requests.push(DBWriteRequest::ExcludeIdentity(
+            wotb_id,
+            block.blockstamp(),
+            block.median_time,
+        ));
+    }
+    for revocation in block.revoked.clone() {
+        let compact_revoc = revocation.to_compact_document();
+        let wotb_id = wotb_index_copy[&compact_revoc.issuer];
+        wot_events.push(WotEvent::DisableNode(wotb_id));
+        wot_copy.set_enabled(wotb_id, false);
+        db_requests.push(DBWriteRequest::RevokeIdentity(
+            wotb_id,
+            block.blockstamp(),
+            block.median_time,
+        ));
+    }
+    for certification in block.certifications.clone() {
+        trace!("try_stack_up_completed_block: apply cert...");
+        let compact_cert = certification.to_compact_document();
+        let wotb_node_from = wotb_index_copy[&compact_cert.issuer];
+        let wotb_node_to = wotb_index_copy[&compact_cert.target];
+        wot_events.push(WotEvent::AddLink(wotb_node_from, wotb_node_to));
+        wot_copy.add_link(wotb_node_from, wotb_node_to);
+        db_requests.push(DBWriteRequest::CreateCert(
+            block.blockstamp(),
+            block.median_time,
+            compact_cert,
+        ));
+        trace!("try_stack_up_completed_block: apply cert...success.");
+    }
+
+    /*// Calculate the state of the wot
+        if !wot_events.is_empty() && verif_level != SyncVerificationLevel::FastSync() {
+            // Calculate sentries_count
+            let sentries_count = wot_copy.get_sentries(3).len();
+            // Calculate average_density
+            let average_density = calculate_average_density::<W>(&wot_copy);
+            let sentry_requirement =
+                get_sentry_requirement(block.members_count, G1_PARAMS.step_max);
+            // Calculate distances and connectivities
+            let (average_distance, distances, average_connectivity, connectivities) =
+                compute_distances::<W>(
+                    &wot_copy,
+                    sentry_requirement,
+                    G1_PARAMS.step_max,
+                    G1_PARAMS.x_percent,
+                );
+            // Calculate centralities and average_centrality
+            let centralities =
+                calculate_distance_stress_centralities::<W>(&wot_copy, G1_PARAMS.step_max);
+            let average_centrality =
+                (centralities.iter().sum::<u64>() as f64 / centralities.len() as f64) as usize;
+            // Register the state of the wot
+            duniter_dal::register_wot_state(
+                db,
+                &WotState {
+                    block_number: block.number.0,
+                    block_hash: block.hash.unwrap().to_string(),
+                    sentries_count,
+                    average_density,
+                    average_distance,
+                    distances,
+                    average_connectivity,
+                    connectivities: connectivities
+                        .iter()
+                        .map(|c| {
+                            if *c > *G1_CONNECTIVITY_MAX {
+                                *G1_CONNECTIVITY_MAX
+                            } else {
+                                *c
+                            }
+                        })
+                        .collect(),
+                    average_centrality,
+                    centralities,
+                },
+            );
+        }*/
+    // Write block in bdd
+    db_requests.push(DBWriteRequest::WriteBlock(DALBlock {
+        block: block.clone(),
+        fork: 0,
+        isolate: false,
+    }));
+
+    (true, db_requests, wot_events)
+}
diff --git a/blockchain/sync.rs b/blockchain/sync.rs
index 4646b23ec79e64a9a1dee59b329d595d169dee55..3fc1000d64d2fbd60bafc8d5b36d3d13fc09b724 100644
--- a/blockchain/sync.rs
+++ b/blockchain/sync.rs
@@ -29,6 +29,8 @@ use self::pbr::ProgressBar;
 use duniter_crypto::keys::{ed25519, PublicKey, Signature};
 use duniter_dal::parsers::identities::parse_compact_identity;
 use duniter_dal::parsers::transactions::parse_transaction;
+//use duniter_dal::writers::requests::DBWriteRequest;
+use duniter_documents::blockchain::v10::documents::membership::MembershipType;
 use duniter_documents::blockchain::v10::documents::BlockDocument;
 use duniter_documents::{BlockHash, BlockId, Hash};
 use duniter_network::{NetworkBlock, NetworkBlockV10};
@@ -51,6 +53,7 @@ pub struct BlockHeader {
 enum ParserWorkMess {
     TargetBlockstamp(Blockstamp),
     NetworkBlock(NetworkBlock),
+    //DBWriteRequest(DBWriteRequest),
     End(),
 }
 
@@ -102,8 +105,8 @@ pub fn sync_ts(
         info!("Start cautious sync...");
         SyncVerificationLevel::Cautious()
     } else {
-        println!("Start cautious sync...");
-        info!("Start cautious sync...");
+        println!("Start fast sync...");
+        info!("Start fast sync...");
         SyncVerificationLevel::FastSync()
     };
 
@@ -244,8 +247,21 @@ pub fn sync_ts(
 
     // Apply blocks
     while let Ok(ParserWorkMess::NetworkBlock(network_block)) = recv_sync_thread.recv() {
+        // Complete block
+        let block_doc = match complete_network_block(
+            &blockchain_module.currency.to_string(),
+            None,
+            &network_block,
+            SyncVerificationLevel::FastSync(),
+        ) {
+            Ok(block_doc) => block_doc,
+            Err(_) => panic!("Receive wrong block, please reset data and resync !"),
+        };
         // Apply block
-        let (success, new_wot_events) = blockchain_module.try_stack_up_block::<RustyWebOfTrust>(
+        let (success, db_requests, new_wot_events) =
+            try_stack_up_completed_block::<RustyWebOfTrust>(&block_doc, &wotb_index, &wot);
+
+        blockchain_module.try_stack_up_block::<RustyWebOfTrust>(
             &network_block,
             &wotb_index,
             &wot,
@@ -253,6 +269,13 @@ pub fn sync_ts(
         );
         if success {
             current_blockstamp = network_block.blockstamp();
+            debug!("Apply db requests...");
+            // Apply db requests
+            db_requests
+                .iter()
+                .map(|req| req.apply(&conf.currency().to_string(), &blockchain_module.db))
+                .collect::<()>();
+            debug!("Finish to apply db requests.");
             // Apply WotEvents
             if !new_wot_events.is_empty() {
                 for wot_event in new_wot_events {
@@ -430,9 +453,21 @@ pub fn parse_ts_block(row: &[sqlite::Value]) -> NetworkBlock {
         ),
         dividend: dividend,
         identities,
-        joiners: Vec::new(),
-        actives: Vec::new(),
-        leavers: Vec::new(),
+        joiners: duniter_dal::parsers::memberships::parse_memberships(
+            currency,
+            MembershipType::In(),
+            row[21].as_string().expect("Fail to parse joiners"),
+        ).expect("Fail to parse joiners (2)"),
+        actives: duniter_dal::parsers::memberships::parse_memberships(
+            currency,
+            MembershipType::In(),
+            row[22].as_string().expect("Fail to parse actives"),
+        ).expect("Fail to parse actives (2)"),
+        leavers: duniter_dal::parsers::memberships::parse_memberships(
+            currency,
+            MembershipType::In(),
+            row[23].as_string().expect("Fail to parse leavers"),
+        ).expect("Fail to parse leavers (2)"),
         revoked: Vec::new(),
         excluded: excluded
             .as_array()
@@ -448,15 +483,6 @@ pub fn parse_ts_block(row: &[sqlite::Value]) -> NetworkBlock {
         transactions,
         inner_hash_and_nonce_str: String::new(),
     };
-    let joiners: serde_json::Value = serde_json::from_str(
-        row[21].as_string().expect("Fail to parse joiners"),
-    ).expect("Fail to parse joiners (2)");
-    let actives: serde_json::Value = serde_json::from_str(
-        row[22].as_string().expect("Fail to parse actives"),
-    ).expect("Fail to parse actives (2)");
-    let leavers: serde_json::Value = serde_json::from_str(
-        row[23].as_string().expect("Fail to parse leavers"),
-    ).expect("Fail to parse leavers (2)");
     let revoked: serde_json::Value = serde_json::from_str(
         row[24].as_string().expect("Fail to parse revoked"),
     ).expect("Fail to parse revoked (2)");
@@ -466,18 +492,6 @@ pub fn parse_ts_block(row: &[sqlite::Value]) -> NetworkBlock {
     // return NetworkBlock
     NetworkBlock::V10(Box::new(NetworkBlockV10 {
         uncompleted_block_doc,
-        joiners: joiners
-            .as_array()
-            .expect("Fail to parse joiners (3)")
-            .to_vec(),
-        actives: actives
-            .as_array()
-            .expect("Fail to parse actives (3)")
-            .to_vec(),
-        leavers: leavers
-            .as_array()
-            .expect("Fail to parse leavers (3)")
-            .to_vec(),
         revoked: revoked
             .as_array()
             .expect("Fail to parse revoked (3)")
diff --git a/dal/block.rs b/dal/block.rs
index 92d5cefda333ccb34e1662288f3c3530ef86a741..ae29b95d44f867a822ff2dd6adb294a181fbe656 100644
--- a/dal/block.rs
+++ b/dal/block.rs
@@ -79,8 +79,6 @@ pub struct DALBlock {
     pub fork: usize,
     pub isolate: bool,
     pub block: BlockDocument,
-    pub median_frame: usize,
-    pub second_tiercile_frame: usize,
 }
 
 impl DALBlock {
@@ -195,7 +193,6 @@ impl DALBlock {
     pub fn get_stackables_blocks(
         currency: &str,
         db: &DuniterDB,
-        wotb_index: &HashMap<ed25519::PublicKey, NodeId>,
         current_blockstamp: &Blockstamp,
     ) -> Vec<DALBlock> {
         debug!("get_stackables_blocks() after {}", current_blockstamp);
@@ -204,12 +201,9 @@ impl DALBlock {
         let (hashs, previous_hashs) = DALBlock::get_blocks_hashs_all_forks(db, &block_id);
         for (hash, previous_hash) in hashs.into_iter().zip(previous_hashs) {
             if previous_hash == current_blockstamp.hash.0 {
-                if let Some(dal_block) = DALBlock::get_block(
-                    currency,
-                    db,
-                    wotb_index,
-                    &Blockstamp { id: block_id, hash },
-                ) {
+                if let Some(dal_block) =
+                    DALBlock::get_block(currency, db, &Blockstamp { id: block_id, hash })
+                {
                     stackables_blocks.push(dal_block);
                 } else {
                     panic!(format!(
@@ -237,12 +231,7 @@ impl DALBlock {
         }
         stackables_forks
     }
-    pub fn get_block(
-        currency: &str,
-        db: &DuniterDB,
-        wotb_index: &HashMap<ed25519::PublicKey, NodeId>,
-        blockstamp: &Blockstamp,
-    ) -> Option<DALBlock> {
+    pub fn get_block(currency: &str, db: &DuniterDB, blockstamp: &Blockstamp) -> Option<DALBlock> {
         let mut cursor = db
             .0
             .prepare(
@@ -410,7 +399,6 @@ impl DALBlock {
                     revoked: parse_revocations(
                         currency,
                         db,
-                        wotb_index,
                         &hashmap_identities,
                         row[25]
                             .as_string()
@@ -424,7 +412,6 @@ impl DALBlock {
                     certifications: parse_certifications(
                         currency,
                         db,
-                        wotb_index,
                         &hashmap_identities,
                         row[27]
                             .as_string()
@@ -444,8 +431,8 @@ impl DALBlock {
                         nonce
                     ),
                 },
-                median_frame: row[13].as_integer().unwrap_or(0) as usize,
-                second_tiercile_frame: row[14].as_integer().unwrap_or(0) as usize,
+                //median_frame: row[13].as_integer().unwrap_or(0) as usize,
+                //second_tiercile_frame: row[14].as_integer().unwrap_or(0) as usize,
             })
         } else {
             None
@@ -499,7 +486,7 @@ impl DALBlock {
             let mut current_frame_vec: Vec<_> = current_frame.values().cloned().collect();
             current_frame_vec.sort_unstable();
 
-            // Calculate median
+            /*// Calculate median
             let mut median_index = match self.block.issuers_count % 2 {
                 1 => (self.block.issuers_count / 2) + 1,
                 _ => self.block.issuers_count / 2,
@@ -517,7 +504,7 @@ impl DALBlock {
             if second_tiercile_index >= self.block.issuers_count {
                 second_tiercile_index = self.block.issuers_count - 1;
             }
-            self.second_tiercile_frame = current_frame_vec[second_tiercile_index];
+            self.second_tiercile_frame = current_frame_vec[second_tiercile_index];*/
         }
     }
 }
diff --git a/dal/identity.rs b/dal/identity.rs
index b65dc0306157f0b8e9f1f715ac9bc387d51932cb..2486c628b3e9ff9ceeeb17fb42b06b52c6fbae7b 100644
--- a/dal/identity.rs
+++ b/dal/identity.rs
@@ -12,7 +12,6 @@ use std::collections::HashMap;
 
 #[derive(Debug, Clone)]
 pub struct DALIdentity {
-    pub wotb_id: NodeId,
     pub hash: String,
     pub state: isize,
     pub joined_on: Blockstamp,
@@ -78,7 +77,6 @@ impl DALIdentity {
 
     pub fn create_identity(
         db: &DuniterDB,
-        wotb_id: NodeId,
         idty_doc: &IdentityDocument,
         current_blockstamp: Blockstamp,
     ) -> DALIdentity {
@@ -87,7 +85,6 @@ impl DALIdentity {
             .expect("convert blockstamp to timestamp failure !");
 
         DALIdentity {
-            wotb_id,
             hash: "0".to_string(),
             state: 0,
             joined_on: current_blockstamp,
@@ -131,7 +128,7 @@ impl DALIdentity {
     pub fn renewal_identity(
         &mut self,
         db: &DuniterDB,
-        wotb_index: &HashMap<ed25519::PublicKey, NodeId>,
+        pubkey: &ed25519::PublicKey,
         renewal_blockstamp: &Blockstamp,
         renawal_timestamp: u64,
         revert: bool,
@@ -142,9 +139,8 @@ impl DALIdentity {
                 DALBlock::get_block(
                     self.idty_doc.currency(),
                     db,
-                    wotb_index,
                     &self.penultimate_renewed_on.clone(),
-                ).unwrap(),
+                ).expect("renewal_identity: Fail to get penultimate_renewed_block"),
             );
             penultimate_renewed_block.clone().unwrap().block.median_time
                 + super::constants::G1_PARAMS.ms_validity < renawal_timestamp
@@ -160,7 +156,7 @@ impl DALIdentity {
         };
         let mut cursor = db.0
             .prepare(
-                "UPDATE identities SET state=?, last_renewed_on=?, expires_on=?, revokes_on=?  WHERE wotb_id=?;",
+                "UPDATE identities SET state=?, last_renewed_on=?, expires_on=?, revokes_on=?  WHERE pubkey=?;",
             )
             .expect("Fail to renewal idty !")
             .cursor();
@@ -173,7 +169,7 @@ impl DALIdentity {
                 sqlite::Value::Integer(
                     (renawal_timestamp + (super::constants::G1_PARAMS.ms_validity * 2)) as i64,
                 ),
-                sqlite::Value::Integer(self.wotb_id.0 as i64),
+                sqlite::Value::String(pubkey.to_string()),
             ])
             .expect("Fail to renewal idty !");
     }
@@ -187,62 +183,92 @@ impl DALIdentity {
             .unwrap();
     }
 
-    pub fn get_identity(currency: &str, db: &DuniterDB, wotb_id: &NodeId) -> Option<DALIdentity> {
+    pub fn get_identity(
+        currency: &str,
+        db: &DuniterDB,
+        pubkey: &ed25519::PublicKey,
+    ) -> Option<DALIdentity> {
         let mut cursor = db
             .0
             .prepare(
-                "SELECT uid, pubkey, hash, sig,
+                "SELECT uid, hash, sig,
                 state, created_on, joined_on, penultimate_renewed_on, last_renewed_on,
-                expires_on, revokes_on, expired_on, revoked_on FROM identities WHERE wotb_id=?;",
+                expires_on, revokes_on, expired_on, revoked_on FROM identities WHERE pubkey=?;",
             )
             .expect("Fail to get idty !")
             .cursor();
 
         cursor
-            .bind(&[sqlite::Value::Integer(wotb_id.0 as i64)])
+            .bind(&[sqlite::Value::String(pubkey.to_string())])
             .expect("Fail to get idty !");
 
-        if let Some(row) = cursor.next().unwrap() {
+        if let Some(row) = cursor.next().expect("get_identity: cursor error") {
             let idty_doc_builder = IdentityDocumentBuilder {
                 currency,
-                username: row[0].as_string().unwrap(),
+                username: row[0]
+                    .as_string()
+                    .expect("get_identity: fail to parse username"),
                 blockstamp: &Blockstamp::from_string(
-                    row[5]
+                    row[4]
                         .as_string()
                         .expect("DB Error : idty created_on invalid !"),
                 ).expect("DB Error : idty created_on invalid (2) !"),
-                issuer: &PublicKey::from_base58(row[1].as_string().unwrap()).unwrap(),
+                issuer: &pubkey,
             };
-            let idty_sig = Signature::from_base64(row[3].as_string().unwrap()).unwrap();
+            let idty_sig = Signature::from_base64(
+                row[2].as_string().expect("get_identity: fail to parse sig"),
+            ).expect("get_identity: fail to parse sig (2)");
             let idty_doc = idty_doc_builder.build_with_signature(vec![idty_sig]);
 
-            let expired_on = match Blockstamp::from_string(row[11].as_string().unwrap()) {
+            let expired_on = match Blockstamp::from_string(
+                row[10]
+                    .as_string()
+                    .expect("get_identity: fail to parse expire on"),
+            ) {
                 Ok(blockstamp) => Some(blockstamp),
                 Err(_) => None,
             };
-            let revoked_on = match Blockstamp::from_string(row[12].as_string().unwrap()) {
+            let revoked_on = match Blockstamp::from_string(
+                row[11]
+                    .as_string()
+                    .expect("get_identity: fail to parse revoked on"),
+            ) {
                 Ok(blockstamp) => Some(blockstamp),
                 Err(_) => None,
             };
             Some(DALIdentity {
-                wotb_id: wotb_id.clone(),
-                hash: row[2].as_string().unwrap().to_string(),
-                state: row[4].as_integer().unwrap() as isize,
+                hash: row[2]
+                    .as_string()
+                    .expect("get_identity: fail to parse hash")
+                    .to_string(),
+                state: row[3]
+                    .as_integer()
+                    .expect("get_identity: fail to parse state") as isize,
                 joined_on: Blockstamp::from_string(
-                    row[6]
+                    row[5]
                         .as_string()
                         .expect("DB Error : idty joined_on invalid !"),
                 ).expect("DB Error : idty joined_on invalid !"),
                 penultimate_renewed_on: Blockstamp::from_string(
-                    row[7]
+                    row[6]
                         .as_string()
                         .expect("DB Error : idty penultimate_renewed_on invalid !"),
                 ).expect(
                     "DB Error : idty penultimate_renewed_on invalid (2) !",
                 ),
-                last_renewed_on: Blockstamp::from_string(row[8].as_string().unwrap()).unwrap(),
-                expires_on: row[9].as_integer().unwrap() as u64,
-                revokes_on: row[10].as_integer().unwrap() as u64,
+                last_renewed_on: Blockstamp::from_string(
+                    row[7]
+                        .as_string()
+                        .expect("get_identity: fail to parse last_renewed_on"),
+                ).expect("get_identity: fail to parse last_renewed_on (2)"),
+                expires_on: row[8]
+                    .as_integer()
+                    .expect("get_identity: fail to parse expires_on")
+                    as u64,
+                revokes_on: row[9]
+                    .as_integer()
+                    .expect("get_identity: fail to parse revokes_on")
+                    as u64,
                 expired_on,
                 revoked_on,
                 idty_doc,
diff --git a/dal/lib.rs b/dal/lib.rs
index 7b6eb80e0d144737018cc3fd8ba683aa828fed35..7c1541dcc352dbe86ff8262f27ae691df90a9b81 100644
--- a/dal/lib.rs
+++ b/dal/lib.rs
@@ -44,11 +44,10 @@ pub mod parsers;
 pub mod tools;
 pub mod writers;
 
-use duniter_crypto::keys::{ed25519, PublicKey, Signature};
+use duniter_crypto::keys::{PublicKey, Signature};
 use duniter_documents::blockchain::v10::documents::BlockDocument;
 use duniter_documents::{BlockHash, BlockId, Blockstamp, Hash};
 use duniter_wotb::NodeId;
-use std::collections::HashMap;
 use std::fmt::Debug;
 use std::marker;
 use std::path::PathBuf;
@@ -144,7 +143,7 @@ pub fn close_db(db: &DuniterDB) {
 pub fn get_uid(db: &DuniterDB, wotb_id: NodeId) -> Option<String> {
     let mut cursor: sqlite::Cursor = db
         .0
-        .prepare("SELECT uid FROM identities WHERE wotb_id=? LIMIT 1;")
+        .prepare("SELECT uid FROM identities WHERE wotb_id=? AND state=0 LIMIT 1;")
         .expect("Request SQL get_current_block is wrong !")
         .cursor();
     cursor
@@ -217,11 +216,7 @@ pub fn new_get_current_block(db: &DuniterDB) -> Option<BlockDocument> {
     None
 }
 
-pub fn get_current_block(
-    currency: &str,
-    db: &DuniterDB,
-    wotb_index: &HashMap<ed25519::PublicKey, NodeId>,
-) -> Option<DALBlock> {
+pub fn get_current_block(currency: &str, db: &DuniterDB) -> Option<DALBlock> {
     let mut cursor: sqlite::Cursor = db
         .0
         .prepare("SELECT number, hash FROM blocks WHERE fork=0 ORDER BY median_time DESC LIMIT ?;")
@@ -235,7 +230,7 @@ pub fn get_current_block(
             id: BlockId(row[0].as_integer().unwrap() as u32),
             hash: BlockHash(Hash::from_hex(row[1].as_string().unwrap()).unwrap()),
         };
-        DALBlock::get_block(currency, db, wotb_index, &blockstamp)
+        DALBlock::get_block(currency, db, &blockstamp)
     } else {
         None
     }
diff --git a/dal/parsers/blocks.rs b/dal/parsers/blocks.rs
index e78ce51adb90701374d846cd4b3812839d117e45..780ff728f3cc4057a26ff2123f7f3f85eef6ff0b 100644
--- a/dal/parsers/blocks.rs
+++ b/dal/parsers/blocks.rs
@@ -8,6 +8,7 @@ use super::excluded::parse_exclusions_from_json_value;
 use super::identities::parse_compact_identity;
 use super::transactions::parse_transaction;
 use duniter_crypto::keys::{PublicKey, Signature};
+use duniter_documents::blockchain::v10::documents::membership::MembershipType;
 use duniter_documents::blockchain::v10::documents::BlockDocument;
 use duniter_documents::{BlockHash, BlockId, Hash};
 
@@ -60,6 +61,42 @@ pub fn parse_json_block(source: &serde_json::Value) -> Option<NetworkBlock> {
     for raw_idty in source.get("identities")?.as_array()? {
         identities.push(parse_compact_identity(&currency, &raw_idty)?);
     }
+    let mut joiners = Vec::new();
+    for joiner in super::memberships::parse_memberships_from_json_value(
+        &currency,
+        MembershipType::In(),
+        &source.get("joiners")?.as_array()?,
+    ) {
+        if let Ok(joiner) = joiner {
+            joiners.push(joiner);
+        } else {
+            return None;
+        }
+    }
+    let mut actives = Vec::new();
+    for active in super::memberships::parse_memberships_from_json_value(
+        &currency,
+        MembershipType::In(),
+        &source.get("actives")?.as_array()?,
+    ) {
+        if let Ok(active) = active {
+            actives.push(active);
+        } else {
+            return None;
+        }
+    }
+    let mut leavers = Vec::new();
+    for leaver in super::memberships::parse_memberships_from_json_value(
+        &currency,
+        MembershipType::Out(),
+        &source.get("leavers")?.as_array()?,
+    ) {
+        if let Ok(leaver) = leaver {
+            leavers.push(leaver);
+        } else {
+            return None;
+        }
+    }
     let mut transactions = Vec::new();
     for json_tx in source.get("transactions")?.as_array()? {
         transactions.push(parse_transaction("g1", &json_tx)?);
@@ -86,9 +123,9 @@ pub fn parse_json_block(source: &serde_json::Value) -> Option<NetworkBlock> {
         inner_hash,
         dividend,
         identities,
-        joiners: Vec::with_capacity(0),
-        actives: Vec::with_capacity(0),
-        leavers: Vec::with_capacity(0),
+        joiners,
+        actives,
+        leavers,
         revoked: Vec::with_capacity(0),
         excluded: parse_exclusions_from_json_value(&source.get("excluded")?.as_array()?),
         certifications: Vec::with_capacity(0),
@@ -101,9 +138,6 @@ pub fn parse_json_block(source: &serde_json::Value) -> Option<NetworkBlock> {
     };
     Some(NetworkBlock::V10(Box::new(NetworkBlockV10 {
         uncompleted_block_doc: block_doc,
-        joiners: source.get("joiners")?.as_array()?.clone(),
-        actives: source.get("actives")?.as_array()?.clone(),
-        leavers: source.get("leavers")?.as_array()?.clone(),
         revoked: source.get("revoked")?.as_array()?.clone(),
         certifications: source.get("certifications")?.as_array()?.clone(),
     })))
diff --git a/dal/parsers/certifications.rs b/dal/parsers/certifications.rs
index ee395afd0df1ee54bc60ac4d8ee2ddb8eea020ab..a62b0a4ad73c69b00f27bff8ee42d97574b61048 100644
--- a/dal/parsers/certifications.rs
+++ b/dal/parsers/certifications.rs
@@ -6,34 +6,65 @@ use super::super::block::DALBlock;
 use super::super::identity::DALIdentity;
 use super::super::DuniterDB;
 use duniter_crypto::keys::{ed25519, PublicKey, Signature};
-use duniter_documents::blockchain::v10::documents::certification::CertificationDocumentBuilder;
-use duniter_documents::blockchain::v10::documents::{CertificationDocument, IdentityDocument};
+use duniter_documents::blockchain::v10::documents::certification::{
+    CertificationDocumentBuilder, CompactCertificationDocument,
+};
+use duniter_documents::blockchain::v10::documents::{
+    CertificationDocument, IdentityDocument, TextDocumentFormat,
+};
 use duniter_documents::blockchain::{Document, DocumentBuilder};
 use duniter_documents::{BlockHash, BlockId, Blockstamp, Hash};
-use duniter_wotb::NodeId;
 use std::collections::HashMap;
 
+pub fn parse_certifications_into_compact(
+    json_certs: &Vec<serde_json::Value>,
+) -> Vec<TextDocumentFormat<CertificationDocument>> {
+    let mut certifications: Vec<TextDocumentFormat<CertificationDocument>> = Vec::new();
+    for certification in json_certs.iter() {
+        let certifications_datas: Vec<&str> = certification
+            .as_str()
+            .expect("Receive block in wrong format : fail to split cert !")
+            .split(':')
+            .collect();
+        if certifications_datas.len() == 4 {
+            certifications.push(TextDocumentFormat::Compact(CompactCertificationDocument {
+                issuer: PublicKey::from_base58(certifications_datas[0])
+                    .expect("Receive block in wrong format : fail to parse issuer !"),
+                target: PublicKey::from_base58(certifications_datas[1])
+                    .expect("Receive block in wrong format : fail to parse target !"),
+                block_number: BlockId(
+                    certifications_datas[2]
+                        .parse()
+                        .expect("Receive block in wrong format : fail to parse block number !"),
+                ),
+                signature: Signature::from_base64(certifications_datas[3])
+                    .expect("Receive block in wrong format : fail to parse signature !"),
+            }));
+        }
+    }
+    certifications
+}
+
 pub fn parse_certifications_from_json_value(
     currency: &str,
     db: &DuniterDB,
-    wotb_index: &HashMap<ed25519::PublicKey, NodeId>,
     block_identities: &HashMap<ed25519::PublicKey, IdentityDocument>,
     array_certifications: &[serde_json::Value],
-) -> Vec<CertificationDocument> {
-    let mut certifications: Vec<CertificationDocument> = Vec::new();
+) -> Vec<TextDocumentFormat<CertificationDocument>> {
+    let mut certifications: Vec<TextDocumentFormat<CertificationDocument>> = Vec::new();
     for certification in array_certifications.iter() {
-        let certification_datas: Vec<&str> = certification.as_str().unwrap().split(':').collect();
+        let certification_datas: Vec<&str> = certification
+            .as_str()
+            .expect("Fail to parse certs : json isn't str !")
+            .split(':')
+            .collect();
         if certification_datas.len() == 4 {
             let target = PublicKey::from_base58(certification_datas[1])
                 .expect("Fail to parse cert target !");
             let target_idty_doc: IdentityDocument = match block_identities.get(&target) {
                 Some(idty_doc) => idty_doc.clone(),
                 None => {
-                    let target_wotb_id = wotb_index.get(&target).expect(&format!(
-                        "target identity {} not found in wotb index !",
-                        target.to_string()
-                    ));
-                    let dal_idty = DALIdentity::get_identity(currency, db, target_wotb_id)
+                    let dal_idty = DALIdentity::get_identity(currency, db, &target)
                         .expect("target identity not found in bdd !");
                     dal_idty.idty_doc
                 }
@@ -53,7 +84,7 @@ pub fn parse_certifications_from_json_value(
                         hash: if cert_blockstamp_id == BlockId(0) {
                             BlockHash(Hash::from_hex(
                             "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855",
-                        ).unwrap())
+                        ).expect("Fail to parse cert : invalid genesis hash"))
                         } else {
                             DALBlock::get_block_hash(db, &cert_blockstamp_id).expect(&format!(
                                 "Fatal Error : Block {} not found in bdd !",
@@ -68,7 +99,9 @@ pub fn parse_certifications_from_json_value(
                 };
             let cert_sig =
                 Signature::from_base64(certification_datas[3]).expect("Fail to parse cert sig !");
-            certifications.push(cert_builder.build_with_signature(vec![cert_sig]));
+            certifications.push(TextDocumentFormat::Complete(
+                cert_builder.build_with_signature(vec![cert_sig]),
+            ));
         }
     }
     certifications
@@ -77,19 +110,20 @@ pub fn parse_certifications_from_json_value(
 pub fn parse_certifications(
     currency: &str,
     db: &DuniterDB,
-    wotb_index: &HashMap<ed25519::PublicKey, NodeId>,
     block_identities: &HashMap<ed25519::PublicKey, IdentityDocument>,
     json_datas: &str,
-) -> Option<Vec<CertificationDocument>> {
-    let raw_certifications: serde_json::Value = serde_json::from_str(json_datas).unwrap();
+) -> Option<Vec<TextDocumentFormat<CertificationDocument>>> {
+    let raw_certifications: serde_json::Value =
+        serde_json::from_str(json_datas).expect("Fail to parse certs: str isn't json !");
 
     if raw_certifications.is_array() {
         Some(parse_certifications_from_json_value(
             currency,
             db,
-            wotb_index,
             block_identities,
-            raw_certifications.as_array().unwrap(),
+            raw_certifications
+                .as_array()
+                .expect("Fail to parse certs: json datas must be an array !"),
         ))
     } else {
         None
diff --git a/dal/parsers/revoked.rs b/dal/parsers/revoked.rs
index dc24d1b2d1df5a3cba065d6b8ea8baec13dedcd5..28f12568284da1ef35e2e2583101000737babde5 100644
--- a/dal/parsers/revoked.rs
+++ b/dal/parsers/revoked.rs
@@ -1,32 +1,55 @@
 extern crate serde_json;
 
 use duniter_crypto::keys::{ed25519, PublicKey, Signature};
-use duniter_documents::blockchain::v10::documents::revocation::RevocationDocumentBuilder;
-use duniter_documents::blockchain::v10::documents::{IdentityDocument, RevocationDocument};
+use duniter_documents::blockchain::v10::documents::revocation::{
+    CompactRevocationDocument, RevocationDocumentBuilder,
+};
+use duniter_documents::blockchain::v10::documents::{
+    IdentityDocument, RevocationDocument, TextDocumentFormat,
+};
 use duniter_documents::blockchain::{Document, DocumentBuilder};
-use duniter_wotb::NodeId;
 
 use super::super::identity::DALIdentity;
 use super::super::DuniterDB;
 
 use std::collections::HashMap;
 
+pub fn parse_revocations_into_compact(
+    json_recocations: &Vec<serde_json::Value>,
+) -> Vec<TextDocumentFormat<RevocationDocument>> {
+    let mut revocations: Vec<TextDocumentFormat<RevocationDocument>> = Vec::new();
+    for revocation in json_recocations.iter() {
+        let revocations_datas: Vec<&str> = revocation
+            .as_str()
+            .expect("Receive block in wrong format !")
+            .split(':')
+            .collect();
+        if revocations_datas.len() == 2 {
+            revocations.push(TextDocumentFormat::Compact(CompactRevocationDocument {
+                issuer: PublicKey::from_base58(revocations_datas[0])
+                    .expect("Receive block in wrong format !"),
+                signature: Signature::from_base64(revocations_datas[1])
+                    .expect("Receive block in wrong format !"),
+            }));
+        }
+    }
+    revocations
+}
+
 pub fn parse_revocations(
     currency: &str,
     db: &DuniterDB,
-    wotb_index: &HashMap<ed25519::PublicKey, NodeId>,
     block_identities: &HashMap<ed25519::PublicKey, IdentityDocument>,
     json_datas: &str,
-) -> Option<Vec<RevocationDocument>> {
-    let raw_certifications: serde_json::Value = serde_json::from_str(json_datas).unwrap();
+) -> Option<Vec<TextDocumentFormat<RevocationDocument>>> {
+    let raw_revocations: serde_json::Value = serde_json::from_str(json_datas).unwrap();
 
-    if raw_certifications.is_array() {
+    if raw_revocations.is_array() {
         Some(parse_revocations_from_json_value(
             currency,
             db,
-            wotb_index,
             block_identities,
-            raw_certifications.as_array().unwrap(),
+            raw_revocations.as_array().unwrap(),
         ))
     } else {
         None
@@ -36,11 +59,10 @@ pub fn parse_revocations(
 pub fn parse_revocations_from_json_value(
     currency: &str,
     db: &DuniterDB,
-    wotb_index: &HashMap<ed25519::PublicKey, NodeId>,
     block_identities: &HashMap<ed25519::PublicKey, IdentityDocument>,
     array_revocations: &[serde_json::Value],
-) -> Vec<RevocationDocument> {
-    let mut revocations: Vec<RevocationDocument> = Vec::new();
+) -> Vec<TextDocumentFormat<RevocationDocument>> {
+    let mut revocations: Vec<TextDocumentFormat<RevocationDocument>> = Vec::new();
     for revocation in array_revocations.iter() {
         let revocations_datas: Vec<&str> = revocation.as_str().unwrap().split(':').collect();
         if revocations_datas.len() == 2 {
@@ -49,8 +71,7 @@ pub fn parse_revocations_from_json_value(
             let idty_doc: IdentityDocument = match block_identities.get(&idty_pubkey) {
                 Some(idty_doc) => idty_doc.clone(),
                 None => {
-                    let idty_wotb_id = wotb_index.get(&idty_pubkey).unwrap();
-                    let dal_idty = DALIdentity::get_identity(currency, db, idty_wotb_id).unwrap();
+                    let dal_idty = DALIdentity::get_identity(currency, db, &idty_pubkey).unwrap();
                     dal_idty.idty_doc
                 }
             };
@@ -62,7 +83,9 @@ pub fn parse_revocations_from_json_value(
                 identity_sig: &idty_doc.signatures()[0],
             };
             let revoc_sig = Signature::from_base64(revocations_datas[1]).unwrap();
-            revocations.push(revoc_doc_builder.build_with_signature(vec![revoc_sig]));
+            revocations.push(TextDocumentFormat::Complete(
+                revoc_doc_builder.build_with_signature(vec![revoc_sig]),
+            ));
         }
     }
     revocations
diff --git a/dal/writers/block.rs b/dal/writers/block.rs
index 906dbdfe6a55b372548f6641753bb0de94548260..aeb4d4d87415c38b6330c57d415032b79f03505b 100644
--- a/dal/writers/block.rs
+++ b/dal/writers/block.rs
@@ -15,9 +15,6 @@ pub fn write_network_block(
     block: &BlockDocument,
     fork: usize,
     isolate: bool,
-    joiners: &Vec<serde_json::Value>,
-    actives: &Vec<serde_json::Value>,
-    leavers: &Vec<serde_json::Value>,
     revoked: &Vec<serde_json::Value>,
     certifications: &Vec<serde_json::Value>,
 ) {
@@ -32,8 +29,8 @@ pub fn write_network_block(
                 block.previous_hash.to_string(), block.inner_hash.unwrap().to_string(),
                 block.dividend.unwrap_or(0),
                 serde_json::to_string(&block.identities).unwrap(),
-                serde_json::to_string(joiners).unwrap(), serde_json::to_string(actives).unwrap(),
-                serde_json::to_string(leavers).unwrap(), serde_json::to_string(revoked).unwrap(),
+                serde_json::to_string(&block.joiners).unwrap(), serde_json::to_string(&block.actives).unwrap(),
+                serde_json::to_string(&block.leavers).unwrap(), serde_json::to_string(revoked).unwrap(),
                 serde_json::to_string(&block.excluded).unwrap(), serde_json::to_string(certifications).unwrap(),
                 serde_json::to_string(&block.transactions).unwrap()
             ))
diff --git a/dal/writers/certification.rs b/dal/writers/certification.rs
index 511c776612dba820ca59d7e7860580cba3b703a2..03ec2db95ec3c77b0a9cdb7fb7acf4148b08342a 100644
--- a/dal/writers/certification.rs
+++ b/dal/writers/certification.rs
@@ -4,12 +4,11 @@ extern crate sqlite;
 
 use super::super::DuniterDB;
 use duniter_crypto::keys::ed25519;
-use duniter_documents::blockchain::v10::documents::CertificationDocument;
-use duniter_documents::blockchain::Document;
+use duniter_documents::blockchain::v10::documents::certification::CompactCertificationDocument;
 use duniter_documents::Blockstamp;
 
 pub fn write_certification(
-    cert: &CertificationDocument,
+    cert: &CompactCertificationDocument,
     db: &DuniterDB,
     written_blockstamp: Blockstamp,
     written_timestamp: u64,
@@ -17,11 +16,11 @@ pub fn write_certification(
     let mut cursor = db
         .0
         .prepare("SELECT median_time FROM blocks WHERE number=? AND fork=0 LIMIT 1;")
-        .unwrap()
+        .expect("invalid write_certification sql request")
         .cursor();
 
     cursor
-        .bind(&[sqlite::Value::Integer(cert.blockstamp().id.0 as i64)])
+        .bind(&[sqlite::Value::Integer(cert.block_number.0 as i64)])
         .expect("convert blockstamp to timestamp failure at step 1 !");
 
     let mut created_timestamp: i64 = 0;
@@ -29,18 +28,20 @@ pub fn write_certification(
         .next()
         .expect("convert blockstamp to timestamp failure at step 2 !")
     {
-        created_timestamp = row[0].as_integer().unwrap();
+        created_timestamp = row[0]
+            .as_integer()
+            .expect("Fail to write cert, impossible to get created_timestamp !");
     }
 
     db.0
         .execute(
             format!("INSERT INTO certifications (pubkey_from, pubkey_to, created_on, signature, written_on, expires_on, chainable_on) VALUES ('{}', '{}', '{}', '{}', '{}', {}, {});",
-                cert.issuers()[0], cert.target(), cert.blockstamp().id.0, cert.signatures()[0],
+                cert.issuer, cert.target, cert.block_number.0, cert.signature,
                 written_blockstamp.to_string(),
                 created_timestamp+super::super::constants::G1_PARAMS.sig_validity,
                 written_timestamp+super::super::constants::G1_PARAMS.sig_period
             ))
-        .unwrap();
+        .expect("Fail to execute INSERT certification !");
 }
 
 pub fn remove_certification(from: ed25519::PublicKey, to: ed25519::PublicKey, db: &DuniterDB) {
@@ -49,5 +50,5 @@ pub fn remove_certification(from: ed25519::PublicKey, to: ed25519::PublicKey, db
             "DELETE FROM certifications WHERE pubkey_from={} AND pubkey_to={}",
             from, to
         ))
-        .unwrap();
+        .expect("Fail to execute DELETE certification !");
 }
diff --git a/dal/writers/identity.rs b/dal/writers/identity.rs
index c000d945cabfc3edf74f155dad765dad2b925d48..ea106fce344f2489d635bf26b09c49446fc67c4e 100644
--- a/dal/writers/identity.rs
+++ b/dal/writers/identity.rs
@@ -1,12 +1,15 @@
+extern crate duniter_wotb;
 extern crate sqlite;
 
 use super::super::identity::DALIdentity;
 use super::super::DuniterDB;
 use duniter_documents::blockchain::Document;
 use duniter_documents::Blockstamp;
+use duniter_wotb::NodeId;
 
 pub fn write(
     idty: &DALIdentity,
+    wotb_id: &NodeId,
     db: &DuniterDB,
     _written_blockstamp: Blockstamp,
     _written_timestamp: u64,
@@ -22,7 +25,7 @@ pub fn write(
     db.0
         .execute(
             format!("INSERT INTO identities (wotb_id, uid, pubkey, hash, sig, state, created_on, joined_on, penultimate_renewed_on, last_renewed_on, expires_on, revokes_on, expired_on, revoked_on) VALUES ({}, '{}', '{}', '{}', '{}', {}, '{}', '{}', '{}', '{}', {}, {}, '{}', '{}');",
-                idty.wotb_id.0, idty.idty_doc.username(), idty.idty_doc.issuers()[0], idty.hash,
+                (*wotb_id).0, idty.idty_doc.username(), idty.idty_doc.issuers()[0], idty.hash,
                 idty.idty_doc.signatures()[0], idty.state,
                 idty.idty_doc.blockstamp().to_string(),
                 idty.joined_on.to_string(),
diff --git a/dal/writers/mod.rs b/dal/writers/mod.rs
index 41219969b14c6d6fc9368ea0e3eb77513d41ebd6..aba7f80035e06d003fbf4387999ea70411845262 100644
--- a/dal/writers/mod.rs
+++ b/dal/writers/mod.rs
@@ -1,3 +1,4 @@
 pub mod block;
 pub mod certification;
 pub mod identity;
+pub mod requests;
diff --git a/dal/writers/requests.rs b/dal/writers/requests.rs
new file mode 100644
index 0000000000000000000000000000000000000000..c48b36a3e385cd6cc6929fb42bcb248c235ce492
--- /dev/null
+++ b/dal/writers/requests.rs
@@ -0,0 +1,83 @@
+extern crate duniter_crypto;
+extern crate duniter_documents;
+extern crate duniter_wotb;
+extern crate serde;
+extern crate serde_json;
+extern crate sqlite;
+
+use self::duniter_crypto::keys::ed25519;
+use self::duniter_documents::blockchain::v10::documents::certification::CompactCertificationDocument;
+use self::duniter_documents::blockchain::v10::documents::identity::IdentityDocument;
+use self::duniter_documents::Blockstamp;
+use self::duniter_wotb::NodeId;
+use super::super::block::DALBlock;
+use super::super::identity::DALIdentity;
+use super::super::DuniterDB;
+
+#[derive(Debug)]
+/// Contain a pending write request for blockchain database
+pub enum DBWriteRequest {
+    /// Newcomer
+    CreateIdentity(NodeId, Blockstamp, u64, IdentityDocument),
+    /// Active
+    RenewalIdentity(ed25519::PublicKey, Blockstamp, u64),
+    /// Excluded
+    ExcludeIdentity(NodeId, Blockstamp, u64),
+    /// Revoked
+    RevokeIdentity(NodeId, Blockstamp, u64),
+    /// Certification
+    CreateCert(Blockstamp, u64, CompactCertificationDocument),
+    /// Certification expiry
+    CertExpiry(NodeId, NodeId, Blockstamp, u64),
+    /// Write block
+    WriteBlock(DALBlock),
+    /// Revert block
+    RevertBlock(DALBlock),
+}
+
+impl DBWriteRequest {
+    pub fn apply(&self, currency: &str, db: &DuniterDB) {
+        match *self {
+            DBWriteRequest::CreateIdentity(
+                ref wotb_id,
+                ref blockstamp,
+                ref median_time,
+                ref idty_doc,
+            ) => {
+                trace!("DBWriteRequest::CreateIdentity...");
+                let idty = DALIdentity::create_identity(db, idty_doc, blockstamp.clone());
+                super::identity::write(&idty, wotb_id, db, blockstamp.clone(), *median_time);
+                trace!("DBWriteRequest::CreateIdentity...finish.");
+            }
+            DBWriteRequest::RenewalIdentity(ref pubkey, ref blockstamp, ref median_time) => {
+                trace!("DBWriteRequest::RenewalIdentity...");
+                let mut idty = DALIdentity::get_identity(currency, db, pubkey)
+                    .expect("Fatal error : impossible ton renewal an identidy that don't exist !");
+                idty.renewal_identity(db, pubkey, blockstamp, *median_time, false);
+                trace!("DBWriteRequest::RenewalIdentity...");
+            }
+            DBWriteRequest::ExcludeIdentity(ref wotb_id, ref blockstamp, ref _median_time) => {
+                DALIdentity::exclude_identity(db, *wotb_id, *blockstamp, false);
+            }
+            DBWriteRequest::RevokeIdentity(ref wotb_id, ref blockstamp, ref _median_time) => {
+                DALIdentity::revoke_identity(db, *wotb_id, blockstamp, false);
+            }
+            DBWriteRequest::CreateCert(ref blockstamp, ref median_time, ref compact_cert) => {
+                trace!("DBWriteRequest::CreateCert...");
+                super::certification::write_certification(
+                    compact_cert,
+                    db,
+                    blockstamp.clone(),
+                    *median_time,
+                );
+                trace!("DBWriteRequest::CreateCert...finish");
+            }
+            DBWriteRequest::WriteBlock(ref dal_block) => {
+                trace!("DBWriteRequest::WriteBlock...");
+                super::block::write(db, &dal_block.block, dal_block.fork, dal_block.isolate);
+                trace!("DBWriteRequest::WriteBlock...finish");
+            }
+            _ => {}
+        }
+    }
+}
diff --git a/documents/blockchain/v10/documents/block.rs b/documents/blockchain/v10/documents/block.rs
index 0305af99761abe685cafcc3d3c8d1f2c839398b5..1b51c4689331f4b1bbf849d348a3ef7428577222 100644
--- a/documents/blockchain/v10/documents/block.rs
+++ b/documents/blockchain/v10/documents/block.rs
@@ -24,7 +24,7 @@ use blockchain::v10::documents::identity::IdentityDocument;
 use blockchain::v10::documents::membership::MembershipDocument;
 use blockchain::v10::documents::revocation::RevocationDocument;
 use blockchain::v10::documents::transaction::TransactionDocument;
-use blockchain::v10::documents::{TextDocument, V10Document};
+use blockchain::v10::documents::*;
 use blockchain::{BlockchainProtocol, Document, IntoSpecializedDocument};
 use {BlockHash, BlockId, Blockstamp, Hash};
 
@@ -130,11 +130,11 @@ pub struct BlockDocument {
     /// Leavers
     pub leavers: Vec<MembershipDocument>,
     /// Revokeds
-    pub revoked: Vec<RevocationDocument>,
+    pub revoked: Vec<TextDocumentFormat<RevocationDocument>>,
     /// Excludeds
     pub excluded: Vec<ed25519::PublicKey>,
     /// Certifications
-    pub certifications: Vec<CertificationDocument>,
+    pub certifications: Vec<TextDocumentFormat<CertificationDocument>>,
     /// Transactions
     pub transactions: Vec<TransactionDocument>,
     /// Part to sign
@@ -146,9 +146,6 @@ impl BlockDocument {
     pub fn compute_inner_hash(&mut self) {
         let mut sha256 = Sha256::new();
         let inner_text = self.generate_compact_inner_text();
-        /*if self.number.0 == 46473 {
-            println!("#46473 raw_format=\"{}\"", inner_text);
-        }*/
         sha256.input_str(&inner_text);
         self.inner_hash = Some(Hash::from_hex(&sha256.result_str()).unwrap());
     }
@@ -176,7 +173,8 @@ impl BlockDocument {
         ));
         self.hash = Some(BlockHash(Hash::from_hex(&sha256.result_str()).unwrap()));
     }
-    fn generate_compact_inner_text(&self) -> String {
+    /// Generate compact inner text (for compute inner_hash)
+    pub fn generate_compact_inner_text(&self) -> String {
         let mut identities_str = String::from("");
         for identity in self.identities.clone() {
             identities_str.push_str("\n");
@@ -205,7 +203,7 @@ impl BlockDocument {
         let mut revokeds_str = String::from("");
         for revocation in self.revoked.clone() {
             revokeds_str.push_str("\n");
-            revokeds_str.push_str(&revocation.generate_compact_text());
+            revokeds_str.push_str(&revocation.as_compact_text());
         }
         let mut excludeds_str = String::from("");
         for exclusion in self.excluded.clone() {
@@ -215,7 +213,7 @@ impl BlockDocument {
         let mut certifications_str = String::from("");
         for certification in self.certifications.clone() {
             certifications_str.push_str("\n");
-            certifications_str.push_str(&certification.generate_compact_text());
+            certifications_str.push_str(&certification.as_compact_text());
         }
         let mut transactions_str = String::from("");
         for transaction in self.transactions.clone() {
@@ -313,12 +311,8 @@ impl Document for BlockDocument {
     }
 }
 
-impl TextDocument for BlockDocument {
-    fn as_text(&self) -> &str {
-        panic!();
-    }
-
-    fn generate_compact_text(&self) -> String {
+impl CompactTextDocument for BlockDocument {
+    fn as_compact_text(&self) -> String {
         let compact_inner_text = self.generate_compact_inner_text();
         format!(
             "{}InnerHash: {}\nNonce: ",
@@ -328,6 +322,18 @@ impl TextDocument for BlockDocument {
     }
 }
 
+impl TextDocument for BlockDocument {
+    type CompactTextDocument_ = BlockDocument;
+
+    fn as_text(&self) -> &str {
+        panic!();
+    }
+
+    fn to_compact_document(&self) -> Self::CompactTextDocument_ {
+        self.clone()
+    }
+}
+
 impl IntoSpecializedDocument<BlockchainProtocol> for BlockDocument {
     fn into_specialized(self) -> BlockchainProtocol {
         BlockchainProtocol::V10(Box::new(V10Document::Block(Box::new(self))))
@@ -506,7 +512,7 @@ a9PHPuSfw7jW8FRQHXFsGi/bnLjbtDnTYvEVgUC9u0WlR7GVofa+Xb+l5iy6NwuEXiwvueAkf08wPVY8
             leavers: Vec::new(),
             revoked: Vec::new(),
             excluded: Vec::new(),
-            certifications: vec![cert1],
+            certifications: vec![TextDocumentFormat::Complete(cert1)],
             transactions: vec![tx1, tx2],
             inner_hash_and_nonce_str: String::new(),
         };
diff --git a/documents/blockchain/v10/documents/certification.rs b/documents/blockchain/v10/documents/certification.rs
index b3e8857ccbe90c902b1e7d8bc307cb61e780aec3..842591838c7eb796bb28cfc5a76bd2e816fffffc 100644
--- a/documents/blockchain/v10/documents/certification.rs
+++ b/documents/blockchain/v10/documents/certification.rs
@@ -21,11 +21,9 @@ use self::serde::ser::{Serialize, Serializer};
 use duniter_crypto::keys::{ed25519, PublicKey, Signature};
 use regex::Regex;
 
-use blockchain::v10::documents::{
-    StandardTextDocumentParser, TextDocument, TextDocumentBuilder, V10Document,
-    V10DocumentParsingError,
-};
+use blockchain::v10::documents::*;
 use blockchain::{BlockchainProtocol, Document, DocumentBuilder, IntoSpecializedDocument};
+use BlockId;
 use Blockstamp;
 
 lazy_static! {
@@ -34,6 +32,31 @@ lazy_static! {
     ).unwrap();
 }
 
+#[derive(Debug, Copy, Clone)]
+/// Wrap an Compact Revocation document (in block content)
+pub struct CompactCertificationDocument {
+    /// Issuer
+    pub issuer: ed25519::PublicKey,
+    /// Target
+    pub target: ed25519::PublicKey,
+    /// Blockstamp
+    pub block_number: BlockId,
+    /// Signature
+    pub signature: ed25519::Signature,
+}
+
+impl CompactTextDocument for CompactCertificationDocument {
+    fn as_compact_text(&self) -> String {
+        format!(
+            "{issuer}:{target}:{block_number}:{signature}",
+            issuer = self.issuer,
+            target = self.target,
+            block_number = self.block_number.0,
+            signature = self.signature,
+        )
+    }
+}
+
 /// Wrap an Certification document.
 ///
 /// Must be created by parsing a text document or using a builder.
@@ -109,27 +132,28 @@ impl Document for CertificationDocument {
 }
 
 impl TextDocument for CertificationDocument {
+    type CompactTextDocument_ = CompactCertificationDocument;
+
     fn as_text(&self) -> &str {
         &self.text
     }
 
-    fn generate_compact_text(&self) -> String {
-        format!(
-            "{issuer}:{target}:{block_number}:{signature}",
-            issuer = self.issuers[0],
-            target = self.target,
-            block_number = self.blockstamp.id.0,
-            signature = self.signatures[0],
-        )
+    fn to_compact_document(&self) -> Self::CompactTextDocument_ {
+        CompactCertificationDocument {
+            issuer: self.issuers[0],
+            target: self.target,
+            block_number: self.blockstamp().id,
+            signature: self.signatures()[0],
+        }
     }
 }
 
-impl Serialize for CertificationDocument {
+impl Serialize for TextDocumentFormat<CertificationDocument> {
     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
     where
         S: Serializer,
     {
-        serializer.serialize_str(&self.generate_compact_text())
+        serializer.serialize_str(&self.as_compact_text())
     }
 }
 
diff --git a/documents/blockchain/v10/documents/identity.rs b/documents/blockchain/v10/documents/identity.rs
index 6e986565b04dc04222ff93ed31b3509b7fb4b7be..40bd02bb3c7dc5c1c7d52938028b8f25e14998e0 100644
--- a/documents/blockchain/v10/documents/identity.rs
+++ b/documents/blockchain/v10/documents/identity.rs
@@ -21,10 +21,7 @@ use self::serde::ser::{Serialize, Serializer};
 use duniter_crypto::keys::{ed25519, PublicKey};
 use regex::Regex;
 
-use blockchain::v10::documents::{
-    StandardTextDocumentParser, TextDocument, TextDocumentBuilder, V10Document,
-    V10DocumentParsingError,
-};
+use blockchain::v10::documents::*;
 use blockchain::{BlockchainProtocol, Document, DocumentBuilder, IntoSpecializedDocument};
 use Blockstamp;
 
@@ -93,12 +90,8 @@ impl Document for IdentityDocument {
     }
 }
 
-impl TextDocument for IdentityDocument {
-    fn as_text(&self) -> &str {
-        &self.text
-    }
-
-    fn generate_compact_text(&self) -> String {
+impl CompactTextDocument for IdentityDocument {
+    fn as_compact_text(&self) -> String {
         format!(
             "{issuer}:{signature}:{blockstamp}:{username}",
             issuer = self.issuers[0],
@@ -109,6 +102,18 @@ impl TextDocument for IdentityDocument {
     }
 }
 
+impl TextDocument for IdentityDocument {
+    type CompactTextDocument_ = IdentityDocument;
+
+    fn as_text(&self) -> &str {
+        &self.text
+    }
+
+    fn to_compact_document(&self) -> Self::CompactTextDocument_ {
+        self.clone()
+    }
+}
+
 impl Serialize for IdentityDocument {
     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
     where
diff --git a/documents/blockchain/v10/documents/membership.rs b/documents/blockchain/v10/documents/membership.rs
index 0cc53d51b5521471a4aa2719963e94a18704dbdf..2e313601e9f938d431ba33800582234a9ab15382 100644
--- a/documents/blockchain/v10/documents/membership.rs
+++ b/documents/blockchain/v10/documents/membership.rs
@@ -21,10 +21,7 @@ use self::serde::ser::{Serialize, Serializer};
 use duniter_crypto::keys::{ed25519, PublicKey};
 use regex::Regex;
 
-use blockchain::v10::documents::{
-    StandardTextDocumentParser, TextDocument, TextDocumentBuilder, V10Document,
-    V10DocumentParsingError,
-};
+use blockchain::v10::documents::*;
 use blockchain::{BlockchainProtocol, Document, DocumentBuilder, IntoSpecializedDocument};
 use Blockstamp;
 
@@ -114,12 +111,8 @@ impl Document for MembershipDocument {
     }
 }
 
-impl TextDocument for MembershipDocument {
-    fn as_text(&self) -> &str {
-        &self.text
-    }
-
-    fn generate_compact_text(&self) -> String {
+impl CompactTextDocument for MembershipDocument {
+    fn as_compact_text(&self) -> String {
         format!(
             "{issuer}:{signature}:{blockstamp}:{idty_blockstamp}:{username}",
             issuer = self.issuers[0],
@@ -131,6 +124,18 @@ impl TextDocument for MembershipDocument {
     }
 }
 
+impl TextDocument for MembershipDocument {
+    type CompactTextDocument_ = MembershipDocument;
+
+    fn as_text(&self) -> &str {
+        &self.text
+    }
+
+    fn to_compact_document(&self) -> Self::CompactTextDocument_ {
+        self.clone()
+    }
+}
+
 impl Serialize for MembershipDocument {
     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
     where
diff --git a/documents/blockchain/v10/documents/mod.rs b/documents/blockchain/v10/documents/mod.rs
index 3557543aabb1be765eb61f36933a895a55c5eba1..495190dd55e0d22a5e671b0c16f1cc8e6e0f2405 100644
--- a/documents/blockchain/v10/documents/mod.rs
+++ b/documents/blockchain/v10/documents/mod.rs
@@ -42,6 +42,8 @@ pub use blockchain::v10::documents::transaction::{
     TransactionDocument, TransactionDocumentBuilder, TransactionDocumentParser,
 };
 
+use std::marker::Sized;
+
 // Use of lazy_static so the regex is only compiled at first use.
 lazy_static! {
     static ref DOCUMENT_REGEX: Regex = Regex::new(
@@ -54,6 +56,25 @@ lazy_static! {
     static ref SIGNATURES_REGEX: Regex = Regex::new("[[:alnum:]+/=]+\n?").unwrap();
 }
 
+#[derive(Debug, Clone)]
+/// Contains a document in full or compact format
+pub enum TextDocumentFormat<D: TextDocument> {
+    /// Complete format (Allows to check the validity of the signature)
+    Complete(D),
+    /// Format present in the blocks (does not always allow to verify the signature)
+    Compact(D::CompactTextDocument_),
+}
+
+impl<D: TextDocument> TextDocumentFormat<D> {
+    /// To compact document
+    pub fn to_compact_document(&self) -> D::CompactTextDocument_ {
+        match *self {
+            TextDocumentFormat::Complete(ref doc) => doc.to_compact_document(),
+            TextDocumentFormat::Compact(ref compact_doc) => (*compact_doc).clone(),
+        }
+    }
+}
+
 /// List of wrapped document types.
 ///
 /// > TODO Add wrapped types in enum variants.
@@ -78,8 +99,30 @@ pub enum V10Document {
     Revocation(Box<RevocationDocument>),
 }
 
+/// Trait for a compact V10 document.
+pub trait CompactTextDocument: Sized + Clone {
+    /// Generate document compact text.
+    /// the compact format is the one used in the blocks.
+    ///
+    /// - Don't contains leading signatures
+    /// - Contains line breaks on all line.
+    fn as_compact_text(&self) -> String;
+}
+
+impl<D: TextDocument> CompactTextDocument for TextDocumentFormat<D> {
+    fn as_compact_text(&self) -> String {
+        match *self {
+            TextDocumentFormat::Complete(ref doc) => doc.generate_compact_text(),
+            TextDocumentFormat::Compact(ref doc) => doc.as_compact_text(),
+        }
+    }
+}
+
 /// Trait for a V10 document.
 pub trait TextDocument: Document<PublicKey = ed25519::PublicKey, CurrencyType = str> {
+    /// Type of associated compact document.
+    type CompactTextDocument_: CompactTextDocument;
+
     /// Return document as text.
     fn as_text(&self) -> &str;
 
@@ -100,12 +143,19 @@ pub trait TextDocument: Document<PublicKey = ed25519::PublicKey, CurrencyType =
         text
     }
 
+    /// Generate compact document.
+    /// the compact format is the one used in the blocks.
+    /// - Don't contains leading signatures
+    fn to_compact_document(&self) -> Self::CompactTextDocument_;
+
     /// Generate document compact text.
     /// the compact format is the one used in the blocks.
     ///
     /// - Don't contains leading signatures
     /// - Contains line breaks on all line.
-    fn generate_compact_text(&self) -> String;
+    fn generate_compact_text(&self) -> String {
+        self.to_compact_document().as_compact_text()
+    }
 }
 
 /// Trait for a V10 document builder.
diff --git a/documents/blockchain/v10/documents/revocation.rs b/documents/blockchain/v10/documents/revocation.rs
index b954ae13b2ead8be53710732e66daadf3ae3eb26..d40d97046fe03fb391ae42598985aa8c143ffcde 100644
--- a/documents/blockchain/v10/documents/revocation.rs
+++ b/documents/blockchain/v10/documents/revocation.rs
@@ -21,10 +21,7 @@ use self::serde::ser::{Serialize, Serializer};
 use duniter_crypto::keys::{ed25519, PublicKey, Signature};
 use regex::Regex;
 
-use blockchain::v10::documents::{
-    StandardTextDocumentParser, TextDocument, TextDocumentBuilder, V10Document,
-    V10DocumentParsingError,
-};
+use blockchain::v10::documents::*;
 use blockchain::{BlockchainProtocol, Document, DocumentBuilder, IntoSpecializedDocument};
 use Blockstamp;
 
@@ -37,6 +34,25 @@ lazy_static! {
     ).unwrap();
 }
 
+#[derive(Debug, Copy, Clone)]
+/// Wrap an Compact Revocation document (in block content)
+pub struct CompactRevocationDocument {
+    /// Issuer
+    pub issuer: ed25519::PublicKey,
+    /// Signature
+    pub signature: ed25519::Signature,
+}
+
+impl CompactTextDocument for CompactRevocationDocument {
+    fn as_compact_text(&self) -> String {
+        format!(
+            "{issuer}:{signature}",
+            issuer = self.issuer,
+            signature = self.signature,
+        )
+    }
+}
+
 /// Wrap an Revocation document.
 ///
 /// Must be created by parsing a text document or using a builder.
@@ -98,25 +114,26 @@ impl Document for RevocationDocument {
 }
 
 impl TextDocument for RevocationDocument {
+    type CompactTextDocument_ = CompactRevocationDocument;
+
     fn as_text(&self) -> &str {
         &self.text
     }
 
-    fn generate_compact_text(&self) -> String {
-        format!(
-            "{issuer}:{signature}",
-            issuer = self.issuers[0],
-            signature = self.signatures[0],
-        )
+    fn to_compact_document(&self) -> Self::CompactTextDocument_ {
+        CompactRevocationDocument {
+            issuer: self.issuers[0],
+            signature: self.signatures[0],
+        }
     }
 }
 
-impl Serialize for RevocationDocument {
+impl Serialize for TextDocumentFormat<RevocationDocument> {
     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
     where
         S: Serializer,
     {
-        serializer.serialize_str(&self.generate_compact_text())
+        serializer.serialize_str(&self.as_compact_text())
     }
 }
 
diff --git a/documents/blockchain/v10/documents/transaction.rs b/documents/blockchain/v10/documents/transaction.rs
index efcf04a7e1252862277bde9898b73b450bf415ee..992640c8a6ce937f77e9e703803fa1791f6a8835 100644
--- a/documents/blockchain/v10/documents/transaction.rs
+++ b/documents/blockchain/v10/documents/transaction.rs
@@ -25,10 +25,7 @@ use regex::RegexBuilder;
 
 use self::serde::ser::{Serialize, Serializer};
 
-use blockchain::v10::documents::{
-    StandardTextDocumentParser, TextDocument, TextDocumentBuilder, V10Document,
-    V10DocumentParsingError,
-};
+use blockchain::v10::documents::*;
 use blockchain::{BlockchainProtocol, Document, DocumentBuilder, IntoSpecializedDocument};
 use Blockstamp;
 
@@ -442,12 +439,8 @@ impl Document for TransactionDocument {
     }
 }
 
-impl TextDocument for TransactionDocument {
-    fn as_text(&self) -> &str {
-        &self.text
-    }
-
-    fn generate_compact_text(&self) -> String {
+impl CompactTextDocument for TransactionDocument {
+    fn as_compact_text(&self) -> String {
         let mut issuers_str = String::from("");
         for issuer in self.issuers.clone() {
             issuers_str.push_str("\n");
@@ -499,12 +492,24 @@ impl TextDocument for TransactionDocument {
     }
 }
 
+impl TextDocument for TransactionDocument {
+    type CompactTextDocument_ = TransactionDocument;
+
+    fn as_text(&self) -> &str {
+        &self.text
+    }
+
+    fn to_compact_document(&self) -> Self::CompactTextDocument_ {
+        self.clone()
+    }
+}
+
 impl Serialize for TransactionDocument {
     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
     where
         S: Serializer,
     {
-        let compact_text = self.generate_compact_text();
+        let compact_text = self.to_compact_document().generate_compact_text();
         serializer.serialize_str(&compact_text.replace("\n", "$"))
     }
 }
diff --git a/network/lib.rs b/network/lib.rs
index d02928b921cb78a28098fc8fe8860c6ecccafb1f..d6b42720d63d0ef75665aa551e0fe19e3c13d7b8 100644
--- a/network/lib.rs
+++ b/network/lib.rs
@@ -109,12 +109,6 @@ pub trait NetworkConf: Debug + Copy + Clone + PartialEq {}
 pub struct NetworkBlockV10 {
     /// Uncompleted block document
     pub uncompleted_block_doc: BlockDocument,
-    /// Joiners
-    pub joiners: Vec<serde_json::Value>,
-    /// actives
-    pub actives: Vec<serde_json::Value>,
-    /// leavers
-    pub leavers: Vec<serde_json::Value>,
     /// revoked
     pub revoked: Vec<serde_json::Value>,
     /// certifications
diff --git a/ws2p/lib.rs b/ws2p/lib.rs
index aef80ddd09595acb261441f5296c91cb3ddbf2df..835e3c0db4aa647f2b0a732e85b3fe5e4042bbbc 100644
--- a/ws2p/lib.rs
+++ b/ws2p/lib.rs
@@ -1063,22 +1063,28 @@ impl WS2PModuleDatas {
     pub fn connect_to_know_endpoints(&mut self) -> () {
         let mut count_established_connections = 0;
         let mut reachable_endpoints = Vec::new();
+        let mut unreachable_endpoints = Vec::new();
         for (_ws2p_full_id, (ep, state)) in self.ws2p_endpoints.clone() {
             match state {
                 WS2PConnectionState::Established => count_established_connections += 1,
                 WS2PConnectionState::NeverTry
                 | WS2PConnectionState::Close
                 | WS2PConnectionState::Denial => reachable_endpoints.push(ep),
-                _ => {}
+                _ => unreachable_endpoints.push(ep),
             }
         }
         let mut free_outcoming_rooms =
             self.conf.clone().unwrap().outcoming_quota - count_established_connections;
-        for ep in reachable_endpoints {
-            if free_outcoming_rooms > 0 {
-                free_outcoming_rooms -= 1;
-                self.connect_to_without_checking_quotas(ep);
-            }
+        while free_outcoming_rooms > 0 {
+            let ep = if !reachable_endpoints.is_empty() {
+                reachable_endpoints.pop().unwrap()
+            } else if !unreachable_endpoints.is_empty() {
+                unreachable_endpoints.pop().unwrap()
+            } else {
+                break;
+            };
+            self.connect_to_without_checking_quotas(ep);
+            free_outcoming_rooms -= 1;
         }
     }
     pub fn connect_to(&mut self, endpoint: NetworkEndpoint) -> () {