Skip to main content

dusk_node/database/rocksdb/
tx_utils.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4//
5// Copyright (c) DUSK NETWORK. All rights reserved.
6
7use super::*;
8
9enum FinalizeOp {
10    Commit,
11    Rollback,
12}
13
14impl<DB: DBAccess> Persist for DBTransaction<'_, DB> {
15    /// Deletes all items from both CF_LEDGER and CF_CANDIDATES column families
16    fn clear_database(&mut self) -> Result<()> {
17        // Create an iterator over the column family CF_LEDGER
18        let iter = self.inner.iterator_cf(self.ledger_cf, IteratorMode::Start);
19
20        // Iterate through the CF_LEDGER column family and delete all items
21        for (key, _) in iter.map(Result::unwrap) {
22            self.inner.delete_cf(self.ledger_cf, key)?;
23        }
24
25        self.clear_candidates()?;
26        self.clear_validation_results()?;
27        Ok(())
28    }
29
30    fn commit(self) -> Result<()> {
31        self.finalize(FinalizeOp::Commit)
32    }
33
34    fn rollback(self) -> Result<()> {
35        self.finalize(FinalizeOp::Rollback)
36    }
37}
38
39impl<DB: DBAccess> std::fmt::Debug for DBTransaction<'_, DB> {
40    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41        //  Print ledger blocks
42        let iter = self.inner.iterator_cf(self.ledger_cf, IteratorMode::Start);
43
44        iter.map(Result::unwrap).try_for_each(|(hash, _)| {
45            if let Ok(Some(blob)) = self.inner.get_cf(self.ledger_cf, &hash[..])
46            {
47                let b = Block::read(&mut &blob[..]).unwrap_or_default();
48                writeln!(f, "ledger_block [{}]: {:#?}", b.header().height, b)
49            } else {
50                Ok(())
51            }
52        })?;
53
54        // Print candidate blocks
55        let iter = self
56            .inner
57            .iterator_cf(self.candidates_cf, IteratorMode::Start);
58
59        let results: std::fmt::Result =
60            iter.map(Result::unwrap).try_for_each(|(hash, _)| {
61                if let Ok(Some(blob)) =
62                    self.inner.get_cf(self.candidates_cf, &hash[..])
63                {
64                    let b = Block::read(&mut &blob[..]).unwrap_or_default();
65                    writeln!(
66                        f,
67                        "candidate_block [{}]: {:#?}",
68                        b.header().height,
69                        b
70                    )
71                } else {
72                    Ok(())
73                }
74            });
75
76        results
77    }
78}
79
80impl<DB: DBAccess> DBTransaction<'_, DB> {
81    fn finalize(self, op: FinalizeOp) -> Result<()> {
82        match op {
83            FinalizeOp::Commit => self
84                .inner
85                .commit()
86                .map_err(error::RocksDbError::commit_failed)?,
87            FinalizeOp::Rollback => self
88                .inner
89                .rollback()
90                .map_err(error::RocksDbError::rollback_failed)?,
91        }
92        Ok(())
93    }
94
95    /// A thin wrapper around inner.put_cf that calculates a db transaction
96    /// disk footprint
97    pub(super) fn put_cf<K: AsRef<[u8]>, V: AsRef<[u8]>>(
98        &self,
99        cf: &impl AsColumnFamilyRef,
100        key: K,
101        value: V,
102    ) -> Result<()> {
103        let kv_size = key.as_ref().len() + value.as_ref().len();
104        self.inner.put_cf(cf, key, value)?;
105        *self.cumulative_inner_size.borrow_mut() += kv_size;
106        Ok(())
107    }
108
109    pub(super) fn get_size(&self) -> usize {
110        *self.cumulative_inner_size.borrow()
111    }
112}