diff --git a/rust-bins/duniter-dbex/src/migrate.rs b/rust-bins/duniter-dbex/src/migrate.rs
index b4bcc7abf868780453ad8a1921a1f7191d75a7df..1678bdeb23a12696d7fa533031656ba16225edcf 100644
--- a/rust-bins/duniter-dbex/src/migrate.rs
+++ b/rust-bins/duniter-dbex/src/migrate.rs
@@ -160,11 +160,8 @@ fn migrate_inner(
 }
 
 fn get_target_block_number(duniter_js_db: &BcV1Db<LevelDb>) -> KvResult<Option<BlockNumber>> {
-    duniter_js_db.main_blocks().iter(.., |it| {
-        it.reverse()
-            .keys()
-            .map(|k_res| k_res.map(|bn| bn.0))
-            .next_res()
+    duniter_js_db.main_blocks().iter_rev(.., |it| {
+        it.keys().map(|k_res| k_res.map(|bn| bn.0)).next_res()
     })
 }
 
diff --git a/rust-libs/duniter-dbs-read-ops/src/lib.rs b/rust-libs/duniter-dbs-read-ops/src/lib.rs
index 80708700004a97d486744ded469f0505a759ebe0..c123d2671b5a199c7433beeae4cba064874fa8a6 100644
--- a/rust-libs/duniter-dbs-read-ops/src/lib.rs
+++ b/rust-libs/duniter-dbs-read-ops/src/lib.rs
@@ -29,7 +29,7 @@ use duniter_dbs::{kv_typed::prelude::*, BlockMetaV2};
 pub fn get_current_block_meta<BcDb: BcV2DbReadable>(bc_db: &BcDb) -> KvResult<Option<BlockMetaV2>> {
     bc_db
         .blocks_meta()
-        .iter(.., |it| it.reverse().values().next_res())
+        .iter_rev(.., |it| it.values().next_res())
 }
 
 pub fn tx_exist<BcDb: BcV2DbReadable>(bc_db_ro: &BcDb, hash: Hash) -> KvResult<bool> {
diff --git a/rust-libs/duniter-dbs-write-ops/src/bc/uds.rs b/rust-libs/duniter-dbs-write-ops/src/bc/uds.rs
index a99d20a4f330bd9c691e18bc95c1e62b88fc2c31..2dde737f962df4b644ff0a1efa704358f947e935 100644
--- a/rust-libs/duniter-dbs-write-ops/src/bc/uds.rs
+++ b/rust-libs/duniter-dbs-write-ops/src/bc/uds.rs
@@ -27,7 +27,7 @@ pub(crate) fn create_uds<B: Backend>(
     uds_reval: &mut TxColRw<B::Col, UdsRevalEvent>,
 ) -> KvResult<()> {
     let previous_ud_amount = uds_reval
-        .iter(.., |it| it.reverse().values().next_res())?
+        .iter_rev(.., |it| it.values().next_res())?
         .unwrap_or(SourceAmountValV2(SourceAmount::ZERO));
     if dividend > previous_ud_amount.0 {
         uds_reval.upsert(U32BE(block_number.0), SourceAmountValV2(dividend));
@@ -50,7 +50,7 @@ pub(crate) fn revert_uds<B: Backend>(
     uds_reval: &mut TxColRw<B::Col, UdsRevalEvent>,
 ) -> KvResult<()> {
     let previous_reval_block_number = uds_reval
-        .iter(.., |it| it.reverse().keys().next_res())?
+        .iter_rev(.., |it| it.keys().next_res())?
         .expect("corrupted db")
         .0;
     if block_number.0 == previous_reval_block_number {
diff --git a/rust-libs/duniter-dbs/Cargo.toml b/rust-libs/duniter-dbs/Cargo.toml
index ae7fe8124f0a866dc0e6f4496f648bc8f3af07d7..30d02d51960137ac0f31bec862de1cc46d351031 100644
--- a/rust-libs/duniter-dbs/Cargo.toml
+++ b/rust-libs/duniter-dbs/Cargo.toml
@@ -34,7 +34,8 @@ tempdir = "0.3.7"
 unwrap = "1.2.1"
 
 [features]
-default = ["sled_backend"]
+#default = ["sled_backend"]
+default = ["sled_backend", "explorer", "leveldb_backend"]
 
 explorer = ["chrono", "kv_typed/explorer"]
 leveldb_backend = ["kv_typed/leveldb_backend"]
diff --git a/rust-libs/duniter-dbs/tests/test_read_write.rs b/rust-libs/duniter-dbs/tests/test_read_write.rs
index a878ab2c17f79f794d11d1f7a84065145b9e3e18..b1af6b37b5391ab65a12597d59a07b1febaab819 100644
--- a/rust-libs/duniter-dbs/tests/test_read_write.rs
+++ b/rust-libs/duniter-dbs/tests/test_read_write.rs
@@ -247,26 +247,21 @@ fn write_some_entries_and_iter<B: Backend>(db: &BcV1Db<B>) -> KvResult<()> {
             Ok::<(), KvError>(())
         })?;
 
-        uids_reader.iter(k2.., |entries_iter| {
-            let mut entries_iter_rev = entries_iter.reverse();
-
+        uids_reader.iter_rev(k2.., |mut entries_iter_rev| {
             assert_eq!(Some((k3, p3)), entries_iter_rev.next_res()?);
             assert_eq!(Some((k2, p2)), entries_iter_rev.next_res()?);
             assert_eq!(None, entries_iter_rev.next_res()?);
             Ok::<(), KvError>(())
         })?;
 
-        uids_reader.iter(..=k2, |entries_iter| {
-            let mut entries_iter_rev = entries_iter.reverse();
-
+        uids_reader.iter_rev(..=k2, |mut entries_iter_rev| {
             assert_eq!(Some((k2, p2)), entries_iter_rev.next_res()?);
             assert_eq!(Some((k1, p1)), entries_iter_rev.next_res()?);
             Ok::<(), KvError>(())
         })?;
 
-        uids_reader.iter(..=k2, |it| {
-            let mut keys_iter_rev = it.keys().reverse();
-
+        uids_reader.iter_rev(..=k2, |iter_rev| {
+            let mut keys_iter_rev = iter_rev.keys();
             assert_eq!(Some(k2), keys_iter_rev.next_res()?);
             assert_eq!(Some(k1), keys_iter_rev.next_res()?);
             assert_eq!(None, keys_iter_rev.next_res()?);
diff --git a/rust-libs/modules/gva/dbs-reader/src/lib.rs b/rust-libs/modules/gva/dbs-reader/src/lib.rs
index e722fa3e845b3c2a3dd275f48be0beee54d1b3a1..99676f7053dcd10620d32f117a4d8b0c3fbee39c 100644
--- a/rust-libs/modules/gva/dbs-reader/src/lib.rs
+++ b/rust-libs/modules/gva/dbs-reader/src/lib.rs
@@ -73,7 +73,7 @@ impl DbsReader {
     ) -> KvResult<Option<SourceAmount>> {
         bc_db
             .uds_reval()
-            .iter(.., |it| it.reverse().values().map_ok(|v| v.0).next_res())
+            .iter_rev(.., |it| it.values().map_ok(|v| v.0).next_res())
     }
 
     pub fn get_blockchain_time(&self, block_number: BlockNumber) -> anyhow::Result<u64> {
diff --git a/rust-libs/modules/gva/dbs-reader/src/uds_of_pubkey.rs b/rust-libs/modules/gva/dbs-reader/src/uds_of_pubkey.rs
index d54f04e65f2e12671fb9fd88f8b9ae9c7927bdc3..1033e720681c6a086941f5ff35e730f44a0c8316 100644
--- a/rust-libs/modules/gva/dbs-reader/src/uds_of_pubkey.rs
+++ b/rust-libs/modules/gva/dbs-reader/src/uds_of_pubkey.rs
@@ -54,12 +54,12 @@ impl DbsReader {
                                 })
                             } else {
                                 let last_ud_opt =
-                                    blocks_with_ud.iter(.., |it| it.keys().reverse().next_res())?;
-                                blocks_with_ud.iter(.., move |it| {
+                                    blocks_with_ud.iter_rev(.., |it| it.keys().next_res())?;
+                                blocks_with_ud.iter_rev(.., move |it| {
                                     all_uds_of_pubkey_inner::<FileBackend, _>(
                                         gva_idty,
                                         page_info,
-                                        it.keys().reverse().map_ok(|bn| BlockNumber(bn.0)),
+                                        it.keys().map_ok(|bn| BlockNumber(bn.0)),
                                         uds_reval,
                                         last_ud_opt.map(|bn| BlockNumber(bn.0)),
                                     )
@@ -79,12 +79,12 @@ impl DbsReader {
                                 })
                             } else {
                                 let last_ud_opt =
-                                    blocks_with_ud.iter(.., |it| it.keys().reverse().next_res())?;
-                                blocks_with_ud.iter(..=U32BE(pos.0), move |it| {
+                                    blocks_with_ud.iter_rev(.., |it| it.keys().next_res())?;
+                                blocks_with_ud.iter_rev(..=U32BE(pos.0), move |it| {
                                     all_uds_of_pubkey_inner::<FileBackend, _>(
                                         gva_idty,
                                         page_info,
-                                        it.keys().reverse().map_ok(|bn| BlockNumber(bn.0)),
+                                        it.keys().map_ok(|bn| BlockNumber(bn.0)),
                                         uds_reval,
                                         last_ud_opt.map(|bn| BlockNumber(bn.0)),
                                     )
@@ -127,8 +127,8 @@ impl DbsReader {
                         },
                     )?
                 } else {
-                    uds.iter(UdIdV2(pubkey, BlockNumber(0))..=UdIdV2(pubkey, pos), |it| {
-                        let it = it.keys().reverse().map_ok(|UdIdV2(_p, bn)| bn);
+                    uds.iter_rev(UdIdV2(pubkey, BlockNumber(0))..=UdIdV2(pubkey, pos), |it| {
+                        let it = it.keys().map_ok(|UdIdV2(_p, bn)| bn);
                         if let Some(bn_to_exclude) = bn_to_exclude_opt {
                             it.filter_ok(|bn| !bn_to_exclude.contains(&bn))
                                 .collect::<KvResult<Vec<_>>>()
@@ -151,10 +151,10 @@ impl DbsReader {
                     },
                 )?
             } else {
-                uds.iter(
+                uds.iter_rev(
                     UdIdV2(pubkey, BlockNumber(0))..UdIdV2(pubkey, BlockNumber(u32::MAX)),
                     |it| {
-                        let it = it.keys().reverse().map_ok(|UdIdV2(_p, bn)| bn);
+                        let it = it.keys().map_ok(|UdIdV2(_p, bn)| bn);
                         if let Some(bn_to_exclude) = bn_to_exclude_opt {
                             it.filter_ok(|bn| !bn_to_exclude.contains(&bn))
                                 .collect::<KvResult<Vec<_>>>()
@@ -177,9 +177,7 @@ impl DbsReader {
                     blocks_numbers[blocks_numbers.len() - 1]
                 };
                 let first_reval = uds_reval
-                    .iter(..=U32BE(first_block_number.0), |it| {
-                        it.reverse().keys().next_res()
-                    })?
+                    .iter_rev(..=U32BE(first_block_number.0), |it| it.keys().next_res())?
                     .expect("corrupted db");
                 let blocks_numbers_len = blocks_numbers.len();
                 let blocks_numbers = blocks_numbers.into_iter();
@@ -263,9 +261,7 @@ where
     };
 
     let first_reval = uds_reval
-        .iter(..=U32BE(first_block_number.0), |it| {
-            it.reverse().keys().next_res()
-        })?
+        .iter_rev(..=U32BE(first_block_number.0), |it| it.keys().next_res())?
         .expect("corrupted db");
 
     let uds_with_sum = if page_info.order {
@@ -377,21 +373,25 @@ fn get_first_and_last_unspent_ud<BC: BackendCol>(
     bn_to_exclude_opt: Option<&BTreeSet<BlockNumber>>,
 ) -> KvResult<(Option<BlockNumber>, Option<BlockNumber>)> {
     if let Some(bn_to_exclude) = bn_to_exclude_opt {
-        uds.iter(
-            UdIdV2(pubkey, BlockNumber(0))..UdIdV2(pubkey, BlockNumber(u32::MAX)),
-            |it| {
-                let mut it = it.keys();
-                Ok((
-                    loop {
-                        if let Some(UdIdV2(_p, bn)) = it.next_res()? {
+        Ok((
+            uds.iter(
+                UdIdV2(pubkey, BlockNumber(0))..UdIdV2(pubkey, BlockNumber(u32::MAX)),
+                |it| {
+                    it.keys()
+                        .filter_map_ok(|UdIdV2(_p, bn)| {
                             if !bn_to_exclude.contains(&bn) {
-                                break Some(bn);
+                                Some(bn)
+                            } else {
+                                None
                             }
-                        } else {
-                            break None;
-                        }
-                    },
-                    it.reverse()
+                        })
+                        .next_res()
+                },
+            )?,
+            uds.iter_rev(
+                UdIdV2(pubkey, BlockNumber(0))..UdIdV2(pubkey, BlockNumber(u32::MAX)),
+                |it| {
+                    it.keys()
                         .filter_map_ok(|UdIdV2(_p, bn)| {
                             if !bn_to_exclude.contains(&bn) {
                                 Some(bn)
@@ -399,21 +399,21 @@ fn get_first_and_last_unspent_ud<BC: BackendCol>(
                                 None
                             }
                         })
-                        .next_res()?,
-                ))
-            },
-        )
+                        .next_res()
+                },
+            )?,
+        ))
     } else {
-        uds.iter(
-            UdIdV2(pubkey, BlockNumber(0))..UdIdV2(pubkey, BlockNumber(u32::MAX)),
-            |it| {
-                let mut it = it.keys();
-                Ok((
-                    it.next_res()?.map(|UdIdV2(_p, bn)| bn),
-                    it.reverse().next_res()?.map(|UdIdV2(_p, bn)| bn),
-                ))
-            },
-        )
+        Ok((
+            uds.iter(
+                UdIdV2(pubkey, BlockNumber(0))..UdIdV2(pubkey, BlockNumber(u32::MAX)),
+                |it| it.keys().map_ok(|UdIdV2(_p, bn)| bn).next_res(),
+            )?,
+            uds.iter_rev(
+                UdIdV2(pubkey, BlockNumber(0))..UdIdV2(pubkey, BlockNumber(u32::MAX)),
+                |it| it.keys().map_ok(|UdIdV2(_p, bn)| bn).next_res(),
+            )?,
+        ))
     }
 }
 
diff --git a/rust-libs/modules/gva/dbs-reader/src/utxos.rs b/rust-libs/modules/gva/dbs-reader/src/utxos.rs
index bd1510179856896131db693b8e37aebe9a0832cb..7f316c243f24e430949e1728aa9c759b9f9eee26 100644
--- a/rust-libs/modules/gva/dbs-reader/src/utxos.rs
+++ b/rust-libs/modules/gva/dbs-reader/src/utxos.rs
@@ -106,8 +106,8 @@ impl DbsReader {
         let last_cursor_opt = if page_info.not_all() {
             self.0
                 .gva_utxos()
-                .iter(k_min..k_max, |it| {
-                    it.keys().reverse().filter_map(mempool_filter).next_res()
+                .iter_rev(k_min..k_max, |it| {
+                    it.keys().filter_map(mempool_filter).next_res()
                 })?
                 .map(|gva_utxo_id| UtxoCursor {
                     block_number: BlockNumber(gva_utxo_id.get_block_number()),
@@ -134,9 +134,17 @@ impl DbsReader {
                 );
             }
         }
-        let mut sum = SourceAmount::ZERO;
+        let UtxosWithSum { utxos, mut sum } = if page_info.order {
+            self.0.gva_utxos().iter(k_min..k_max, |it| {
+                find_script_utxos_inner(txs_mp_db_ro, amount_target_opt, page_info, it)
+            })?
+        } else {
+            self.0.gva_utxos().iter_rev(k_min..k_max, |it| {
+                find_script_utxos_inner(txs_mp_db_ro, amount_target_opt, page_info, it)
+            })?
+        };
 
-        let utxos = self.0.gva_utxos().iter(k_min..k_max, |mut it| {
+        /* let utxos = self.0.gva_utxos().iter(k_min..k_max, |mut it| {
             if !page_info.order {
                 it = it.reverse();
             }
@@ -196,42 +204,7 @@ impl DbsReader {
             } else {
                 it.collect::<KvResult<Vec<_>>>()
             }
-            /*let mut utxos = Vec::new();
-            for entry_res in it {
-                let (gva_utxo_id, SourceAmountValV2(utxo_amount)) = entry_res?;
-                let tx_hash = gva_utxo_id.get_tx_hash();
-                let output_index = gva_utxo_id.get_output_index() as u32;
-                if !txs_mp_db_ro
-                    .utxos_ids()
-                    .contains_key(&UtxoIdDbV2(tx_hash, output_index))?
-                {
-                    utxos.push((
-                        gva_db_ro
-                            .blockchain_time()
-                            .get(&U32BE(gva_utxo_id.get_block_number()))?
-                            .ok_or_else(|| {
-                                KvError::DbCorrupted(format!(
-                                    "No gva time for block {}",
-                                    gva_utxo_id.get_block_number()
-                                ))
-                            })? as i64,
-                        UtxoIdV10 {
-                            tx_hash,
-                            output_index: output_index as usize,
-                        },
-                        utxo_amount,
-                    ));
-
-                    total = total + utxo_amount;
-                    if let Some(total_target) = amount_target_opt {
-                        if total >= total_target {
-                            return Ok((utxos, total));
-                        }
-                    }
-                }
-            }
-            Ok::<_, KvError>((utxos, total))*/
-        })?;
+        })?;*/
 
         if amount_target_opt.is_none() {
             sum = utxos.iter().map(|(_utxo_id_with_bn, sa)| *sa).sum();
@@ -257,6 +230,78 @@ impl DbsReader {
     }
 }
 
+fn find_script_utxos_inner<TxsMpDb, I>(
+    txs_mp_db_ro: &TxsMpDb,
+    amount_target_opt: Option<SourceAmount>,
+    page_info: PageInfo<UtxoCursor>,
+    utxos_iter: I,
+) -> KvResult<UtxosWithSum>
+where
+    TxsMpDb: TxsMpV2DbReadable,
+    I: Iterator<Item = KvResult<(GvaUtxoIdDbV1, SourceAmountValV2)>>,
+{
+    let mut sum = SourceAmount::ZERO;
+
+    let it = utxos_iter.filter_map(|entry_res| match entry_res {
+        Ok((gva_utxo_id, SourceAmountValV2(utxo_amount))) => {
+            let tx_hash = gva_utxo_id.get_tx_hash();
+            let output_index = gva_utxo_id.get_output_index();
+            match txs_mp_db_ro
+                .utxos_ids()
+                .contains_key(&UtxoIdDbV2(tx_hash, output_index as u32))
+            {
+                Ok(false) => Some(Ok((
+                    UtxoCursor {
+                        tx_hash,
+                        output_index,
+                        block_number: BlockNumber(gva_utxo_id.get_block_number()),
+                    },
+                    utxo_amount,
+                ))),
+                Ok(true) => None,
+                Err(e) => Some(Err(e)),
+            }
+        }
+        Err(e) => Some(Err(e)),
+    });
+    let utxos = if let Some(limit) = page_info.limit_opt {
+        if let Some(total_target) = amount_target_opt {
+            it.take(limit)
+                .take_while(|res| match res {
+                    Ok((_, utxo_amount)) => {
+                        if sum < total_target {
+                            sum = sum + *utxo_amount;
+                            true
+                        } else {
+                            false
+                        }
+                    }
+                    Err(_) => true,
+                })
+                .collect::<KvResult<Vec<_>>>()?
+        } else {
+            it.take(limit).collect::<KvResult<Vec<_>>>()?
+        }
+    } else if let Some(total_target) = amount_target_opt {
+        it.take_while(|res| match res {
+            Ok((_, utxo_amount)) => {
+                if sum < total_target {
+                    sum = sum + *utxo_amount;
+                    true
+                } else {
+                    false
+                }
+            }
+            Err(_) => true,
+        })
+        .collect::<KvResult<Vec<_>>>()?
+    } else {
+        it.collect::<KvResult<Vec<_>>>()?
+    };
+
+    Ok(UtxosWithSum { utxos, sum })
+}
+
 #[cfg(test)]
 mod tests {
 
diff --git a/rust-libs/tools/kv_typed/src/backend.rs b/rust-libs/tools/kv_typed/src/backend.rs
index bafc69ab76aaed2f173a2ea24db82848ff9ab8aa..6e8688c93c09e3099d6ce2d2d07d9a02ea7ea444 100644
--- a/rust-libs/tools/kv_typed/src/backend.rs
+++ b/rust-libs/tools/kv_typed/src/backend.rs
@@ -58,6 +58,7 @@ pub trait BackendCol: 'static + Clone + Debug + Send + Sync {
     fn contains_key<K: Key>(&self, k: &K) -> KvResult<bool>;
     fn count(&self) -> KvResult<usize>;
     fn iter<K: Key, V: Value>(&self, range: RangeBytes) -> Self::Iter;
+    fn iter_rev<K: Key, V: Value>(&self, range: RangeBytes) -> Self::Iter;
     fn put<K: Key, V: Value>(&mut self, k: &K, value: &V) -> KvResult<()>;
     fn delete<K: Key>(&mut self, k: &K) -> KvResult<()>;
     fn new_batch() -> Self::Batch;
diff --git a/rust-libs/tools/kv_typed/src/backend/leveldb.rs b/rust-libs/tools/kv_typed/src/backend/leveldb.rs
index b03a712223fd9601d051c1a377c7c972deb5bdf9..7176a7fddffc71fcfac14165bcf8f2ae74201b9b 100644
--- a/rust-libs/tools/kv_typed/src/backend/leveldb.rs
+++ b/rust-libs/tools/kv_typed/src/backend/leveldb.rs
@@ -210,6 +210,10 @@ impl BackendCol for LevelDbCol {
         LevelDbIter(self.0.iter(ReadOptions::new()))
     }
     #[inline(always)]
+    fn iter_rev<K: Key, V: Value>(&self, _range: RangeBytes) -> Self::Iter {
+        LevelDbIter(self.0.iter(ReadOptions::new()).reverse())
+    }
+    #[inline(always)]
     fn save(&self) -> KvResult<()> {
         Ok(())
     }
diff --git a/rust-libs/tools/kv_typed/src/backend/memory.rs b/rust-libs/tools/kv_typed/src/backend/memory.rs
index fd3709c5c59eab6c3b1f59155c34ca701d075525..b3ec5589cae81679324b4bf4e341a59040f1d695 100644
--- a/rust-libs/tools/kv_typed/src/backend/memory.rs
+++ b/rust-libs/tools/kv_typed/src/backend/memory.rs
@@ -337,6 +337,10 @@ impl BackendCol for MemCol {
         })
     }
     #[inline(always)]
+    fn iter_rev<K: Key, V: Value>(&self, range: RangeBytes) -> Self::Iter {
+        self.iter::<K, V>(range).reverse()
+    }
+    #[inline(always)]
     fn save(&self) -> KvResult<()> {
         /*if let Some(ref file_path) = self.path {
             let bytes = Self::tree_to_bytes(&self.tree);
diff --git a/rust-libs/tools/kv_typed/src/backend/memory_singleton.rs b/rust-libs/tools/kv_typed/src/backend/memory_singleton.rs
index d77bcedda42b506b4861a5587fec26312038a3ea..200973d752061dd568183fd666e62c57d35a45f5 100644
--- a/rust-libs/tools/kv_typed/src/backend/memory_singleton.rs
+++ b/rust-libs/tools/kv_typed/src/backend/memory_singleton.rs
@@ -155,6 +155,10 @@ impl BackendCol for MemCol {
         MemIter(self.0.clone())
     }
     #[inline(always)]
+    fn iter_rev<K: Key, V: Value>(&self, _: RangeBytes) -> Self::Iter {
+        MemIter(self.0.clone())
+    }
+    #[inline(always)]
     fn save(&self) -> KvResult<()> {
         Ok(())
     }
diff --git a/rust-libs/tools/kv_typed/src/backend/sled.rs b/rust-libs/tools/kv_typed/src/backend/sled.rs
index 6efd6cb2144035c5896afa99120005d8c45ea14c..d519fa0027192b23992bd233f6cf298fa1ec04f8 100644
--- a/rust-libs/tools/kv_typed/src/backend/sled.rs
+++ b/rust-libs/tools/kv_typed/src/backend/sled.rs
@@ -163,6 +163,10 @@ impl BackendCol for SledCol {
         }
     }
     #[inline(always)]
+    fn iter_rev<K: Key, V: Value>(&self, range: RangeBytes) -> Self::Iter {
+        self.iter::<K, V>(range).reverse()
+    }
+    #[inline(always)]
     fn save(&self) -> KvResult<()> {
         self.0.flush()?;
         Ok(())
diff --git a/rust-libs/tools/kv_typed/src/collection_ro.rs b/rust-libs/tools/kv_typed/src/collection_ro.rs
index 8096e05e5b6867e656d39cb861f27545bc40ba77..485b204f6445616c67f7779a78a38ccd16caad41 100644
--- a/rust-libs/tools/kv_typed/src/collection_ro.rs
+++ b/rust-libs/tools/kv_typed/src/collection_ro.rs
@@ -28,6 +28,25 @@ pub trait DbCollectionRo: Sized {
         range: R,
         f: F,
     ) -> D;
+    /// Don't worry about complex iter type. Use it like an `impl Iterator<Item=KvResult<(K, V)>>`.
+    fn iter_rev<
+        D: Send + Sync,
+        R: 'static + RangeBounds<Self::K>,
+        F: FnOnce(
+            KvIter<
+                Self::BackendCol,
+                <Self::BackendCol as BackendCol>::KeyBytes,
+                <Self::BackendCol as BackendCol>::ValueBytes,
+                <Self::BackendCol as BackendCol>::Iter,
+                Self::K,
+                Self::V,
+            >,
+        ) -> D,
+    >(
+        &self,
+        range: R,
+        f: F,
+    ) -> D;
     fn subscribe(&self, subscriber_sender: Subscriber<Self::Event>) -> KvResult<()>;
 }
 
@@ -108,6 +127,30 @@ impl<BC: BackendCol, E: EventTrait> DbCollectionRo for ColRo<BC, E> {
         f(KvIter::new(iter, range))
     }
     #[inline(always)]
+    fn iter_rev<
+        D: Send + Sync,
+        R: 'static + RangeBounds<Self::K>,
+        F: FnOnce(
+            KvIter<
+                Self::BackendCol,
+                <Self::BackendCol as BackendCol>::KeyBytes,
+                <Self::BackendCol as BackendCol>::ValueBytes,
+                <Self::BackendCol as BackendCol>::Iter,
+                Self::K,
+                Self::V,
+            >,
+        ) -> D,
+    >(
+        &self,
+        range: R,
+        f: F,
+    ) -> D {
+        let range: RangeBytes = crate::iter::convert_range::<Self::K, R>(range);
+        let r = self.inner.read();
+        let iter = r.backend_col.iter::<Self::K, Self::V>(range.clone());
+        f(KvIter::new(iter, range).reverse())
+    }
+    #[inline(always)]
     fn subscribe(&self, subscriber_sender: Subscriber<Self::Event>) -> KvResult<()> {
         self.subscription_sender
             .try_send(subscriber_sender)
diff --git a/rust-libs/tools/kv_typed/src/explorer.rs b/rust-libs/tools/kv_typed/src/explorer.rs
index 5a86fa1daa87ced1f3ebc780b06e362f0e1e898f..1d5926db8351da880a59589e8fe46314896b2476 100644
--- a/rust-libs/tools/kv_typed/src/explorer.rs
+++ b/rust-libs/tools/kv_typed/src/explorer.rs
@@ -365,20 +365,21 @@ impl<'a> ExplorerAction<'a> {
         };
 
         if let Some(limit) = limit {
-            col.iter(range, |iter| {
-                if reverse {
-                    iter.reverse()
-                        .step_by(step.get())
+            if reverse {
+                col.iter_rev(range, |iter| {
+                    iter.step_by(step.get())
                         .filter_map(filter_map_closure)
                         .take(limit)
                         .collect()
-                } else {
+                })
+            } else {
+                col.iter(range, |iter| {
                     iter.step_by(step.get())
                         .filter_map(filter_map_closure)
                         .take(limit)
                         .collect()
-                }
-            })
+                })
+            }
         } else {
             {
                 let (send, recv) = unbounded();
@@ -389,24 +390,29 @@ impl<'a> ExplorerAction<'a> {
                     iter.filter_map(filter_map_closure).collect()
                 });
 
-                col.iter(range, |iter| {
-                    if reverse {
-                        for entry_res in iter.reverse() {
+                if reverse {
+                    col.iter_rev(range, |iter| {
+                        for entry_res in iter {
                             if send.try_send(entry_res).is_err() {
                                 return handler.join().expect("child thread panic");
                             }
                         }
-                    } else {
+                        drop(send);
+
+                        handler.join().expect("child thread panic")
+                    })
+                } else {
+                    col.iter(range, |iter| {
                         for entry_res in iter {
                             if send.try_send(entry_res).is_err() {
                                 return handler.join().expect("child thread panic");
                             }
                         }
-                    }
-                    drop(send);
+                        drop(send);
 
-                    handler.join().expect("child thread panic")
-                })
+                        handler.join().expect("child thread panic")
+                    })
+                }
             }
         }
     }
diff --git a/rust-libs/tools/kv_typed/src/lib.rs b/rust-libs/tools/kv_typed/src/lib.rs
index 0908acaaa0c563be45bfa0eed80b50fafc676edd..2a881c6b7e68ea2559c2c4e7fb7ec518d8286767 100644
--- a/rust-libs/tools/kv_typed/src/lib.rs
+++ b/rust-libs/tools/kv_typed/src/lib.rs
@@ -79,9 +79,7 @@ pub mod prelude {
     #[cfg(feature = "explorer")]
     pub use crate::explorer::{ExplorableKey, ExplorableValue};
     pub use crate::from_bytes::FromBytes;
-    pub use crate::iter::{
-        keys::KvIterKeys, values::KvIterValues, EntryIter, KvIter, ResultIter, ReversableIterator,
-    };
+    pub use crate::iter::{keys::KvIterKeys, values::KvIterValues, EntryIter, KvIter, ResultIter};
     pub use crate::key::{Key, U32BE};
     pub use crate::subscription::{NewSubscribers, Subscriber, Subscribers};
     pub use crate::transactional_read::{TransactionalRead, TxColRo};
@@ -97,7 +95,7 @@ pub(crate) use crate::collection_inner::ColInner;
 pub(crate) use crate::error::BackendResult;
 #[cfg(feature = "explorer")]
 pub(crate) use crate::explorer::{ExplorableKey, ExplorableValue};
-pub(crate) use crate::iter::RangeBytes;
+pub(crate) use crate::iter::{RangeBytes, ReversableIterator};
 pub(crate) use crate::prelude::*;
 pub(crate) use crate::subscription::{ColSubscribers, SubscriptionsSender};
 pub(crate) use crate::transactional_write::tx_iter::BackendTxIter;
diff --git a/rust-libs/tools/kv_typed/src/transactional_read.rs b/rust-libs/tools/kv_typed/src/transactional_read.rs
index e4ef0b077fab0b5e0e8290292fb6497daa64a451..94b63d4606815d5b18d35e95990a069265a006c5 100644
--- a/rust-libs/tools/kv_typed/src/transactional_read.rs
+++ b/rust-libs/tools/kv_typed/src/transactional_read.rs
@@ -57,6 +57,22 @@ impl<'db, BC: BackendCol, E: EventTrait> TxColRo<'db, BC, E> {
             .iter::<E::K, E::V>(range_bytes.clone());
         f(KvIter::new(backend_iter, range_bytes))
     }
+    #[allow(clippy::type_complexity)]
+    #[inline(always)]
+    /// Don't worry about complex iter type. Use it like an `impl Iterator<Item=KvResult<(K, V)>>`.
+    pub fn iter_rev<D, R, F>(&self, range: R, f: F) -> D
+    where
+        D: Send + Sync,
+        R: 'static + RangeBounds<E::K>,
+        F: FnOnce(KvIter<BC, BC::KeyBytes, BC::ValueBytes, BC::Iter, E::K, E::V>) -> D,
+    {
+        let range_bytes = crate::iter::convert_range::<E::K, R>(range);
+        let backend_iter = self
+            .col_reader
+            .backend_col
+            .iter::<E::K, E::V>(range_bytes.clone());
+        f(KvIter::new(backend_iter, range_bytes).reverse())
+    }
 }
 impl<'db, V: ValueZc, BC: BackendCol, E: EventTrait<V = V>> TxColRo<'db, BC, E> {
     pub fn get_ref<D, F: Fn(&V::Ref) -> KvResult<D>>(&self, k: &E::K, f: F) -> KvResult<Option<D>> {
diff --git a/rust-libs/tools/kv_typed/src/transactional_write.rs b/rust-libs/tools/kv_typed/src/transactional_write.rs
index 64b522788bdeecc4051f1464eabaf93771c3dfff..b7b4d4181871230679d6a3122a313debca46f75e 100644
--- a/rust-libs/tools/kv_typed/src/transactional_write.rs
+++ b/rust-libs/tools/kv_typed/src/transactional_write.rs
@@ -98,6 +98,35 @@ impl<'db, BC: BackendCol, E: EventTrait> TxColRw<'db, BC, E> {
             range_bytes,
         ))
     }
+    #[allow(clippy::type_complexity)]
+    #[inline(always)]
+    /// Don't worry about complex iter type. Use it like an `impl Iterator<Item=KvResult<(K, V)>>`.
+    pub fn iter_rev<'tx, D, R, F>(&'tx self, range: R, f: F) -> D
+    where
+        D: Send + Sync,
+        R: 'static + RangeBounds<E::K>,
+        F: FnOnce(
+            KvIter<
+                BC,
+                CowKB<'tx, BC::KeyBytes>,
+                CowVB<'tx, BC::ValueBytes>,
+                BackendTxIter<BC>,
+                E::K,
+                E::V,
+            >,
+        ) -> D,
+    {
+        let range_bytes = crate::iter::convert_range::<E::K, R>(range);
+        let backend_iter = self
+            .col_reader
+            .backend_col
+            .iter::<E::K, E::V>(range_bytes.clone());
+        f(KvIter::new(
+            BackendTxIter::new(backend_iter, &self.batch.tree),
+            range_bytes,
+        )
+        .reverse())
+    }
 }
 
 pub trait DbTxCollectionRw {
diff --git a/rust-libs/tools/kv_typed/tests/test_db_schema.rs b/rust-libs/tools/kv_typed/tests/test_db_schema.rs
index 75ef7c69868e3d7f2b729050275f0460f8f48d10..63f0cada21106fda528aafe03c56d834eb393dd6 100644
--- a/rust-libs/tools/kv_typed/tests/test_db_schema.rs
+++ b/rust-libs/tools/kv_typed/tests/test_db_schema.rs
@@ -90,8 +90,8 @@ fn test_db<B: Backend>(db: &TestV1Db<B>) -> KvResult<()> {
         Ok::<(), KvError>(())
     })?;
 
-    db.col1().iter(.., |it| {
-        let mut iter = it.values().reverse();
+    db.col1().iter_rev(.., |it| {
+        let mut iter = it.values();
 
         assert_eq!(iter.next_res()?, Some("tutu".to_owned()));
         assert_eq!(iter.next_res()?, Some("toto".to_owned()));
@@ -101,8 +101,8 @@ fn test_db<B: Backend>(db: &TestV1Db<B>) -> KvResult<()> {
 
     db.col1_write().upsert(7, "titi".to_owned())?;
 
-    db.col1().iter(.., |it| {
-        let mut iter = it.values().reverse().step_by(2);
+    db.col1().iter_rev(.., |it| {
+        let mut iter = it.values().step_by(2);
 
         assert_eq!(iter.next_res()?, Some("titi".to_owned()));
         assert_eq!(iter.next_res()?, Some("toto".to_owned()));
@@ -169,7 +169,7 @@ fn test_db<B: Backend>(db: &TestV1Db<B>) -> KvResult<()> {
                 vec![4, 42]
             );
             assert_eq!(
-                c3.iter(.., |it| it.reverse().keys().collect::<KvResult<Vec<_>>>())?,
+                c3.iter_rev(.., |it| it.keys().collect::<KvResult<Vec<_>>>())?,
                 vec![42, 4]
             );
             c3.upsert(8, vec![11, 12, 13]);
@@ -178,8 +178,8 @@ fn test_db<B: Backend>(db: &TestV1Db<B>) -> KvResult<()> {
                 c3.iter(.., |it| it.keys().collect::<KvResult<Vec<_>>>())?,
                 vec![8, 42]
             );
-            c3.iter(.., |it| {
-                let iter = it.reverse().keys();
+            c3.iter_rev(.., |it| {
+                let iter = it.keys();
                 r2.recv().expect("disconnected");
                 assert_eq!(iter.collect::<KvResult<Vec<_>>>()?, vec![42, 8]);