diff --git a/Cargo.lock b/Cargo.lock
index f40c81f10369de38b94ad0e9a67c7be7d4b1f212..b727cd5f2799ffd74bc980811a3f4fac2c8489dc 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -930,6 +930,7 @@ dependencies = [
  "dup-crypto-tests-tools 0.1.0",
  "durs-bc-db-reader 0.3.0-dev",
  "durs-bc-db-writer 0.3.0-dev",
+ "durs-common-tests-tools 0.1.0",
  "durs-common-tools 0.2.0",
  "durs-conf 0.3.0-dev",
  "durs-message 0.3.0-dev",
@@ -942,6 +943,7 @@ dependencies = [
  "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "pbr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/lib/modules/blockchain/blockchain/tests/common.rs b/lib/modules/blockchain/blockchain/tests/common.rs
new file mode 100644
index 0000000000000000000000000000000000000000..d87405b5d93ea8eb736d234e3a323975d7d29654
--- /dev/null
+++ b/lib/modules/blockchain/blockchain/tests/common.rs
@@ -0,0 +1,77 @@
+//  Copyright (C) 2017-2019  The AXIOM TEAM Association.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+use dubp_currency_params::genesis_block_params::v10::BlockV10Parameters;
+use dubp_currency_params::{CurrencyName, CurrencyParameters};
+use durs_bc_db_writer::WotsV10DBs;
+use durs_blockchain::BlockchainModule;
+use durs_message::DursMsg;
+use durs_module::RouterThreadMessage;
+use std::path::{Path, PathBuf};
+use std::sync::mpsc::Sender;
+use std::thread::JoinHandle;
+use tempfile::TempDir;
+
+pub static TEST_CURRENCY: &str = "test_currency";
+
+/// Init logger and user datas directory
+pub fn init() -> PathBuf {
+    durs_common_tests_tools::logger::init_logger_stdout(vec![]);
+    TempDir::new().expect("Fail to create tmp dir.").into_path()
+}
+
+/// Stop and clear test
+pub fn stop_and_clean(
+    bc_sender: Sender<DursMsg>,
+    handle: JoinHandle<()>,
+    tmp_profile_path: PathBuf,
+) {
+    // Send STOP signal to blockchain module
+    bc_sender
+        .send(DursMsg::Stop)
+        .expect("Fail to send stop signal to blockchain module.");
+    handle
+        .join()
+        .expect("Blockchain module fail to stop correctly.");
+
+    // Clear user datas
+    std::fs::remove_dir_all(tmp_profile_path).expect("Fail to remove tmp dir.");
+}
+
+/// Initialize a BlockchainModule with empty blockchain
+pub fn init_bc_module(
+    fake_router_sender: Sender<RouterThreadMessage<DursMsg>>,
+    genesis_block_parameters: BlockV10Parameters,
+    tmp_path: &Path,
+) -> BlockchainModule {
+    let currency_name = CurrencyName(TEST_CURRENCY.to_owned());
+    //let profile_path = tmp_profile_path.to_owned();
+
+    //let dbs_path = durs_conf::get_blockchain_db_path(profile_path.clone());
+    let db = durs_bc_db_writer::open_db(tmp_path).expect("Fail to open blockchain DB.");
+
+    BlockchainModule::new(
+        fake_router_sender,
+        tmp_path.to_owned(),
+        Some(currency_name.clone()),
+        Some(CurrencyParameters::from((
+            &currency_name,
+            genesis_block_parameters,
+        ))),
+        db,
+        WotsV10DBs::open(None),
+    )
+    .expect("Fail to init BlockchainModule with empty blockchain.")
+}
diff --git a/lib/modules/blockchain/blockchain/tests/revert_blocks.rs b/lib/modules/blockchain/blockchain/tests/revert_blocks.rs
new file mode 100644
index 0000000000000000000000000000000000000000..2e5a77fd383d4516b5340b3b81372e3bfe100d5b
--- /dev/null
+++ b/lib/modules/blockchain/blockchain/tests/revert_blocks.rs
@@ -0,0 +1,162 @@
+//  Copyright (C) 2017-2019  The AXIOM TEAM Association.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+mod common;
+
+use crate::common::*;
+use dubp_block_doc::{block::BlockDocumentTrait, BlockDocument};
+use dubp_common_doc::BlockNumber;
+use dubp_currency_params::genesis_block_params::v10::BlockV10Parameters;
+use dup_crypto::keys::{KeyPair, Signator, SignatorEnum};
+use durs_blockchain::BlockchainModule;
+use durs_message::events::{BlockchainEvent, DursEvent};
+use durs_message::requests::DursReqContent;
+use durs_message::DursMsg;
+use durs_module::{
+    ModuleEvent, ModuleReqFullId, ModuleReqId, ModuleRole, ModuleStaticName, RouterThreadMessage,
+};
+use durs_network::events::NetworkEvent;
+use durs_network::requests::OldNetworkRequest;
+use pretty_assertions::assert_eq;
+use std::sync::mpsc::{channel, Receiver, Sender};
+
+#[test]
+fn test_revert_block() {
+    // Init test
+    let tmp_profile_path = common::init();
+
+    // Router channel
+    let (router_sender, router_receiver) = channel(); // RouterThreadMessage<DursMsg>
+
+    let genesis_params = BlockV10Parameters::default();
+
+    let mut bc = init_bc_module(router_sender, genesis_params, tmp_profile_path.as_path());
+
+    // Create blockchain module channel
+    let (bc_sender, bc_receiver): (Sender<DursMsg>, Receiver<DursMsg>) = channel();
+
+    let handle = std::thread::spawn(move || {
+        bc.start_blockchain(&bc_receiver, None);
+    });
+
+    // Receive 11 requests GetBlocks
+    for i in 0..11 {
+        let msg = router_receiver
+            .recv()
+            .expect("blockchain module disconnected.");
+        if let RouterThreadMessage::ModuleMessage(durs_msg) = msg {
+            assert_eq!(
+                DursMsg::Request {
+                    req_from: BlockchainModule::name(),
+                    req_to: ModuleRole::InterNodesNetwork,
+                    req_id: ModuleReqId(i),
+                    req_content: DursReqContent::OldNetworkRequest(OldNetworkRequest::GetBlocks(
+                        ModuleReqFullId(BlockchainModule::name(), ModuleReqId(i)),
+                        50,
+                        i * 50
+                    )),
+                },
+                durs_msg
+            );
+            log::info!("Router receive: {:?}", durs_msg);
+        } else {
+            panic!("Expect ModuleMesage, found: {:?}", msg)
+        }
+    }
+
+    // Receive first g1-test chunk
+    let gt_chunk_0 = dubp_blocks_tests_tools::gt::get_gt_chunk(0);
+    receive_valid_blocks(&bc_sender, &router_receiver, gt_chunk_0);
+
+    // Receive second g1-test chunk
+    let gt_chunk_1 = dubp_blocks_tests_tools::gt::get_gt_chunk(1);
+    receive_valid_blocks(&bc_sender, &router_receiver, gt_chunk_1);
+
+    // Receive third g1-test chunk
+    let mut gt_chunk_2 = dubp_blocks_tests_tools::gt::get_gt_chunk(2);
+    gt_chunk_2.truncate(50);
+    let block_546 = gt_chunk_2.get(46).cloned().expect("gt_chunk_2 is empty !");
+    receive_valid_blocks(&bc_sender, &router_receiver, gt_chunk_2);
+
+    // Generate 6 forks blocks from 547 to 553
+    let signator = SignatorEnum::Ed25519(
+        dup_crypto::keys::ed25519::Ed25519KeyPair::generate_random()
+            .generate_signator()
+            .expect("fail to generatye signator"),
+    );
+    let mut fork_blocks = Vec::new();
+    let mut previous_hash = block_546.hash().expect("block_546 have None hash").0;
+    let mut bc_time = block_546.common_time();
+    for n in 547..=553 {
+        bc_time += 301;
+        let block = dubp_blocks_tests_tools::mocks::gen_empty_timed_issued_hashed_block_v10(
+            BlockNumber(n),
+            bc_time,
+            signator.public_key(),
+            previous_hash,
+            &signator,
+        );
+        let block_hash = block.hash().clone().expect("block must have hash");
+        fork_blocks.push(BlockDocument::V10(block));
+        previous_hash = block_hash.0;
+    }
+
+    // Cause the revert of 3 blocks (send forks blocks from 547)
+    receive_valid_blocks(&bc_sender, &router_receiver, fork_blocks);
+
+    // TODO verify that we have switched to the new branch
+
+    // let msg2 = router_receiver
+    //     .recv()
+    //     .expect("blockchain module disconnected.");
+    // log::info!("Router receive: {:?}", msg2);
+
+    // Stop and clean
+    common::stop_and_clean(bc_sender, handle, tmp_profile_path);
+}
+
+fn receive_valid_blocks(
+    bc_sender: &Sender<DursMsg>,
+    router_receiver: &Receiver<RouterThreadMessage<DursMsg>>,
+    blocks: Vec<BlockDocument>,
+) {
+    bc_sender
+        .send(DursMsg::Event {
+            event_from: ModuleStaticName("toto"),
+            event_type: ModuleEvent::NewBlockFromNetwork,
+            event_content: DursEvent::NetworkEvent(NetworkEvent::ReceiveBlocks(blocks.clone())),
+        })
+        .expect("Fail to send blocks to blockchain module.");
+    for block in blocks {
+        let msg = router_receiver
+            .recv()
+            .expect("blockchain module disconnected.");
+        if let RouterThreadMessage::ModuleMessage(durs_msg) = msg {
+            assert_eq!(
+                DursMsg::Event {
+                    event_from: ModuleStaticName("blockchain"),
+                    event_type: ModuleEvent::NewValidBlock,
+                    event_content: DursEvent::BlockchainEvent(Box::new(
+                        BlockchainEvent::StackUpValidBlock(Box::new(block))
+                    )),
+                },
+                durs_msg
+            );
+        //log::debug!("Router receive: {:?}", msg);
+        } else {
+            panic!("Expect ModuleMesage, found: {:?}", msg)
+        }
+    }
+}