Repository: lablup/rraft-py (language: python)

Issue:
`RefMutContainer` is totally not SAFE and does not perform its role
I used `RefMutContainer` for preventing SIGSEGV, SIGBUS, SystemError, race conditions and other all bugs hard to debug,
but it do not perform its role.

A simple few lines of code can simply cause SIGSEGV.

```
$ python
>>> import rraft
>>> m = rraft.Message()
>>> r = m.make_ref()
>>> # Remove original
>>> m = None
>>> # Now all r's related behaviors are undefined. 
>>> # For example, r.clear_commit() should raise DESTROYED_ERR by calling `drop` of RefMutContainer
>>> # But `drop` is not called when ref's original is removed.
>>> # Instead, It can cause SIGSEGV or keep that memory intact.
>>> # This is a completely wrong assumption.
>>> r
Message { msg_type: MsgHup, to: 0, from: 0, term: 0, log_term: 0, index: 0, entries: [], commit: 3, commit_term: 0, snapshot: None, request_snapshot: 0, reject: false, reject_hint: 0, context: [], deprecated_priority: 0, priority: 0 }
>>> r
fish: Job 1, 'python3 $argv' terminated by signal SIGSEGV (Address boundary error)
```


Discussion / hints:

Fix patch:
diff --git a/harness/src/network.py b/harness/src/network.py
index f7380c9..2fcedd7 100644
--- a/harness/src/network.py
+++ b/harness/src/network.py
@@ -5,6 +5,7 @@
     ConfState,
     Config_Ref,
     Logger,
+    Logger_Ref,
     MemStorage,
     Message,
     Message_Ref,
@@ -65,7 +66,7 @@ def default_config() -> Config:
         return cfg
 
     @staticmethod
-    def new(peers: List[Optional[Interface]], l: Logger) -> "Network":
+    def new(peers: List[Optional[Interface]], l: Logger | Logger_Ref) -> "Network":
         """
         Initializes a network from `peers`.
 
@@ -74,14 +75,13 @@ def new(peers: List[Optional[Interface]], l: Logger) -> "Network":
         A `None` node will be replaced with a new Raft node, and its configuration will
         be `peers`.
         """
-        cfg = Network.default_config()
-        return Network.new_with_config(peers, cfg, l)
+        return Network.new_with_config(peers, Network.default_config(), l)
 
     @staticmethod
     def new_with_config(
         peers: List[Optional[Interface]],
         config: Config | Config_Ref,
-        l: Logger,
+        l: Logger | Logger_Ref,
     ) -> "Network":
         """
         Initialize a network from `peers` with explicitly specified `config`.
diff --git a/rraft.pyi b/rraft.pyi
index e4c67d6..abe8e46 100644
--- a/rraft.pyi
+++ b/rraft.pyi
@@ -3246,6 +3246,9 @@ class Config_Ref(__API_Config):
 #     Reference type of :class:`Status__Memstorage`.
 #     """
 
+class DestroyedRefUsedError(Exception):
+    """ """
+
 class RaftError(Exception):
     """ """
 
diff --git a/src/bindings/config.rs b/src/bindings/config.rs
index 6c3e1c4..f0c173c 100644
--- a/src/bindings/config.rs
+++ b/src/bindings/config.rs
@@ -3,7 +3,7 @@ use pyo3::{intern, prelude::*};
 use raft::Config;
 
 use utils::implement_type_conversion;
-use utils::reference::RustRef;
+use utils::reference::{RefMutContainer, RefMutOwner};
 
 use utils::errors::Py_RaftError;
 
@@ -12,13 +12,13 @@ use super::readonly_option::Py_ReadOnlyOption;
 #[derive(Clone)]
 #[pyclass(name = "Config")]
 pub struct Py_Config {
-    pub inner: Config,
+    pub inner: RefMutOwner<Config>,
 }
 
 #[derive(Clone)]
 #[pyclass(name = "Config_Ref")]
 pub struct Py_Config_Ref {
-    pub inner: RustRef<Config>,
+    pub inner: RefMutContainer<Config>,
 }
 
 #[derive(FromPyObject)]
@@ -112,24 +112,26 @@ impl Py_Config {
         config.skip_bcast_commit = skip_bcast_commit.unwrap_or(config.skip_bcast_commit);
         config.read_only_option = read_only_option.map_or(config.read_only_option, |opt| opt.0);
 
-        Py_Config { inner: config }
+        Py_Config {
+            inner: RefMutOwner::new(config),
+        }
     }
 
     #[staticmethod]
     pub fn default() -> Py_Config {
         Py_Config {
-            inner: Config::default(),
+            inner: RefMutOwner::new(Config::default()),
         }
     }
 
     pub fn make_ref(&mut self) -> Py_Config_Ref {
         Py_Config_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
     pub fn __repr__(&self) -> String {
-        format_config(self.inner.clone())
+        format_config(self.inner.inner.clone())
     }
 
     fn __getattr__(this: PyObject, py: Python, attr: &str) -> PyResult<PyObject> {
@@ -146,7 +148,7 @@ impl Py_Config_Ref {
 
     pub fn clone(&self) -> PyResult<Py_Config> {
         Ok(Py_Config {
-            inner: self.inner.map_as_ref(|inner| inner.clone())?,
+            inner: RefMutOwner::new(self.inner.map_as_ref(|inner| inner.clone())?),
         })
     }
 
diff --git a/src/bindings/get_entries_context.rs b/src/bindings/get_entries_context.rs
index c74901b..d7a29cf 100644
--- a/src/bindings/get_entries_context.rs
+++ b/src/bindings/get_entries_context.rs
@@ -1,16 +1,15 @@
 use pyo3::{intern, prelude::*};
 use raft::GetEntriesContext;
-
-use utils::reference::RustRef;
+use utils::reference::{RefMutContainer, RefMutOwner};
 
 #[pyclass(name = "GetEntriesContext")]
 pub struct Py_GetEntriesContext {
-    pub inner: GetEntriesContext,
+    pub inner: RefMutOwner<GetEntriesContext>,
 }
 
 #[pyclass(name = "GetEntriesContext_Ref")]
 pub struct Py_GetEntriesContext_Ref {
-    pub inner: RustRef<GetEntriesContext>,
+    pub inner: RefMutContainer<GetEntriesContext>,
 }
 
 #[pymethods]
@@ -18,18 +17,18 @@ impl Py_GetEntriesContext {
     #[staticmethod]
     pub fn empty(can_async: bool) -> Self {
         Py_GetEntriesContext {
-            inner: GetEntriesContext::empty(can_async),
+            inner: RefMutOwner::new(GetEntriesContext::empty(can_async)),
         }
     }
 
     pub fn make_ref(&mut self) -> Py_GetEntriesContext_Ref {
         Py_GetEntriesContext_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
     pub fn __repr__(&self) -> String {
-        format!("{:?}", self.inner)
+        format!("{:?}", self.inner.inner)
     }
 
     fn __getattr__(this: PyObject, py: Python, attr: &str) -> PyResult<PyObject> {
diff --git a/src/bindings/global.rs b/src/bindings/global.rs
index 4d486ab..4e8e58c 100644
--- a/src/bindings/global.rs
+++ b/src/bindings/global.rs
@@ -16,6 +16,7 @@ use raftpb_bindings::message_type::{
 
 use external_bindings::slog::Py_Logger;
 use raftpb_bindings::message_type::Py_MessageType;
+use utils::reference::RefMutOwner;
 
 // Global scope functions
 #[pyfunction]
@@ -26,7 +27,7 @@ pub fn majority(total: usize) -> usize {
 #[pyfunction]
 pub fn default_logger() -> Py_Logger {
     Py_Logger {
-        inner: _default_logger(),
+        inner: RefMutOwner::new(_default_logger()),
     }
 }
 
@@ -38,7 +39,7 @@ pub fn vote_resp_msg_type(typ: &Py_MessageType) -> Py_MessageType {
 #[pyfunction]
 pub fn new_conf_change_single(node_id: u64, typ: &Py_ConfChangeType) -> Py_ConfChangeSingle {
     Py_ConfChangeSingle {
-        inner: _new_conf_change_single(node_id, typ.0),
+        inner: RefMutOwner::new(_new_conf_change_single(node_id, typ.0)),
     }
 }
 
diff --git a/src/bindings/inflights.rs b/src/bindings/inflights.rs
index 252612c..672b563 100644
--- a/src/bindings/inflights.rs
+++ b/src/bindings/inflights.rs
@@ -1,19 +1,21 @@
 use pyo3::{intern, prelude::*, pyclass::CompareOp};
 
 use raft::Inflights;
-
-use utils::{implement_type_conversion, reference::RustRef};
+use utils::{
+    implement_type_conversion,
+    reference::{RefMutContainer, RefMutOwner},
+};
 
 #[derive(Clone)]
 #[pyclass(name = "Inflights")]
 pub struct Py_Inflights {
-    pub inner: Inflights,
+    pub inner: RefMutOwner<Inflights>,
 }
 
 #[derive(Clone)]
 #[pyclass(name = "Inflights_Ref")]
 pub struct Py_Inflights_Ref {
-    pub inner: RustRef<Inflights>,
+    pub inner: RefMutContainer<Inflights>,
 }
 
 #[derive(FromPyObject)]
@@ -29,26 +31,26 @@ impl Py_Inflights {
     #[new]
     pub fn new(cap: usize) -> Self {
         Py_Inflights {
-            inner: Inflights::new(cap),
+            inner: RefMutOwner::new(Inflights::new(cap)),
         }
     }
 
     pub fn make_ref(&mut self) -> Py_Inflights_Ref {
         Py_Inflights_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
     pub fn __repr__(&self) -> String {
-        format!("{:?}", self.inner)
+        format!("{:?}", self.inner.inner)
     }
 
     pub fn __richcmp__(&self, py: Python, rhs: Py_Inflights_Mut, op: CompareOp) -> PyObject {
         let rhs: Inflights = rhs.into();
 
         match op {
-            CompareOp::Eq => (self.inner == rhs).into_py(py),
-            CompareOp::Ne => (self.inner != rhs).into_py(py),
+            CompareOp::Eq => (self.inner.inner == rhs).into_py(py),
+            CompareOp::Ne => (self.inner.inner != rhs).into_py(py),
             _ => py.NotImplemented(),
         }
     }
@@ -84,7 +86,7 @@ impl Py_Inflights_Ref {
 
     pub fn clone(&self) -> PyResult<Py_Inflights> {
         Ok(Py_Inflights {
-            inner: self.inner.map_as_ref(|inner| inner.clone())?,
+            inner: RefMutOwner::new(self.inner.map_as_ref(|inner| inner.clone())?),
         })
     }
 
diff --git a/src/bindings/joint_config.rs b/src/bindings/joint_config.rs
index fa146af..2023a1b 100644
--- a/src/bindings/joint_config.rs
+++ b/src/bindings/joint_config.rs
@@ -4,19 +4,21 @@ use pyo3::{intern, prelude::*, pyclass::CompareOp, types::PySet};
 
 use fxhash::FxHasher;
 use raft::JointConfig;
-
-use utils::{implement_type_conversion, reference::RustRef};
+use utils::{
+    implement_type_conversion,
+    reference::{RefMutContainer, RefMutOwner},
+};
 
 #[derive(Clone)]
 #[pyclass(name = "JointConfig")]
 pub struct Py_JointConfig {
-    pub inner: JointConfig,
+    pub inner: RefMutOwner<JointConfig>,
 }
 
 #[derive(Clone)]
 #[pyclass(name = "JointConfig_Ref")]
 pub struct Py_JointConfig_Ref {
-    pub inner: RustRef<JointConfig>,
+    pub inner: RefMutContainer<JointConfig>,
 }
 
 #[derive(FromPyObject)]
@@ -32,28 +34,28 @@ impl Py_JointConfig {
     #[new]
     pub fn new(voters: &PySet) -> PyResult<Self> {
         Ok(Py_JointConfig {
-            inner: JointConfig::new(
+            inner: RefMutOwner::new(JointConfig::new(
                 voters.extract::<HashSet<u64, BuildHasherDefault<FxHasher>>>()?,
-            ),
+            )),
         })
     }
 
     pub fn make_ref(&mut self) -> Py_JointConfig_Ref {
         Py_JointConfig_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
     pub fn __repr__(&self) -> String {
-        format!("{:?}", self.inner)
+        format!("{:?}", self.inner.inner)
     }
 
     pub fn __richcmp__(&self, py: Python, rhs: Py_JointConfig_Mut, op: CompareOp) -> PyObject {
         let rhs: JointConfig = rhs.into();
 
         match op {
-            CompareOp::Eq => (self.inner == rhs).into_py(py),
-            CompareOp::Ne => (self.inner != rhs).into_py(py),
+            CompareOp::Eq => (self.inner.inner == rhs).into_py(py),
+            CompareOp::Ne => (self.inner.inner != rhs).into_py(py),
             _ => py.NotImplemented(),
         }
     }
@@ -97,7 +99,7 @@ impl Py_JointConfig_Ref {
 
     pub fn clone(&self) -> PyResult<Py_JointConfig> {
         Ok(Py_JointConfig {
-            inner: self.inner.map_as_ref(|inner| inner.clone())?,
+            inner: RefMutOwner::new(self.inner.map_as_ref(|inner| inner.clone())?),
         })
     }
 
diff --git a/src/bindings/light_ready.rs b/src/bindings/light_ready.rs
index 10f7dbf..24e2b87 100644
--- a/src/bindings/light_ready.rs
+++ b/src/bindings/light_ready.rs
@@ -4,17 +4,19 @@ use raftpb_bindings::{
     entry::{Py_Entry, Py_Entry_Ref},
     message::{Py_Message, Py_Message_Ref},
 };
-use utils::reference::RustRef;
-use utils::unsafe_cast::make_mut;
+use utils::{
+    reference::{RefMutContainer, RefMutOwner},
+    unsafe_cast::make_mut,
+};
 
 #[pyclass(name = "LightReady")]
 pub struct Py_LightReady {
-    pub inner: LightReady,
+    pub inner: RefMutOwner<LightReady>,
 }
 
 #[pyclass(name = "LightReady_Ref")]
 pub struct Py_LightReady_Ref {
-    pub inner: RustRef<LightReady>,
+    pub inner: RefMutContainer<LightReady>,
 }
 
 #[pymethods]
@@ -22,18 +24,18 @@ impl Py_LightReady {
     #[staticmethod]
     pub fn default() -> Self {
         Py_LightReady {
-            inner: LightReady::default(),
+            inner: RefMutOwner::new(LightReady::default()),
         }
     }
 
     pub fn make_ref(&mut self) -> Py_LightReady_Ref {
         Py_LightReady_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
     pub fn __repr__(&self) -> String {
-        format!("{:?}", self.inner)
+        format!("{:?}", self.inner.inner)
     }
 
     fn __getattr__(this: PyObject, py: Python, attr: &str) -> PyResult<PyObject> {
@@ -58,7 +60,7 @@ impl Py_LightReady_Ref {
                 .committed_entries()
                 .iter()
                 .map(|entry| Py_Entry_Ref {
-                    inner: RustRef::new(unsafe { make_mut(entry) }),
+                    inner: RefMutContainer::new_raw(unsafe { make_mut(entry) }),
                 })
                 .collect::<Vec<_>>()
                 .into_py(py)
@@ -70,7 +72,9 @@ impl Py_LightReady_Ref {
             inner
                 .take_committed_entries()
                 .into_iter()
-                .map(|entry| Py_Entry { inner: entry })
+                .map(|entry| Py_Entry {
+                    inner: RefMutOwner::new(entry),
+                })
                 .collect::<Vec<_>>()
                 .into_py(py)
         })
@@ -82,7 +86,7 @@ impl Py_LightReady_Ref {
                 .messages()
                 .iter()
                 .map(|msg| Py_Message_Ref {
-                    inner: RustRef::new(unsafe { make_mut(msg) }),
+                    inner: RefMutContainer::new_raw(unsafe { make_mut(msg) }),
                 })
                 .collect::<Vec<_>>()
                 .into_py(py)
@@ -94,7 +98,9 @@ impl Py_LightReady_Ref {
             inner
                 .take_messages()
                 .into_iter()
-                .map(|msg| Py_Message { inner: msg })
+                .map(|msg| Py_Message {
+                    inner: RefMutOwner::new(msg),
+                })
                 .collect::<Vec<_>>()
                 .into_py(py)
         })
diff --git a/src/bindings/majority_config.rs b/src/bindings/majority_config.rs
index c20f516..5ab8882 100644
--- a/src/bindings/majority_config.rs
+++ b/src/bindings/majority_config.rs
@@ -3,19 +3,21 @@ use pyo3::{intern, prelude::*, pyclass::CompareOp, types::PySet};
 use fxhash::FxHasher;
 use raft::MajorityConfig;
 use std::{collections::HashSet, hash::BuildHasherDefault};
-
-use utils::{implement_type_conversion, reference::RustRef};
+use utils::{
+    implement_type_conversion,
+    reference::{RefMutContainer, RefMutOwner},
+};
 
 #[derive(Clone)]
 #[pyclass(name = "MajorityConfig")]
 pub struct Py_MajorityConfig {
-    pub inner: MajorityConfig,
+    pub inner: RefMutOwner<MajorityConfig>,
 }
 
 #[derive(Clone)]
 #[pyclass(name = "MajorityConfig_Ref")]
 pub struct Py_MajorityConfig_Ref {
-    pub inner: RustRef<MajorityConfig>,
+    pub inner: RefMutContainer<MajorityConfig>,
 }
 
 #[derive(FromPyObject)]
@@ -31,28 +33,28 @@ impl Py_MajorityConfig {
     #[new]
     pub fn new(voters: &PySet) -> PyResult<Self> {
         Ok(Py_MajorityConfig {
-            inner: MajorityConfig::new(
+            inner: RefMutOwner::new(MajorityConfig::new(
                 voters.extract::<HashSet<u64, BuildHasherDefault<FxHasher>>>()?,
-            ),
+            )),
         })
     }
 
     pub fn make_ref(&mut self) -> Py_MajorityConfig_Ref {
         Py_MajorityConfig_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
     pub fn __repr__(&self) -> String {
-        format!("{:?}", self.inner)
+        format!("{:?}", self.inner.inner)
     }
 
     pub fn __richcmp__(&self, py: Python, rhs: Py_MajorityConfig_Mut, op: CompareOp) -> PyObject {
         let rhs: MajorityConfig = rhs.into();
 
         match op {
-            CompareOp::Eq => (self.inner == rhs).into_py(py),
-            CompareOp::Ne => (self.inner != rhs).into_py(py),
+            CompareOp::Eq => (self.inner.inner == rhs).into_py(py),
+            CompareOp::Ne => (self.inner.inner != rhs).into_py(py),
             _ => py.NotImplemented(),
         }
     }
@@ -100,7 +102,7 @@ impl Py_MajorityConfig_Ref {
 
     pub fn clone(&self) -> PyResult<Py_MajorityConfig> {
         Ok(Py_MajorityConfig {
-            inner: self.inner.map_as_ref(|inner| inner.clone())?,
+            inner: RefMutOwner::new(self.inner.map_as_ref(|inner| inner.clone())?),
         })
     }
 
diff --git a/src/bindings/peer.rs b/src/bindings/peer.rs
index e32a6b5..dd79dd1 100644
--- a/src/bindings/peer.rs
+++ b/src/bindings/peer.rs
@@ -1,17 +1,16 @@
 use pyo3::{intern, prelude::*, types::PyBytes};
 
 use raft::raw_node::Peer;
-
-use utils::reference::RustRef;
+use utils::reference::{RefMutContainer, RefMutOwner};
 
 #[pyclass(name = "Peer")]
 pub struct Py_Peer {
-    pub inner: Peer,
+    pub inner: RefMutOwner<Peer>,
 }
 
 #[pyclass(name = "Peer_Ref")]
 pub struct Py_Peer_Ref {
-    pub inner: RustRef<Peer>,
+    pub inner: RefMutContainer<Peer>,
 }
 
 #[pymethods]
@@ -19,18 +18,18 @@ impl Py_Peer {
     #[new]
     pub fn new() -> Self {
         Py_Peer {
-            inner: Peer::default(),
+            inner: RefMutOwner::new(Peer::default()),
         }
     }
 
     pub fn make_ref(&mut self) -> Py_Peer_Ref {
         Py_Peer_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
     pub fn __repr__(&self) -> String {
-        format!("{:?}", self.inner)
+        format!("{:?}", self.inner.inner)
     }
 
     fn __getattr__(this: PyObject, py: Python, attr: &str) -> PyResult<PyObject> {
diff --git a/src/bindings/progress.rs b/src/bindings/progress.rs
index 04f503e..afe713c 100644
--- a/src/bindings/progress.rs
+++ b/src/bindings/progress.rs
@@ -1,8 +1,10 @@
 use pyo3::{intern, prelude::*, pyclass::CompareOp};
 
 use raft::Progress;
-
-use utils::{implement_type_conversion, reference::RustRef};
+use utils::{
+    implement_type_conversion,
+    reference::{RefMutContainer, RefMutOwner},
+};
 
 use super::{
     inflights::{Py_Inflights_Mut, Py_Inflights_Ref},
@@ -12,13 +14,13 @@ use super::{
 #[derive(Clone)]
 #[pyclass(name = "Progress")]
 pub struct Py_Progress {
-    pub inner: Progress,
+    pub inner: RefMutOwner<Progress>,
 }
 
 #[derive(Clone)]
 #[pyclass(name = "Progress_Ref")]
 pub struct Py_Progress_Ref {
-    pub inner: RustRef<Progress>,
+    pub inner: RefMutContainer<Progress>,
 }
 
 #[derive(FromPyObject)]
@@ -34,26 +36,26 @@ impl Py_Progress {
     #[new]
     pub fn new(next_idx: u64, ins_size: usize) -> Self {
         Py_Progress {
-            inner: Progress::new(next_idx, ins_size),
+            inner: RefMutOwner::new(Progress::new(next_idx, ins_size)),
         }
     }
 
     pub fn make_ref(&mut self) -> Py_Progress_Ref {
         Py_Progress_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
     pub fn __repr__(&self) -> String {
-        format!("{:?}", self.inner)
+        format!("{:?}", self.inner.inner)
     }
 
     pub fn __richcmp__(&self, py: Python, rhs: Py_Progress_Mut, op: CompareOp) -> PyObject {
         let rhs: Progress = rhs.into();
 
         match op {
-            CompareOp::Eq => (self.inner == rhs).into_py(py),
-            CompareOp::Ne => (self.inner != rhs).into_py(py),
+            CompareOp::Eq => (self.inner.inner == rhs).into_py(py),
+            CompareOp::Ne => (self.inner.inner != rhs).into_py(py),
             _ => py.NotImplemented(),
         }
     }
@@ -89,7 +91,7 @@ impl Py_Progress_Ref {
 
     pub fn clone(&self) -> PyResult<Py_Progress> {
         Ok(Py_Progress {
-            inner: self.inner.map_as_ref(|x| x.clone())?,
+            inner: RefMutOwner::new(self.inner.map_as_ref(|x| x.clone())?),
         })
     }
 
@@ -155,7 +157,7 @@ impl Py_Progress_Ref {
 
     pub fn get_ins(&mut self) -> PyResult<Py_Inflights_Ref> {
         self.inner.map_as_mut(|inner| Py_Inflights_Ref {
-            inner: RustRef::new(&mut inner.ins),
+            inner: RefMutContainer::new_raw(&mut inner.ins),
         })
     }
 
diff --git a/src/bindings/progress_tracker.rs b/src/bindings/progress_tracker.rs
index 84d5a13..31319cf 100644
--- a/src/bindings/progress_tracker.rs
+++ b/src/bindings/progress_tracker.rs
@@ -8,7 +8,7 @@ use pyo3::{prelude::*, types::PySet};
 use fxhash::FxHasher;
 use raft::{Progress, ProgressTracker};
 use utils::implement_type_conversion;
-use utils::reference::RustRef;
+use utils::reference::{RefMutContainer, RefMutOwner};
 use utils::unsafe_cast::{make_mut, make_static};
 
 use super::joint_config::Py_JointConfig_Ref;
@@ -17,13 +17,13 @@ use super::progress::Py_Progress_Ref;
 #[derive(Clone)]
 #[pyclass(name = "ProgressTracker")]
 pub struct Py_ProgressTracker {
-    pub inner: ProgressTracker,
+    pub inner: RefMutOwner<ProgressTracker>,
 }
 
 #[derive(Clone)]
 #[pyclass(name = "ProgressTracker_Ref")]
 pub struct Py_ProgressTracker_Ref {
-    pub inner: RustRef<ProgressTracker>,
+    pub inner: RefMutContainer<ProgressTracker>,
 }
 
 #[derive(FromPyObject)]
@@ -39,19 +39,19 @@ impl Py_ProgressTracker {
     #[new]
     pub fn new(max_inflight: usize) -> Self {
         Py_ProgressTracker {
-            inner: ProgressTracker::new(max_inflight),
+            inner: RefMutOwner::new(ProgressTracker::new(max_inflight)),
         }
     }
 
     pub fn make_ref(&mut self) -> Py_ProgressTracker_Ref {
         Py_ProgressTracker_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
     pub fn __getitem__(&self, id: u64) -> Option<Py_Progress_Ref> {
         self.inner.get(id).map(|progress| Py_Progress_Ref {
-            inner: RustRef::new(unsafe { make_mut(progress) }),
+            inner: RefMutContainer::new_raw(unsafe { make_mut(progress) }),
         })
     }
 
@@ -72,7 +72,7 @@ impl Py_ProgressMapItem {
 
     pub fn progress(&self) -> Py_Progress_Ref {
         Py_Progress_Ref {
-            inner: RustRef::new(unsafe { make_mut(self.1) }),
+            inner: RefMutContainer::new_raw(unsafe { make_mut(self.1) }),
         }
     }
 }
@@ -81,14 +81,14 @@ impl Py_ProgressMapItem {
 impl Py_ProgressTracker_Ref {
     pub fn clone(&self) -> PyResult<Py_ProgressTracker> {
         Ok(Py_ProgressTracker {
-            inner: self.inner.map_as_ref(|x| x.clone())?,
+            inner: RefMutOwner::new(self.inner.map_as_ref(|x| x.clone())?),
         })
     }
 
     pub fn __getitem__(&self, id: u64) -> PyResult<Option<Py_Progress_Ref>> {
         self.inner.map_as_ref(|inner| {
             inner.get(id).map(|progress| Py_Progress_Ref {
-                inner: RustRef::new(unsafe { make_mut(progress) }),
+                inner: RefMutContainer::new_raw(unsafe { make_mut(progress) }),
             })
         })
     }
@@ -111,7 +111,7 @@ impl Py_ProgressTracker_Ref {
     pub fn get(&self, id: u64) -> PyResult<Option<Py_Progress_Ref>> {
         self.inner.map_as_ref(|inner| {
             inner.get(id).map(|progress| Py_Progress_Ref {
-                inner: RustRef::new(unsafe { make_mut(progress) }),
+                inner: RefMutContainer::new_raw(unsafe { make_mut(progress) }),
             })
         })
     }
@@ -172,7 +172,7 @@ impl Py_ProgressTracker_Ref {
 
     pub fn conf_voters(&mut self) -> PyResult<Py_JointConfig_Ref> {
         self.inner.map_as_mut(|inner| Py_JointConfig_Ref {
-            inner: RustRef::new(unsafe { make_mut(inner.conf().voters()) }),
+            inner: RefMutContainer::new_raw(unsafe { make_mut(inner.conf().voters()) }),
         })
     }
 
diff --git a/src/bindings/raft_state.rs b/src/bindings/raft_state.rs
index 5abf514..5de3e22 100644
--- a/src/bindings/raft_state.rs
+++ b/src/bindings/raft_state.rs
@@ -1,23 +1,26 @@
 use pyo3::{intern, prelude::*};
 
 use raft::storage::RaftState;
-use utils::{implement_type_conversion, reference::RustRef};
 
 use raftpb_bindings::{
     conf_state::{Py_ConfState_Mut, Py_ConfState_Ref},
     hard_state::{Py_HardState_Mut, Py_HardState_Ref},
 };
+use utils::{
+    implement_type_conversion,
+    reference::{RefMutContainer, RefMutOwner},
+};
 
 #[derive(Clone)]
 #[pyclass(name = "RaftState")]
 pub struct Py_RaftState {
-    pub inner: RaftState,
+    pub inner: RefMutOwner<RaftState>,
 }
 
 #[derive(Clone)]
 #[pyclass(name = "RaftState_Ref")]
 pub struct Py_RaftState_Ref {
-    pub inner: RustRef<RaftState>,
+    pub inner: RefMutContainer<RaftState>,
 }
 
 #[derive(FromPyObject)]
@@ -33,25 +36,25 @@ impl Py_RaftState {
     #[new]
     pub fn new(hard_state: Py_HardState_Mut, conf_state: Py_ConfState_Mut) -> Self {
         Py_RaftState {
-            inner: RaftState::new(hard_state.into(), conf_state.into()),
+            inner: RefMutOwner::new(RaftState::new(hard_state.into(), conf_state.into())),
         }
     }
 
     #[staticmethod]
     pub fn default() -> Self {
         Py_RaftState {
-            inner: RaftState::default(),
+            inner: RefMutOwner::new(RaftState::default()),
         }
     }
 
     pub fn make_ref(&mut self) -> Py_RaftState_Ref {
         Py_RaftState_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
     pub fn __repr__(&self) -> String {
-        format!("{:?}", self.inner)
+        format!("{:?}", self.inner.inner)
     }
 
     fn __getattr__(this: PyObject, py: Python, attr: &str) -> PyResult<PyObject> {
@@ -68,7 +71,7 @@ impl Py_RaftState_Ref {
 
     pub fn clone(&self) -> PyResult<Py_RaftState> {
         Ok(Py_RaftState {
-            inner: self.inner.map_as_ref(|x| x.clone())?,
+            inner: RefMutOwner::new(self.inner.map_as_ref(|x| x.clone())?),
         })
     }
 
@@ -78,7 +81,7 @@ impl Py_RaftState_Ref {
 
     pub fn get_conf_state(&mut self) -> PyResult<Py_ConfState_Ref> {
         self.inner.map_as_mut(|inner| Py_ConfState_Ref {
-            inner: RustRef::new(&mut inner.conf_state),
+            inner: RefMutContainer::new_raw(&mut inner.conf_state),
         })
     }
 
@@ -88,7 +91,7 @@ impl Py_RaftState_Ref {
 
     pub fn get_hard_state(&mut self) -> PyResult<Py_HardState_Ref> {
         self.inner.map_as_mut(|inner| Py_HardState_Ref {
-            inner: RustRef::new(&mut inner.hard_state),
+            inner: RefMutContainer::new_raw(&mut inner.hard_state),
         })
     }
 
diff --git a/src/bindings/read_state.rs b/src/bindings/read_state.rs
index e32a44d..577206c 100644
--- a/src/bindings/read_state.rs
+++ b/src/bindings/read_state.rs
@@ -1,19 +1,21 @@
 use pyo3::{intern, prelude::*, pyclass::CompareOp, types::PyBytes};
 
 use raft::ReadState;
-
-use utils::{implement_type_conversion, reference::RustRef};
+use utils::{
+    implement_type_conversion,
+    reference::{RefMutContainer, RefMutOwner},
+};
 
 #[derive(Clone)]
 #[pyclass(name = "ReadState")]
 pub struct Py_ReadState {
-    pub inner: ReadState,
+    pub inner: RefMutOwner<ReadState>,
 }
 
 #[derive(Clone)]
 #[pyclass(name = "ReadState_Ref")]
 pub struct Py_ReadState_Ref {
-    pub inner: RustRef<ReadState>,
+    pub inner: RefMutContainer<ReadState>,
 }
 
 #[derive(FromPyObject)]
@@ -29,13 +31,13 @@ impl Py_ReadState {
     #[staticmethod]
     pub fn default() -> Self {
         Py_ReadState {
-            inner: ReadState::default(),
+            inner: RefMutOwner::new(ReadState::default()),
         }
     }
 
     pub fn make_ref(&mut self) -> Py_ReadState_Ref {
         Py_ReadState_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
@@ -46,15 +48,15 @@ impl Py_ReadState {
     }
 
     pub fn __repr__(&self) -> String {
-        format!("{:?}", self.inner)
+        format!("{:?}", self.inner.inner)
     }
 
     pub fn __richcmp__(&self, py: Python, rhs: Py_ReadState_Mut, op: CompareOp) -> PyObject {
         let rhs: ReadState = rhs.into();
 
         match op {
-            CompareOp::Eq => (self.inner == rhs).into_py(py),
-            CompareOp::Ne => (self.inner != rhs).into_py(py),
+            CompareOp::Eq => (self.inner.inner == rhs).into_py(py),
+            CompareOp::Ne => (self.inner.inner != rhs).into_py(py),
             _ => py.NotImplemented(),
         }
     }
@@ -90,7 +92,7 @@ impl Py_ReadState_Ref {
 
     pub fn clone(&self) -> PyResult<Py_ReadState> {
         Ok(Py_ReadState {
-            inner: self.inner.map_as_ref(|x| x.clone())?,
+            inner: RefMutOwner::new(self.inner.map_as_ref(|x| x.clone())?),
         })
     }
 
diff --git a/src/bindings/ready.rs b/src/bindings/ready.rs
index a96ad4f..3b23120 100644
--- a/src/bindings/ready.rs
+++ b/src/bindings/ready.rs
@@ -12,16 +12,19 @@ use super::{
     soft_state::Py_SoftState,
 };
 use raft::{raw_node::Ready, SoftState};
-use utils::{reference::RustRef, unsafe_cast::make_mut};
+use utils::{
+    reference::{RefMutContainer, RefMutOwner},
+    unsafe_cast::make_mut,
+};
 
 #[pyclass(name = "Ready")]
 pub struct Py_Ready {
-    pub inner: Ready,
+    pub inner: RefMutOwner<Ready>,
 }
 
 #[pyclass(name = "Ready_Ref")]
 pub struct Py_Ready_Ref {
-    pub inner: RustRef<Ready>,
+    pub inner: RefMutContainer<Ready>,
 }
 
 #[pymethods]
@@ -29,18 +32,18 @@ impl Py_Ready {
     #[staticmethod]
     pub fn default() -> Self {
         Py_Ready {
-            inner: Ready::default(),
+            inner: RefMutOwner::new(Ready::default()),
         }
     }
 
     pub fn make_ref(&mut self) -> Py_Ready_Ref {
         Py_Ready_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
     pub fn __repr__(&self) -> String {
-        format!("{:?}", self.inner)
+        format!("{:?}", self.inner.inner)
     }
 
     fn __getattr__(this: PyObject, py: Python, attr: &str) -> PyResult<PyObject> {
@@ -58,7 +61,7 @@ impl Py_Ready_Ref {
     pub fn hs(&mut self) -> PyResult<Option<Py_HardState_Ref>> {
         self.inner.map_as_mut(|inner| {
             inner.hs().map(|hs| Py_HardState_Ref {
-                inner: RustRef::new(unsafe { make_mut(hs) }),
+                inner: RefMutContainer::new_raw(unsafe { make_mut(hs) }),
             })
         })
     }
@@ -66,10 +69,10 @@ impl Py_Ready_Ref {
     pub fn ss(&mut self) -> PyResult<Option<Py_SoftState>> {
         self.inner.map_as_mut(|inner| {
             inner.ss().map(|ss| Py_SoftState {
-                inner: SoftState {
+                inner: RefMutOwner::new(SoftState {
                     leader_id: ss.leader_id,
                     raft_state: ss.raft_state,
-                },
+                }),
             })
         })
     }
@@ -84,7 +87,7 @@ impl Py_Ready_Ref {
 
     pub fn snapshot(&mut self) -> PyResult<Py_Snapshot_Ref> {
         self.inner.map_as_mut(|inner| Py_Snapshot_Ref {
-            inner: RustRef::new(unsafe { make_mut(inner.snapshot()) }),
+            inner: RefMutContainer::new_raw(unsafe { make_mut(inner.snapshot()) }),
         })
     }
 
@@ -93,7 +96,7 @@ impl Py_Ready_Ref {
             unsafe { make_mut(inner.committed_entries()) }
                 .iter_mut()
                 .map(|entry| Py_Entry_Ref {
-                    inner: RustRef::new(entry),
+                    inner: RefMutContainer::new_raw(entry),
                 })
                 .collect::<Vec<_>>()
                 .into_py(py)
@@ -105,7 +108,9 @@ impl Py_Ready_Ref {
             inner
                 .take_committed_entries()
                 .into_iter()
-                .map(|entry| Py_Entry { inner: entry })
+                .map(|entry| Py_Entry {
+                    inner: RefMutOwner::new(entry),
+                })
                 .collect::<Vec<_>>()
                 .into_py(py)
         })
@@ -116,7 +121,7 @@ impl Py_Ready_Ref {
             unsafe { make_mut(inner.entries()) }
                 .iter_mut()
                 .map(|entry| Py_Entry_Ref {
-                    inner: RustRef::new(entry),
+                    inner: RefMutContainer::new_raw(entry),
                 })
                 .collect::<Vec<_>>()
                 .into_py(py)
@@ -128,7 +133,9 @@ impl Py_Ready_Ref {
             inner
                 .take_entries()
                 .into_iter()
-                .map(|entry| Py_Entry { inner: entry })
+                .map(|entry| Py_Entry {
+                    inner: RefMutOwner::new(entry),
+                })
                 .collect::<Vec<_>>()
                 .into_py(py)
         })
@@ -140,7 +147,7 @@ impl Py_Ready_Ref {
                 .messages()
                 .iter()
                 .map(|msg| Py_Message_Ref {
-                    inner: RustRef::new(unsafe { make_mut(msg) }),
+                    inner: RefMutContainer::new_raw(unsafe { make_mut(msg) }),
                 })
                 .collect::<Vec<_>>()
                 .into_py(py)
@@ -152,7 +159,9 @@ impl Py_Ready_Ref {
             inner
                 .take_messages()
                 .into_iter()
-                .map(|msg| Py_Message { inner: msg })
+                .map(|msg| Py_Message {
+                    inner: RefMutOwner::new(msg),
+                })
                 .collect::<Vec<_>>()
                 .into_py(py)
         })
@@ -164,7 +173,7 @@ impl Py_Ready_Ref {
                 .persisted_messages()
                 .iter()
                 .map(|msg| Py_Message_Ref {
-                    inner: RustRef::new(unsafe { make_mut(msg) }),
+                    inner: RefMutContainer::new_raw(unsafe { make_mut(msg) }),
                 })
                 .collect::<Vec<_>>()
                 .into_py(py)
@@ -176,7 +185,9 @@ impl Py_Ready_Ref {
             inner
                 .take_persisted_messages()
                 .into_iter()
-                .map(|msg| Py_Message { inner: msg })
+                .map(|msg| Py_Message {
+                    inner: RefMutOwner::new(msg),
+                })
                 .collect::<Vec<_>>()
                 .into_py(py)
         })
@@ -188,7 +199,7 @@ impl Py_Ready_Ref {
                 .read_states()
                 .iter()
                 .map(|rs| Py_ReadState_Ref {
-                    inner: RustRef::new(unsafe { make_mut(rs) }),
+                    inner: RefMutContainer::new_raw(unsafe { make_mut(rs) }),
                 })
                 .collect::<Vec<_>>()
                 .into_py(py)
@@ -200,7 +211,9 @@ impl Py_Ready_Ref {
             inner
                 .take_read_states()
                 .into_iter()
-                .map(|rs| Py_ReadState { inner: rs })
+                .map(|rs| Py_ReadState {
+                    inner: RefMutOwner::new(rs),
+                })
                 .collect::<Vec<_>>()
                 .into_py(py)
         })
diff --git a/src/bindings/soft_state.rs b/src/bindings/soft_state.rs
index fc91180..e33258d 100644
--- a/src/bindings/soft_state.rs
+++ b/src/bindings/soft_state.rs
@@ -1,19 +1,18 @@
 use pyo3::{intern, prelude::*, pyclass::CompareOp};
 
 use raft::SoftState;
-
-use utils::reference::RustRef;
+use utils::reference::{RefMutContainer, RefMutOwner};
 
 use super::state_role::Py_StateRole;
 
 #[pyclass(name = "SoftState")]
 pub struct Py_SoftState {
-    pub inner: SoftState,
+    pub inner: RefMutOwner<SoftState>,
 }
 
 #[pyclass(name = "SoftState_Ref")]
 pub struct Py_SoftState_Ref {
-    pub inner: RustRef<SoftState>,
+    pub inner: RefMutContainer<SoftState>,
 }
 
 #[pymethods]
@@ -21,18 +20,18 @@ impl Py_SoftState {
     #[staticmethod]
     pub fn default() -> Self {
         Py_SoftState {
-            inner: SoftState::default(),
+            inner: RefMutOwner::new(SoftState::default()),
         }
     }
 
     pub fn make_ref(&mut self) -> Py_SoftState_Ref {
         Py_SoftState_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
     pub fn __repr__(&self) -> String {
-        format!("{:?}", self.inner)
+        format!("{:?}", self.inner.inner)
     }
 
     pub fn __richcmp__(
@@ -42,8 +41,12 @@ impl Py_SoftState {
         op: CompareOp,
     ) -> PyResult<PyObject> {
         match op {
-            CompareOp::Eq => rhs.inner.map_as_ref(|x| (x == &self.inner).into_py(py)),
-            CompareOp::Ne => rhs.inner.map_as_ref(|x| (x != &self.inner).into_py(py)),
+            CompareOp::Eq => rhs
+                .inner
+                .map_as_ref(|x| (x == &self.inner.inner).into_py(py)),
+            CompareOp::Ne => rhs
+                .inner
+                .map_as_ref(|x| (x != &self.inner.inner).into_py(py)),
             _ => Ok(py.NotImplemented()),
         }
     }
diff --git a/src/bindings/unstable.rs b/src/bindings/unstable.rs
index 812255d..a7bb3ab 100644
--- a/src/bindings/unstable.rs
+++ b/src/bindings/unstable.rs
@@ -1,24 +1,25 @@
 use pyo3::{intern, prelude::*, types::PyList};
 
-use external_bindings::slog::{Py_Logger_Mut, Py_Logger_Ref};
+use external_bindings::slog::Py_Logger_Mut;
 use raftpb_bindings::{
     entry::{Py_Entry_Mut, Py_Entry_Ref},
     snapshot::{Py_Snapshot_Mut, Py_Snapshot_Ref},
 };
 
 use raft::Unstable;
-use utils::unsafe_cast::make_mut;
-
-use utils::reference::RustRef;
+use utils::{
+    reference::{RefMutContainer, RefMutOwner},
+    unsafe_cast::make_mut,
+};
 
 #[pyclass(name = "Unstable")]
 pub struct Py_Unstable {
-    pub inner: Unstable,
+    pub inner: RefMutOwner<Unstable>,
 }
 
 #[pyclass(name = "Unstable_Ref")]
 pub struct Py_Unstable_Ref {
-    pub inner: RustRef<Unstable>,
+    pub inner: RefMutContainer<Unstable>,
 }
 
 #[pymethods]
@@ -26,18 +27,18 @@ impl Py_Unstable {
     #[new]
     pub fn new(offset: u64, logger: Py_Logger_Mut) -> Self {
         Py_Unstable {
-            inner: Unstable::new(offset, logger.into()),
+            inner: RefMutOwner::new(Unstable::new(offset, logger.into())),
         }
     }
 
     pub fn make_ref(&mut self) -> Py_Unstable_Ref {
         Py_Unstable_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
     pub fn __repr__(&self) -> String {
-        format!("{:?}", self.inner)
+        format!("{:?}", self.inner.inner)
     }
 
     fn __getattr__(this: PyObject, py: Python, attr: &str) -> PyResult<PyObject> {
@@ -75,7 +76,7 @@ impl Py_Unstable_Ref {
                 .slice(lo, hi)
                 .iter()
                 .map(|entry| Py_Entry_Ref {
-                    inner: RustRef::new(unsafe { make_mut(entry) }),
+                    inner: RefMutContainer::new_raw(unsafe { make_mut(entry) }),
                 })
                 .collect::<Vec<_>>()
                 .into_py(py)
@@ -132,7 +133,7 @@ impl Py_Unstable_Ref {
                 .entries
                 .iter_mut()
                 .map(|entry| Py_Entry_Ref {
-                    inner: RustRef::new(entry),
+                    inner: RefMutContainer::new_raw(entry),
                 })
                 .collect::<Vec<_>>()
                 .into_py(py)
@@ -147,11 +148,11 @@ impl Py_Unstable_Ref {
         })
     }
 
-    pub fn get_logger(&mut self) -> PyResult<Py_Logger_Ref> {
-        self.inner.map_as_mut(|inner| Py_Logger_Ref {
-            inner: RustRef::new(&mut inner.logger),
-        })
-    }
+    // pub fn get_logger(&mut self) -> PyResult<Py_Logger_Ref> {
+    //     self.inner.map_as_mut(|inner| Py_Logger_Ref {
+    //         inner: RefMutContainer::new(&mut inner.logger),
+    //     })
+    // }
 
     pub fn set_logger(&mut self) -> PyResult<()> {
         todo!()
@@ -160,7 +161,7 @@ impl Py_Unstable_Ref {
     pub fn get_snapshot(&mut self) -> PyResult<Option<Py_Snapshot_Ref>> {
         self.inner.map_as_mut(|inner| {
             inner.snapshot.as_ref().map(|snapshot| Py_Snapshot_Ref {
-                inner: RustRef::new(unsafe { make_mut(snapshot) }),
+                inner: RefMutContainer::new_raw(unsafe { make_mut(snapshot) }),
             })
         })
     }
diff --git a/src/external_bindings/slog.rs b/src/external_bindings/slog.rs
index 57f04ab..c8950ef 100644
--- a/src/external_bindings/slog.rs
+++ b/src/external_bindings/slog.rs
@@ -2,7 +2,10 @@ use pyo3::{intern, prelude::*, types::PyString};
 use slog::*;
 use slog_async::OverflowStrategy;
 
-use utils::{implement_type_conversion, reference::RustRef};
+use utils::{
+    implement_type_conversion,
+    reference::{RefMutContainer, RefMutOwner},
+};
 
 #[pyclass(name = "OverflowStrategy")]
 pub struct Py_OverflowStrategy(pub OverflowStrategy);
@@ -52,13 +55,13 @@ impl Py_OverflowStrategy {
 #[derive(Clone)]
 #[pyclass(name = "Logger")]
 pub struct Py_Logger {
-    pub inner: Logger,
+    pub inner: RefMutOwner<Logger>,
 }
 
 #[derive(Clone)]
 #[pyclass(name = "Logger_Ref")]
 pub struct Py_Logger_Ref {
-    pub inner: RustRef<Logger>,
+    pub inner: RefMutContainer<Logger>,
 }
 
 #[derive(FromPyObject)]
@@ -83,12 +86,14 @@ impl Py_Logger {
 
         let logger = slog::Logger::root(drain, o!());
 
-        Py_Logger { inner: logger }
+        Py_Logger {
+            inner: RefMutOwner::new(logger),
+        }
     }
 
     pub fn make_ref(&mut self) -> Py_Logger_Ref {
         Py_Logger_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
diff --git a/src/lib.rs b/src/lib.rs
index 4f03b3e..d0badcd 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,4 +1,3 @@
-use bindings::global::add_constants;
 use pyo3::prelude::*;
 
 #[pymodule]
@@ -96,6 +95,11 @@ fn rraft(py: Python, m: &PyModule) -> PyResult<()> {
         m
     )?)?;
 
+    m.add(
+        "DestroyedRefUsedError",
+        py.get_type::<utils::errors::DestroyedRefUsedError>(),
+    )?;
+
     m.add("RaftError", py.get_type::<utils::errors::RaftError>())?;
     m.add(
         "RaftStorageError",
@@ -156,7 +160,7 @@ fn rraft(py: Python, m: &PyModule) -> PyResult<()> {
         py.get_type::<utils::errors::RequestSnapshotDroppedError>(),
     )?;
 
-    add_constants(m)?;
+    bindings::global::add_constants(m)?;
 
     Ok(())
 }
diff --git a/src/mem_storage_bindings/mem_storage.rs b/src/mem_storage_bindings/mem_storage.rs
index e0e16ee..e3e858f 100644
--- a/src/mem_storage_bindings/mem_storage.rs
+++ b/src/mem_storage_bindings/mem_storage.rs
@@ -4,7 +4,10 @@ use pyo3::{intern, prelude::*};
 
 use raft::{prelude::ConfState, storage::MemStorage, storage::Storage, GetEntriesContext};
 use utils::{
-    errors::Py_RaftError, implement_type_conversion, reference::RustRef, unsafe_cast::make_mut,
+    errors::Py_RaftError,
+    implement_type_conversion,
+    reference::{RefMutContainer, RefMutOwner},
+    unsafe_cast::make_mut,
 };
 
 use raftpb_bindings::{conf_state::Py_ConfState_Mut, entry::Py_Entry, snapshot::Py_Snapshot};
@@ -16,13 +19,13 @@ use bindings::{get_entries_context::Py_GetEntriesContext_Ref, raft_state::Py_Raf
 #[derive(Clone)]
 #[pyclass(name = "MemStorage")]
 pub struct Py_MemStorage {
-    pub inner: MemStorage,
+    pub inner: RefMutOwner<MemStorage>,
 }
 
 #[derive(Clone)]
 #[pyclass(name = "MemStorage_Ref")]
 pub struct Py_MemStorage_Ref {
-    pub inner: RustRef<MemStorage>,
+    pub inner: RefMutContainer<MemStorage>,
 }
 
 #[derive(FromPyObject)]
@@ -38,27 +41,27 @@ impl Py_MemStorage {
     #[new]
     pub fn new() -> Self {
         Py_MemStorage {
-            inner: MemStorage::new(),
+            inner: RefMutOwner::new(MemStorage::new()),
         }
     }
 
     #[staticmethod]
     pub fn default() -> Self {
         Py_MemStorage {
-            inner: MemStorage::default(),
+            inner: RefMutOwner::new(MemStorage::default()),
         }
     }
 
     #[staticmethod]
     pub fn new_with_conf_state(cs: Py_ConfState_Mut) -> Self {
         Py_MemStorage {
-            inner: MemStorage::new_with_conf_state::<ConfState>(cs.into()),
+            inner: RefMutOwner::new(MemStorage::new_with_conf_state::<ConfState>(cs.into())),
         }
     }
 
     pub fn make_ref(&mut self) -> Py_MemStorage_Ref {
         Py_MemStorage_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
@@ -72,7 +75,7 @@ impl Py_MemStorage {
 impl Py_MemStorage_Ref {
     pub fn clone(&mut self) -> PyResult<Py_MemStorage> {
         Ok(Py_MemStorage {
-            inner: self.inner.map_as_mut(|x| x.clone())?,
+            inner: RefMutOwner::new(self.inner.map_as_mut(|x| x.clone())?),
         })
     }
 
@@ -85,7 +88,9 @@ impl Py_MemStorage_Ref {
         self.inner.map_as_ref(|inner| {
             inner
                 .initial_state()
-                .map(|state| Py_RaftState { inner: state })
+                .map(|state| Py_RaftState {
+                    inner: RefMutOwner::new(state),
+                })
                 .map_err(|e| Py_RaftError(e).into())
         })?
     }
@@ -109,7 +114,9 @@ impl Py_MemStorage_Ref {
         self.inner.map_as_ref(|inner| {
             inner
                 .snapshot(request_index, _to)
-                .map(|snapshot| Py_Snapshot { inner: snapshot })
+                .map(|snapshot| Py_Snapshot {
+                    inner: RefMutOwner::new(snapshot),
+                })
                 .map_err(|e| Py_RaftError(e).into())
         })?
     }
@@ -132,7 +139,9 @@ impl Py_MemStorage_Ref {
                 .map(|entries| {
                     entries
                         .into_iter()
-                        .map(|entry| Py_Entry { inner: entry })
+                        .map(|entry| Py_Entry {
+                            inner: RefMutOwner::new(entry),
+                        })
                         .collect::<Vec<_>>()
                         .into_py(py)
                 })
@@ -142,13 +151,13 @@ impl Py_MemStorage_Ref {
 
     pub fn wl(&mut self) -> PyResult<Py_MemStorageCore_Ref> {
         self.inner.map_as_mut(|inner| Py_MemStorageCore_Ref {
-            inner: RustRef::new(inner.wl().deref_mut()),
+            inner: RefMutContainer::new_raw(inner.wl().deref_mut()),
         })
     }
 
     pub fn rl(&self) -> PyResult<Py_MemStorageCore_Ref> {
         self.inner.map_as_ref(|inner| Py_MemStorageCore_Ref {
-            inner: RustRef::new(unsafe { make_mut(inner.rl().deref()) }),
+            inner: RefMutContainer::new_raw(unsafe { make_mut(inner.rl().deref()) }),
         })
     }
 }
diff --git a/src/mem_storage_bindings/mem_storage_core.rs b/src/mem_storage_bindings/mem_storage_core.rs
index 40932a6..8843a0a 100644
--- a/src/mem_storage_bindings/mem_storage_core.rs
+++ b/src/mem_storage_bindings/mem_storage_core.rs
@@ -2,7 +2,10 @@ use bindings::get_entries_context::Py_GetEntriesContext;
 use pyo3::{intern, prelude::*, types::PyList};
 
 use raft::storage::MemStorageCore;
-use utils::{errors::Py_RaftError, reference::RustRef};
+use utils::{
+    errors::Py_RaftError,
+    reference::{RefMutContainer, RefMutOwner},
+};
 
 use raftpb_bindings::{
     conf_state::Py_ConfState_Mut,
@@ -13,12 +16,12 @@ use raftpb_bindings::{
 
 #[pyclass(name = "MemStorageCore")]
 pub struct Py_MemStorageCore {
-    pub inner: MemStorageCore,
+    pub inner: RefMutOwner<MemStorageCore>,
 }
 
 #[pyclass(name = "MemStorageCore_Ref")]
 pub struct Py_MemStorageCore_Ref {
-    pub inner: RustRef<MemStorageCore>,
+    pub inner: RefMutContainer<MemStorageCore>,
 }
 
 #[pymethods]
@@ -26,13 +29,13 @@ impl Py_MemStorageCore {
     #[staticmethod]
     pub fn default() -> Self {
         Py_MemStorageCore {
-            inner: MemStorageCore::default(),
+            inner: RefMutOwner::new(MemStorageCore::default()),
         }
     }
 
     pub fn make_ref(&mut self) -> Py_MemStorageCore_Ref {
         Py_MemStorageCore_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
@@ -97,7 +100,7 @@ impl Py_MemStorageCore_Ref {
 
     pub fn hard_state(&mut self) -> PyResult<Py_HardState_Ref> {
         self.inner.map_as_mut(|inner| Py_HardState_Ref {
-            inner: RustRef::new(inner.mut_hard_state()),
+            inner: RefMutContainer::new_raw(inner.mut_hard_state()),
         })
     }
 
@@ -125,7 +128,9 @@ impl Py_MemStorageCore_Ref {
         self.inner.map_as_mut(|inner| {
             inner
                 .take_get_entries_context()
-                .map(|ctx| Py_GetEntriesContext { inner: ctx })
+                .map(|ctx| Py_GetEntriesContext {
+                    inner: RefMutOwner::new(ctx),
+                })
         })
     }
 }
diff --git a/src/mem_storage_bindings/raft.rs b/src/mem_storage_bindings/raft.rs
index 1a3ddf6..fac7789 100644
--- a/src/mem_storage_bindings/raft.rs
+++ b/src/mem_storage_bindings/raft.rs
@@ -3,7 +3,10 @@ use pyo3::{
     prelude::*,
     types::{PyList, PyString},
 };
-use utils::{reference::RustRef, unsafe_cast::make_mut};
+use utils::{
+    reference::{RefMutContainer, RefMutOwner},
+    unsafe_cast::make_mut,
+};
 
 use raft::{
     storage::MemStorage, Raft, CAMPAIGN_ELECTION, CAMPAIGN_PRE_ELECTION, CAMPAIGN_TRANSFER,
@@ -35,12 +38,12 @@ use super::mem_storage::{Py_MemStorage_Mut, Py_MemStorage_Ref};
 
 #[pyclass(name = "InMemoryRaft")]
 pub struct Py_InMemoryRaft {
-    pub inner: Raft<MemStorage>,
+    pub inner: RefMutOwner<Raft<MemStorage>>,
 }
 
 #[pyclass(name = "InMemoryRaft_Ref")]
 pub struct Py_InMemoryRaft_Ref {
-    pub inner: RustRef<Raft<MemStorage>>,
+    pub inner: RefMutContainer<Raft<MemStorage>>,
 }
 
 #[pymethods]
@@ -52,13 +55,15 @@ impl Py_InMemoryRaft {
         logger: Py_Logger_Mut,
     ) -> PyResult<Self> {
         Raft::new(&cfg.into(), store.into(), &logger.into())
-            .map(|r| Py_InMemoryRaft { inner: r })
+            .map(|r| Py_InMemoryRaft {
+                inner: RefMutOwner::new(r),
+            })
             .map_err(|e| Py_RaftError(e).into())
     }
 
     pub fn make_ref(&mut self) -> Py_InMemoryRaft_Ref {
         Py_InMemoryRaft_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
@@ -259,13 +264,13 @@ impl Py_InMemoryRaft_Ref {
 
     pub fn soft_state(&self) -> PyResult<Py_SoftState> {
         self.inner.map_as_ref(|inner| Py_SoftState {
-            inner: inner.soft_state(),
+            inner: RefMutOwner::new(inner.soft_state()),
         })
     }
 
     pub fn hard_state(&self) -> PyResult<Py_HardState> {
         self.inner.map_as_ref(|inner| Py_HardState {
-            inner: inner.hard_state(),
+            inner: RefMutOwner::new(inner.hard_state()),
         })
     }
 
@@ -278,7 +283,7 @@ impl Py_InMemoryRaft_Ref {
             inner
                 .apply_conf_change(&cc.into())
                 .map(|cs| Py_ConfState_Ref {
-                    inner: RustRef::new(unsafe { make_mut(&cs) }),
+                    inner: RefMutContainer::new_raw(unsafe { make_mut(&cs) }),
                 })
                 .map_err(|e| Py_RaftError(e).into())
         })?
@@ -307,7 +312,7 @@ impl Py_InMemoryRaft_Ref {
 
     pub fn post_conf_change(&mut self) -> PyResult<Py_ConfState_Ref> {
         self.inner.map_as_mut(|inner| Py_ConfState_Ref {
-            inner: RustRef::new(&mut inner.post_conf_change()),
+            inner: RefMutContainer::new_raw(&mut inner.post_conf_change()),
         })
     }
 
@@ -332,7 +337,7 @@ impl Py_InMemoryRaft_Ref {
 
     pub fn prs(&mut self) -> PyResult<Py_ProgressTracker_Ref> {
         self.inner.map_as_mut(|inner| Py_ProgressTracker_Ref {
-            inner: RustRef::new(inner.mut_prs()),
+            inner: RefMutContainer::new_raw(inner.mut_prs()),
         })
     }
 
@@ -343,7 +348,7 @@ impl Py_InMemoryRaft_Ref {
     pub fn snap(&self) -> PyResult<Option<Py_Snapshot_Ref>> {
         self.inner.map_as_ref(|inner| {
             inner.snap().map(|snapshot| Py_Snapshot_Ref {
-                inner: RustRef::new(unsafe { make_mut(snapshot) }),
+                inner: RefMutContainer::new_raw(unsafe { make_mut(snapshot) }),
             })
         })
     }
@@ -408,7 +413,9 @@ impl Py_InMemoryRaft_Ref {
             inner
                 .read_states
                 .iter()
-                .map(|rs| Py_ReadState { inner: rs.clone() })
+                .map(|rs| Py_ReadState {
+                    inner: RefMutOwner::new(rs.clone()),
+                })
                 .collect::<Vec<_>>()
                 .into_py(py)
         })
@@ -473,7 +480,7 @@ impl Py_InMemoryRaft_Ref {
                 .msgs
                 .iter_mut()
                 .map(|msg| Py_Message_Ref {
-                    inner: RustRef::new(msg),
+                    inner: RefMutContainer::new_raw(msg),
                 })
                 .collect::<Vec<_>>()
                 .into_py(py)
@@ -493,7 +500,9 @@ impl Py_InMemoryRaft_Ref {
             let msgs = inner.msgs.drain(..).collect::<Vec<_>>();
 
             msgs.into_iter()
-                .map(|msg| Py_Message { inner: msg })
+                .map(|msg| Py_Message {
+                    inner: RefMutOwner::new(msg),
+                })
                 .collect::<Vec<_>>()
                 .into_py(py)
         })
@@ -501,7 +510,7 @@ impl Py_InMemoryRaft_Ref {
 
     pub fn get_raft_log(&mut self) -> PyResult<Py_InMemoryRaftLog_Ref> {
         self.inner.map_as_mut(|inner| Py_InMemoryRaftLog_Ref {
-            inner: RustRef::new(&mut inner.raft_log),
+            inner: RefMutContainer::new_raw(&mut inner.raft_log),
         })
     }
 
@@ -539,7 +548,7 @@ impl Py_InMemoryRaft_Ref {
 
     pub fn store(&mut self) -> PyResult<Py_MemStorage_Ref> {
         self.inner.map_as_mut(|inner| Py_MemStorage_Ref {
-            inner: RustRef::new(inner.mut_store()),
+            inner: RefMutContainer::new_raw(inner.mut_store()),
         })
     }
 
diff --git a/src/mem_storage_bindings/raft_log.rs b/src/mem_storage_bindings/raft_log.rs
index c890856..63b3718 100644
--- a/src/mem_storage_bindings/raft_log.rs
+++ b/src/mem_storage_bindings/raft_log.rs
@@ -2,6 +2,7 @@ use bindings::get_entries_context::Py_GetEntriesContext_Ref;
 use pyo3::types::PyList;
 use pyo3::{intern, prelude::*};
 use utils::errors::Py_RaftError;
+use utils::reference::{RefMutContainer, RefMutOwner};
 use utils::unsafe_cast::make_mut;
 
 use external_bindings::slog::Py_Logger_Mut;
@@ -10,19 +11,18 @@ use raftpb_bindings::snapshot::{Py_Snapshot_Mut, Py_Snapshot_Ref};
 use super::mem_storage::{Py_MemStorage_Mut, Py_MemStorage_Ref};
 use raft::RaftLog;
 use raft::{storage::MemStorage, GetEntriesContext};
-use utils::reference::RustRef;
 
 use bindings::unstable::Py_Unstable_Ref;
 use raftpb_bindings::entry::{Py_Entry, Py_Entry_Mut, Py_Entry_Ref};
 
 #[pyclass(name = "InMemoryRaftLog")]
 pub struct Py_InMemoryRaftLog {
-    pub inner: RaftLog<MemStorage>,
+    pub inner: RefMutOwner<RaftLog<MemStorage>>,
 }
 
 #[pyclass(name = "InMemoryRaftLog_Ref")]
 pub struct Py_InMemoryRaftLog_Ref {
-    pub inner: RustRef<RaftLog<MemStorage>>,
+    pub inner: RefMutContainer<RaftLog<MemStorage>>,
 }
 
 #[pymethods]
@@ -30,13 +30,13 @@ impl Py_InMemoryRaftLog {
     #[new]
     pub fn new(store: Py_MemStorage_Mut, logger: Py_Logger_Mut) -> Self {
         Py_InMemoryRaftLog {
-            inner: RaftLog::new(store.into(), logger.into()),
+            inner: RefMutOwner::new(RaftLog::new(store.into(), logger.into())),
         }
     }
 
     pub fn make_ref(&mut self) -> Py_InMemoryRaftLog_Ref {
         Py_InMemoryRaftLog_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
@@ -74,7 +74,9 @@ impl Py_InMemoryRaftLog_Ref {
                 .map(|entries| {
                     entries
                         .into_iter()
-                        .map(|entry| Py_Entry { inner: entry })
+                        .map(|entry| Py_Entry {
+                            inner: RefMutOwner::new(entry),
+                        })
                         .collect::<Vec<_>>()
                         .into_py(py)
                 })
@@ -87,7 +89,9 @@ impl Py_InMemoryRaftLog_Ref {
             inner
                 .all_entries()
                 .into_iter()
-                .map(|entry| Py_Entry { inner: entry })
+                .map(|entry| Py_Entry {
+                    inner: RefMutOwner::new(entry),
+                })
                 .collect::<Vec<_>>()
                 .into_py(py)
         })
@@ -98,7 +102,9 @@ impl Py_InMemoryRaftLog_Ref {
             inner.next_entries(max_size).map(|entries| {
                 entries
                     .into_iter()
-                    .map(|entry| Py_Entry { inner: entry })
+                    .map(|entry| Py_Entry {
+                        inner: RefMutOwner::new(entry),
+                    })
                     .collect::<Vec<_>>()
                     .into_py(py)
             })
@@ -117,7 +123,9 @@ impl Py_InMemoryRaftLog_Ref {
                 .map(|entries| {
                     entries
                         .into_iter()
-                        .map(|entry| Py_Entry { inner: entry })
+                        .map(|entry| Py_Entry {
+                            inner: RefMutOwner::new(entry),
+                        })
                         .collect::<Vec<_>>()
                         .into_py(py)
                 })
@@ -226,7 +234,7 @@ impl Py_InMemoryRaftLog_Ref {
             inner
                 .snapshot(request_index, to)
                 .map(|mut snapshot| Py_Snapshot_Ref {
-                    inner: RustRef::new(&mut snapshot),
+                    inner: RefMutContainer::new_raw(&mut snapshot),
                 })
                 .map_err(|e| Py_RaftError(e).into())
         })?
@@ -264,7 +272,7 @@ impl Py_InMemoryRaftLog_Ref {
 
     pub fn unstable(&self) -> PyResult<Py_Unstable_Ref> {
         self.inner.map_as_ref(|inner| Py_Unstable_Ref {
-            inner: RustRef::new(unsafe { make_mut(inner.unstable()) }),
+            inner: RefMutContainer::new_raw(unsafe { make_mut(inner.unstable()) }),
         })
     }
 
@@ -275,7 +283,7 @@ impl Py_InMemoryRaftLog_Ref {
                     .unstable_entries()
                     .iter()
                     .map(|entry| Py_Entry_Ref {
-                        inner: RustRef::new(unsafe { make_mut(entry) }),
+                        inner: RefMutContainer::new_raw(unsafe { make_mut(entry) }),
                     })
                     .collect::<Vec<_>>()
             })
@@ -288,7 +296,7 @@ impl Py_InMemoryRaftLog_Ref {
                 .unstable_snapshot()
                 .as_ref()
                 .map(|snapshot| Py_Snapshot_Ref {
-                    inner: RustRef::new(unsafe { make_mut(snapshot) }),
+                    inner: RefMutContainer::new_raw(unsafe { make_mut(snapshot) }),
                 })
         })
     }
@@ -319,13 +327,13 @@ impl Py_InMemoryRaftLog_Ref {
 
     pub fn store(&mut self) -> PyResult<Py_MemStorage_Ref> {
         self.inner.map_as_mut(|inner| Py_MemStorage_Ref {
-            inner: RustRef::new(inner.mut_store()),
+            inner: RefMutContainer::new_raw(inner.mut_store()),
         })
     }
 
     pub fn get_store(&mut self) -> PyResult<Py_MemStorage_Ref> {
         self.inner.map_as_mut(|inner| Py_MemStorage_Ref {
-            inner: RustRef::new(inner.mut_store()),
+            inner: RefMutContainer::new_raw(inner.mut_store()),
         })
     }
 
@@ -348,7 +356,7 @@ impl Py_InMemoryRaftLog_Ref {
         //         .map(|entries| {
         //             entries.iter().map(|entry| {
         //                 Py_Entry_Ref {
-        //                     inner: RustRef::new(unsafe { make_mut(entry) }),
+        //                     inner: RefMutContainer::new(unsafe { make_mut(entry) }),
         //                 }
         //             }).collect::<Vec<_>>()
         //         }).collect::<Result<Vec<Py_Entry_Ref>, _>>()
diff --git a/src/mem_storage_bindings/raw_node.rs b/src/mem_storage_bindings/raw_node.rs
index c91e654..3bcafbe 100644
--- a/src/mem_storage_bindings/raw_node.rs
+++ b/src/mem_storage_bindings/raw_node.rs
@@ -6,6 +6,7 @@ use raft::storage::MemStorage;
 use raft::GetEntriesContext;
 
 use raft::raw_node::RawNode;
+use utils::reference::{RefMutContainer, RefMutOwner};
 use utils::unsafe_cast::make_mut;
 
 use super::raft::Py_InMemoryRaft_Ref;
@@ -22,16 +23,15 @@ use raftpb_bindings::snapshot::Py_Snapshot_Ref;
 use super::mem_storage::{Py_MemStorage_Mut, Py_MemStorage_Ref};
 use bindings::snapshot_status::Py_SnapshotStatus;
 use utils::errors::Py_RaftError;
-use utils::reference::RustRef;
 
 #[pyclass(name = "InMemoryRawNode")]
 pub struct Py_InMemoryRawNode {
-    pub inner: RawNode<MemStorage>,
+    pub inner: RefMutOwner<RawNode<MemStorage>>,
 }
 
 #[pyclass(name = "InMemoryRawNode_Ref")]
 pub struct Py_InMemoryRawNode_Ref {
-    pub inner: RustRef<RawNode<MemStorage>>,
+    pub inner: RefMutContainer<RawNode<MemStorage>>,
 }
 
 #[pymethods]
@@ -43,14 +43,15 @@ impl Py_InMemoryRawNode {
         logger: Py_Logger_Mut,
     ) -> PyResult<Self> {
         Ok(Py_InMemoryRawNode {
-            inner: RawNode::new(&cfg.into(), storage.into(), &logger.into())
-                .map_err(Py_RaftError)?,
+            inner: RefMutOwner::new(
+                RawNode::new(&cfg.into(), storage.into(), &logger.into()).map_err(Py_RaftError)?,
+            ),
         })
     }
 
     pub fn make_ref(&mut self) -> Py_InMemoryRawNode_Ref {
         Py_InMemoryRawNode_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
@@ -75,7 +76,7 @@ impl Py_InMemoryRawNode_Ref {
         let rd = rd.inner.map_as_mut(|rd| std::mem::take(rd))?;
 
         self.inner.map_as_mut(|inner| Py_LightReady {
-            inner: inner.advance(rd),
+            inner: RefMutOwner::new(inner.advance(rd)),
         })
     }
 
@@ -83,7 +84,7 @@ impl Py_InMemoryRawNode_Ref {
         let rd = rd.inner.map_as_mut(|rd| std::mem::take(rd))?;
 
         self.inner.map_as_mut(|inner| Py_LightReady {
-            inner: inner.advance_append(rd),
+            inner: RefMutOwner::new(inner.advance_append(rd)),
         })
     }
 
@@ -133,7 +134,7 @@ impl Py_InMemoryRawNode_Ref {
     pub fn snap(&self) -> PyResult<Option<Py_Snapshot_Ref>> {
         self.inner.map_as_ref(|inner| {
             inner.snap().map(|snap| Py_Snapshot_Ref {
-                inner: RustRef::new(unsafe { make_mut(snap) }),
+                inner: RefMutContainer::new_raw(unsafe { make_mut(snap) }),
             })
         })
     }
@@ -199,7 +200,7 @@ impl Py_InMemoryRawNode_Ref {
 
     pub fn ready(&mut self) -> PyResult<Py_Ready> {
         self.inner.map_as_mut(|inner| Py_Ready {
-            inner: inner.ready(),
+            inner: RefMutOwner::new(inner.ready()),
         })
     }
 
@@ -209,21 +210,23 @@ impl Py_InMemoryRawNode_Ref {
 
             inner
                 .apply_conf_change(&cc)
-                .map(|cs| Py_ConfState { inner: cs })
+                .map(|cs| Py_ConfState {
+                    inner: RefMutOwner::new(cs),
+                })
                 .map_err(|e| Py_RaftError(e).into())
         })?
     }
 
     pub fn apply_conf_change_v2(&mut self, cc: Py_ConfChangeV2_Mut) -> PyResult<Py_ConfState> {
+        let cc: ConfChangeV2 = cc.into();
+
         self.inner.map_as_mut(|inner| {
-            {
-                let cc: ConfChangeV2 = cc.into();
-
-                inner
-                    .apply_conf_change(&cc)
-                    .map(|cs| Py_ConfState { inner: cs })
-            }
-            .map_err(|e| Py_RaftError(e).into())
+            inner
+                .apply_conf_change(&cc)
+                .map(|cs| Py_ConfState {
+                    inner: RefMutOwner::new(cs),
+                })
+                .map_err(|e| Py_RaftError(e).into())
         })?
     }
 
@@ -239,13 +242,13 @@ impl Py_InMemoryRawNode_Ref {
 
     pub fn get_raft(&mut self) -> PyResult<Py_InMemoryRaft_Ref> {
         self.inner.map_as_mut(|inner| Py_InMemoryRaft_Ref {
-            inner: RustRef::new(&mut inner.raft),
+            inner: RefMutContainer::new_raw(&mut inner.raft),
         })
     }
 
     pub fn store(&mut self) -> PyResult<Py_MemStorage_Ref> {
         self.inner.map_as_mut(|inner| Py_MemStorage_Ref {
-            inner: RustRef::new(inner.mut_store()),
+            inner: RefMutContainer::new_raw(inner.mut_store()),
         })
     }
 
diff --git a/src/py_storage_bindings/py_storage.rs b/src/py_storage_bindings/py_storage.rs
index e14bee9..bd61a3e 100644
--- a/src/py_storage_bindings/py_storage.rs
+++ b/src/py_storage_bindings/py_storage.rs
@@ -8,11 +8,11 @@ use raftpb_bindings::hard_state::Py_HardState;
 
 use raftpb_bindings::entry::Py_Entry_Ref;
 use raftpb_bindings::snapshot::{Py_Snapshot_Mut, Py_Snapshot_Ref};
-use utils::reference::RustRef;
 
 use bindings::raft_state::{Py_RaftState_Mut, Py_RaftState_Ref};
 use raftpb_bindings::entry::Py_Entry_Mut;
-use utils::errors::{makeNativeRaftError, Py_RaftError, DESTROYED_ERR_MSG};
+use utils::errors::{make_native_raft_error, Py_RaftError, DESTROYED_ERR_MSG};
+use utils::reference::{RefMutContainer, RefMutOwner};
 use utils::unsafe_cast::make_mut;
 
 #[derive(Clone)]
@@ -24,7 +24,7 @@ pub struct Py_Storage {
 #[derive(Clone)]
 #[pyclass(name = "Storage_Ref")]
 pub struct Py_Storage_Ref {
-    pub inner: RustRef<Py_Storage>,
+    pub inner: RefMutContainer<Py_Storage>,
 }
 
 #[pymethods]
@@ -36,7 +36,7 @@ impl Py_Storage {
 
     pub fn make_ref(&mut self) -> Py_Storage_Ref {
         Py_Storage_Ref {
-            inner: RustRef::new(self),
+            inner: RefMutContainer::new_raw(self),
         }
     }
 
@@ -147,7 +147,7 @@ impl Py_Storage_Ref {
     pub fn initial_state(&self) -> PyResult<Py_RaftState_Ref> {
         Storage::initial_state(self)
             .map(|mut rs| Py_RaftState_Ref {
-                inner: RustRef::new(&mut rs),
+                inner: RefMutContainer::new_raw(&mut rs),
             })
             .map_err(|e| Py_RaftError(e).into())
     }
@@ -169,7 +169,7 @@ impl Py_Storage_Ref {
                 let py_entries = entries
                     .iter_mut()
                     .map(|x| Py_Entry_Ref {
-                        inner: RustRef::new(x),
+                        inner: RefMutContainer::new_raw(x),
                     })
                     .collect::<Vec<_>>();
                 py_entries.into_py(py)
@@ -192,7 +192,7 @@ impl Py_Storage_Ref {
     pub fn snapshot(&self, request_index: u64, to: u64) -> PyResult<Py_Snapshot_Ref> {
         Storage::snapshot(self, request_index, to)
             .map(|mut snapshot| Py_Snapshot_Ref {
-                inner: RustRef::new(&mut snapshot),
+                inner: RefMutContainer::new_raw(&mut snapshot),
             })
             .map_err(|e| Py_RaftError(e).into())
     }
@@ -209,7 +209,7 @@ impl Storage for Py_Storage {
                         .extract::<_>()
                         .map(|rs: Py_RaftState_Mut| rs.into())
                 })
-                .map_err(|e| makeNativeRaftError(py, e))
+                .map_err(|e| make_native_raft_error(py, e))
         })
     }
 
@@ -221,7 +221,9 @@ impl Storage for Py_Storage {
         context: GetEntriesContext,
     ) -> raft::Result<Vec<raft::prelude::Entry>> {
         let max_size: Option<u64> = max_size.into();
-        let mut context = Py_GetEntriesContext { inner: context };
+        let mut context = Py_GetEntriesContext {
+            inner: RefMutOwner::new(context),
+        };
 
         Python::with_gil(|py| {
             self.storage
@@ -232,7 +234,7 @@ impl Storage for Py_Storage {
                         .extract::<Vec<Py_Entry_Mut>>()
                         .map(|entries| entries.into_iter().map(|e| e.into()).collect())
                 })
-                .map_err(|e| makeNativeRaftError(py, e))
+                .map_err(|e| make_native_raft_error(py, e))
         })
     }
 
@@ -242,7 +244,7 @@ impl Storage for Py_Storage {
                 .as_ref(py)
                 .call_method("term", (idx,), None)
                 .and_then(|term| term.extract::<u64>())
-                .map_err(|e| makeNativeRaftError(py, e))
+                .map_err(|e| make_native_raft_error(py, e))
         })
     }
 
@@ -252,7 +254,7 @@ impl Storage for Py_Storage {
                 .as_ref(py)
                 .call_method("first_index", (), None)
                 .and_then(|term| term.extract::<u64>())
-                .map_err(|e| makeNativeRaftError(py, e))
+                .map_err(|e| make_native_raft_error(py, e))
         })
     }
 
@@ -262,7 +264,7 @@ impl Storage for Py_Storage {
                 .as_ref(py)
                 .call_method("last_index", (), None)
                 .and_then(|term| term.extract::<u64>())
-                .map_err(|e| makeNativeRaftError(py, e))
+                .map_err(|e| make_native_raft_error(py, e))
         })
     }
 
@@ -276,7 +278,7 @@ impl Storage for Py_Storage {
                         .extract::<_>()
                         .map(|ss: Py_Snapshot_Mut| ss.into())
                 })
-                .map_err(|e| makeNativeRaftError(py, e))
+                .map_err(|e| make_native_raft_error(py, e))
         })
     }
 }
@@ -294,7 +296,7 @@ impl Storage for Py_Storage_Ref {
                                 .extract::<_>(py)
                                 .map(|rs: Py_RaftState_Mut| rs.into())
                         })
-                        .map_err(|e| makeNativeRaftError(py, e))
+                        .map_err(|e| make_native_raft_error(py, e))
                 })
             })
             .expect(DESTROYED_ERR_MSG)
@@ -308,7 +310,9 @@ impl Storage for Py_Storage_Ref {
         context: GetEntriesContext,
     ) -> raft::Result<Vec<raft::prelude::Entry>> {
         let max_size: Option<u64> = max_size.into();
-        let mut context = Py_GetEntriesContext { inner: context };
+        let mut context = Py_GetEntriesContext {
+            inner: RefMutOwner::new(context),
+        };
 
         unsafe { make_mut(&self.inner) }
             .map_as_mut(|inner| {
@@ -322,7 +326,7 @@ impl Storage for Py_Storage_Ref {
                                 .extract::<Vec<Py_Entry_Mut>>()
                                 .map(|entries| entries.into_iter().map(|e| e.into()).collect())
                         })
-                        .map_err(|e| makeNativeRaftError(py, e))
+                        .map_err(|e| make_native_raft_error(py, e))
                 })
             })
             .expect(DESTROYED_ERR_MSG)
@@ -337,7 +341,7 @@ impl Storage for Py_Storage_Ref {
                         .as_ref(py)
                         .call_method("term", (idx,), None)
                         .and_then(|term| term.extract::<u64>())
-                        .map_err(|e| makeNativeRaftError(py, e))
+                        .map_err(|e| make_native_raft_error(py, e))
                 })
             })
             .expect(DESTROYED_ERR_MSG)
@@ -352,7 +356,7 @@ impl Storage for Py_Storage_Ref {
                         .as_ref(py)
                         .call_method("first_index", (), None)
                         .and_then(|term| term.extract::<u64>())
-                        .map_err(|e| makeNativeRaftError(py, e))
+                        .map_err(|e| make_native_raft_error(py, e))
                 })
             })
             .expect(DESTROYED_ERR_MSG)
@@ -367,7 +371,7 @@ impl Storage for Py_Storage_Ref {
                         .as_ref(py)
                         .call_method("last_index", (), None)
                         .and_then(|term| term.extract::<u64>())
-                        .map_err(|e| makeNativeRaftError(py, e))
+                        .map_err(|e| make_native_raft_error(py, e))
                 })
             })
             .expect(DESTROYED_ERR_MSG)
@@ -385,7 +389,7 @@ impl Storage for Py_Storage_Ref {
                                 .extract::<_>(py)
                                 .map(|ss: Py_Snapshot_Mut| ss.into())
                         })
-                        .map_err(|e| makeNativeRaftError(py, e))
+                        .map_err(|e| make_native_raft_error(py, e))
                 })
             })
             .expect(DESTROYED_ERR_MSG)
diff --git a/src/py_storage_bindings/raft.rs b/src/py_storage_bindings/raft.rs
index 12468b9..aba7da6 100644
--- a/src/py_storage_bindings/raft.rs
+++ b/src/py_storage_bindings/raft.rs
@@ -3,7 +3,10 @@ use pyo3::{
     prelude::*,
     types::{PyList, PyString},
 };
-use utils::{reference::RustRef, unsafe_cast::make_mut};
+use utils::{
+    reference::{RefMutContainer, RefMutOwner},
+    unsafe_cast::make_mut,
+};
 
 use raft::{Raft, CAMPAIGN_ELECTION, CAMPAIGN_PRE_ELECTION, CAMPAIGN_TRANSFER};
 
@@ -34,12 +37,12 @@ use utils::errors::Py_RaftError;
 
 #[pyclass(name = "Raft")]
 pub struct Py_Raft {
-    pub inner: Raft<Py_Storage>,
+    pub inner: RefMutOwner<Raft<Py_Storage>>,
 }
 
 #[pyclass(name = "Raft_Ref")]
 pub struct Py_Raft_Ref {
-    pub inner: RustRef<Raft<Py_Storage>>,
+    pub inner: RefMutContainer<Raft<Py_Storage>>,
 }
 
 #[pymethods]
@@ -47,13 +50,15 @@ impl Py_Raft {
     #[new]
     pub fn new(cfg: Py_Config_Mut, store: &Py_Storage, logger: Py_Logger_Mut) -> PyResult<Self> {
         Raft::new(&cfg.into(), store.clone(), &logger.into())
-            .map(|r| Py_Raft { inner: r })
+            .map(|r| Py_Raft {
+                inner: RefMutOwner::new(r),
+            })
             .map_err(|e| Py_RaftError(e).into())
     }
 
     pub fn make_ref(&mut self) -> Py_Raft_Ref {
         Py_Raft_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
@@ -254,13 +259,13 @@ impl Py_Raft_Ref {
 
     pub fn soft_state(&self) -> PyResult<Py_SoftState> {
         self.inner.map_as_ref(|inner| Py_SoftState {
-            inner: inner.soft_state(),
+            inner: RefMutOwner::new(inner.soft_state()),
         })
     }
 
     pub fn hard_state(&self) -> PyResult<Py_HardState> {
         self.inner.map_as_ref(|inner| Py_HardState {
-            inner: inner.hard_state(),
+            inner: RefMutOwner::new(inner.hard_state()),
         })
     }
 
@@ -273,7 +278,7 @@ impl Py_Raft_Ref {
             inner
                 .apply_conf_change(&cc.into())
                 .map(|cs| Py_ConfState_Ref {
-                    inner: RustRef::new(unsafe { make_mut(&cs) }),
+                    inner: RefMutContainer::new_raw(unsafe { make_mut(&cs) }),
                 })
                 .map_err(|e| Py_RaftError(e).into())
         })?
@@ -302,7 +307,7 @@ impl Py_Raft_Ref {
 
     pub fn post_conf_change(&mut self) -> PyResult<Py_ConfState_Ref> {
         self.inner.map_as_mut(|inner| Py_ConfState_Ref {
-            inner: RustRef::new(&mut inner.post_conf_change()),
+            inner: RefMutContainer::new_raw(&mut inner.post_conf_change()),
         })
     }
 
@@ -327,7 +332,7 @@ impl Py_Raft_Ref {
 
     pub fn prs(&mut self) -> PyResult<Py_ProgressTracker_Ref> {
         self.inner.map_as_mut(|inner| Py_ProgressTracker_Ref {
-            inner: RustRef::new(inner.mut_prs()),
+            inner: RefMutContainer::new_raw(inner.mut_prs()),
         })
     }
 
@@ -338,7 +343,7 @@ impl Py_Raft_Ref {
     pub fn snap(&self) -> PyResult<Option<Py_Snapshot_Ref>> {
         self.inner.map_as_ref(|inner| {
             inner.snap().map(|snapshot| Py_Snapshot_Ref {
-                inner: RustRef::new(unsafe { make_mut(snapshot) }),
+                inner: RefMutContainer::new_raw(unsafe { make_mut(snapshot) }),
             })
         })
     }
@@ -403,7 +408,9 @@ impl Py_Raft_Ref {
             inner
                 .read_states
                 .iter()
-                .map(|rs| Py_ReadState { inner: rs.clone() })
+                .map(|rs| Py_ReadState {
+                    inner: RefMutOwner::new(rs.clone()),
+                })
                 .collect::<Vec<_>>()
                 .into_py(py)
         })
@@ -468,7 +475,7 @@ impl Py_Raft_Ref {
                 .msgs
                 .iter_mut()
                 .map(|msg| Py_Message_Ref {
-                    inner: RustRef::new(msg),
+                    inner: RefMutContainer::new_raw(msg),
                 })
                 .collect::<Vec<_>>()
                 .into_py(py)
@@ -488,7 +495,9 @@ impl Py_Raft_Ref {
             let msgs = inner.msgs.drain(..).collect::<Vec<_>>();
 
             msgs.into_iter()
-                .map(|msg| Py_Message { inner: msg })
+                .map(|msg| Py_Message {
+                    inner: RefMutOwner::new(msg),
+                })
                 .collect::<Vec<_>>()
                 .into_py(py)
         })
@@ -496,7 +505,7 @@ impl Py_Raft_Ref {
 
     pub fn get_raft_log(&mut self) -> PyResult<Py_RaftLog_Ref> {
         self.inner.map_as_mut(|inner| Py_RaftLog_Ref {
-            inner: RustRef::new(&mut inner.raft_log),
+            inner: RefMutContainer::new_raw(&mut inner.raft_log),
         })
     }
 
@@ -534,7 +543,7 @@ impl Py_Raft_Ref {
 
     pub fn store(&mut self) -> PyResult<Py_Storage_Ref> {
         self.inner.map_as_mut(|inner| Py_Storage_Ref {
-            inner: RustRef::new(inner.mut_store()),
+            inner: RefMutContainer::new_raw(inner.mut_store()),
         })
     }
 
diff --git a/src/py_storage_bindings/raft_log.rs b/src/py_storage_bindings/raft_log.rs
index 8c7a5be..00d2c4a 100644
--- a/src/py_storage_bindings/raft_log.rs
+++ b/src/py_storage_bindings/raft_log.rs
@@ -1,12 +1,12 @@
 use pyo3::types::PyList;
 use pyo3::{intern, prelude::*};
+use utils::reference::{RefMutContainer, RefMutOwner};
 use utils::unsafe_cast::make_mut;
 
 use external_bindings::slog::Py_Logger_Mut;
 use raftpb_bindings::snapshot::{Py_Snapshot_Mut, Py_Snapshot_Ref};
 
 use raft::{GetEntriesContext, RaftLog};
-use utils::reference::RustRef;
 
 use super::py_storage::{Py_Storage, Py_Storage_Ref};
 use bindings::{get_entries_context::Py_GetEntriesContext_Ref, unstable::Py_Unstable_Ref};
@@ -15,12 +15,12 @@ use utils::errors::Py_RaftError;
 
 #[pyclass(name = "RaftLog")]
 pub struct Py_RaftLog {
-    pub inner: RaftLog<Py_Storage>,
+    pub inner: RefMutOwner<RaftLog<Py_Storage>>,
 }
 
 #[pyclass(name = "RaftLog_Ref")]
 pub struct Py_RaftLog_Ref {
-    pub inner: RustRef<RaftLog<Py_Storage>>,
+    pub inner: RefMutContainer<RaftLog<Py_Storage>>,
 }
 
 #[pymethods]
@@ -28,13 +28,13 @@ impl Py_RaftLog {
     #[new]
     pub fn new(store: &Py_Storage, logger: Py_Logger_Mut) -> Self {
         Py_RaftLog {
-            inner: RaftLog::new(store.clone(), logger.into()),
+            inner: RefMutOwner::new(RaftLog::new(store.clone(), logger.into())),
         }
     }
 
     pub fn make_ref(&mut self) -> Py_RaftLog_Ref {
         Py_RaftLog_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
@@ -72,7 +72,9 @@ impl Py_RaftLog_Ref {
                 .map(|entries| {
                     entries
                         .into_iter()
-                        .map(|entry| Py_Entry { inner: entry })
+                        .map(|entry| Py_Entry {
+                            inner: RefMutOwner::new(entry),
+                        })
                         .collect::<Vec<_>>()
                         .into_py(py)
                 })
@@ -85,7 +87,9 @@ impl Py_RaftLog_Ref {
             inner
                 .all_entries()
                 .into_iter()
-                .map(|entry| Py_Entry { inner: entry })
+                .map(|entry| Py_Entry {
+                    inner: RefMutOwner::new(entry),
+                })
                 .collect::<Vec<_>>()
                 .into_py(py)
         })
@@ -96,7 +100,9 @@ impl Py_RaftLog_Ref {
             inner.next_entries(max_size).map(|entries| {
                 entries
                     .into_iter()
-                    .map(|entry| Py_Entry { inner: entry })
+                    .map(|entry| Py_Entry {
+                        inner: RefMutOwner::new(entry),
+                    })
                     .collect::<Vec<_>>()
                     .into_py(py)
             })
@@ -115,7 +121,9 @@ impl Py_RaftLog_Ref {
                 .map(|entries| {
                     entries
                         .into_iter()
-                        .map(|entry| Py_Entry { inner: entry })
+                        .map(|entry| Py_Entry {
+                            inner: RefMutOwner::new(entry),
+                        })
                         .collect::<Vec<_>>()
                         .into_py(py)
                 })
@@ -224,7 +232,7 @@ impl Py_RaftLog_Ref {
             inner
                 .snapshot(request_index, to)
                 .map(|mut snapshot| Py_Snapshot_Ref {
-                    inner: RustRef::new(&mut snapshot),
+                    inner: RefMutContainer::new_raw(&mut snapshot),
                 })
                 .map_err(|e| Py_RaftError(e).into())
         })?
@@ -262,7 +270,7 @@ impl Py_RaftLog_Ref {
 
     pub fn unstable(&self) -> PyResult<Py_Unstable_Ref> {
         self.inner.map_as_ref(|inner| Py_Unstable_Ref {
-            inner: RustRef::new(unsafe { make_mut(inner.unstable()) }),
+            inner: RefMutContainer::new_raw(unsafe { make_mut(inner.unstable()) }),
         })
     }
 
@@ -273,7 +281,7 @@ impl Py_RaftLog_Ref {
                     .unstable_entries()
                     .iter()
                     .map(|entry| Py_Entry_Ref {
-                        inner: RustRef::new(unsafe { make_mut(entry) }),
+                        inner: RefMutContainer::new_raw(unsafe { make_mut(entry) }),
                     })
                     .collect::<Vec<_>>()
             })
@@ -286,7 +294,7 @@ impl Py_RaftLog_Ref {
                 .unstable_snapshot()
                 .as_ref()
                 .map(|snapshot| Py_Snapshot_Ref {
-                    inner: RustRef::new(unsafe { make_mut(snapshot) }),
+                    inner: RefMutContainer::new_raw(unsafe { make_mut(snapshot) }),
                 })
         })
     }
@@ -317,13 +325,13 @@ impl Py_RaftLog_Ref {
 
     pub fn store(&mut self) -> PyResult<Py_Storage_Ref> {
         self.inner.map_as_mut(|inner| Py_Storage_Ref {
-            inner: RustRef::new(inner.mut_store()),
+            inner: RefMutContainer::new_raw(inner.mut_store()),
         })
     }
 
     pub fn get_store(&mut self) -> PyResult<Py_Storage_Ref> {
         self.inner.map_as_mut(|inner| Py_Storage_Ref {
-            inner: RustRef::new(inner.mut_store()),
+            inner: RefMutContainer::new_raw(inner.mut_store()),
         })
     }
 
@@ -346,7 +354,7 @@ impl Py_RaftLog_Ref {
         //         .map(|entries| {
         //             entries.iter().map(|entry| {
         //                 Py_Entry_Ref {
-        //                     inner: RustRef::new(unsafe { make_mut(entry) }),
+        //                     inner: RefMutContainer::new(unsafe { make_mut(entry) }),
         //                 }
         //             }).collect::<Vec<_>>()
         //         }).collect::<Result<Vec<Py_Entry_Ref>, _>>()
diff --git a/src/py_storage_bindings/raw_node.rs b/src/py_storage_bindings/raw_node.rs
index 83480e5..bc3df09 100644
--- a/src/py_storage_bindings/raw_node.rs
+++ b/src/py_storage_bindings/raw_node.rs
@@ -5,6 +5,7 @@ use raft::prelude::{ConfChange, ConfChangeV2};
 use raft::GetEntriesContext;
 
 use raft::raw_node::RawNode;
+use utils::reference::{RefMutContainer, RefMutOwner};
 use utils::unsafe_cast::make_mut;
 
 use bindings::config::Py_Config_Mut;
@@ -18,7 +19,6 @@ use raftpb_bindings::message::Py_Message_Mut;
 use raftpb_bindings::snapshot::Py_Snapshot_Ref;
 
 use bindings::snapshot_status::Py_SnapshotStatus;
-use utils::reference::RustRef;
 
 use crate::py_storage::{Py_Storage, Py_Storage_Ref};
 use crate::raft::Py_Raft_Ref;
@@ -26,12 +26,12 @@ use utils::errors::Py_RaftError;
 
 #[pyclass(name = "RawNode")]
 pub struct Py_RawNode {
-    pub inner: RawNode<Py_Storage>,
+    pub inner: RefMutOwner<RawNode<Py_Storage>>,
 }
 
 #[pyclass(name = "RawNode_Ref")]
 pub struct Py_RawNode_Ref {
-    pub inner: RustRef<RawNode<Py_Storage>>,
+    pub inner: RefMutContainer<RawNode<Py_Storage>>,
 }
 
 #[pymethods]
@@ -39,14 +39,15 @@ impl Py_RawNode {
     #[new]
     pub fn new(cfg: Py_Config_Mut, storage: &Py_Storage, logger: Py_Logger_Mut) -> PyResult<Self> {
         Ok(Py_RawNode {
-            inner: RawNode::new(&cfg.into(), storage.clone(), &logger.into())
-                .map_err(Py_RaftError)?,
+            inner: RefMutOwner::new(
+                RawNode::new(&cfg.into(), storage.clone(), &logger.into()).map_err(Py_RaftError)?,
+            ),
         })
     }
 
     pub fn make_ref(&mut self) -> Py_RawNode_Ref {
         Py_RawNode_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
@@ -71,7 +72,7 @@ impl Py_RawNode_Ref {
         let rd = rd.inner.map_as_mut(|rd| std::mem::take(rd))?;
 
         self.inner.map_as_mut(|inner| Py_LightReady {
-            inner: inner.advance(rd),
+            inner: RefMutOwner::new(inner.advance(rd)),
         })
     }
 
@@ -79,7 +80,7 @@ impl Py_RawNode_Ref {
         let rd = rd.inner.map_as_mut(|rd| std::mem::take(rd))?;
 
         self.inner.map_as_mut(|inner| Py_LightReady {
-            inner: inner.advance_append(rd),
+            inner: RefMutOwner::new(inner.advance_append(rd)),
         })
     }
 
@@ -129,7 +130,7 @@ impl Py_RawNode_Ref {
     pub fn snap(&self) -> PyResult<Option<Py_Snapshot_Ref>> {
         self.inner.map_as_ref(|inner| {
             inner.snap().map(|snap| Py_Snapshot_Ref {
-                inner: RustRef::new(unsafe { make_mut(snap) }),
+                inner: RefMutContainer::new_raw(unsafe { make_mut(snap) }),
             })
         })
     }
@@ -195,7 +196,7 @@ impl Py_RawNode_Ref {
 
     pub fn ready(&mut self) -> PyResult<Py_Ready> {
         self.inner.map_as_mut(|inner| Py_Ready {
-            inner: inner.ready(),
+            inner: RefMutOwner::new(inner.ready()),
         })
     }
 
@@ -205,7 +206,9 @@ impl Py_RawNode_Ref {
 
             inner
                 .apply_conf_change(&cc)
-                .map(|cs| Py_ConfState { inner: cs })
+                .map(|cs| Py_ConfState {
+                    inner: RefMutOwner::new(cs),
+                })
                 .map_err(|e| Py_RaftError(e).into())
         })?
     }
@@ -216,7 +219,9 @@ impl Py_RawNode_Ref {
 
             inner
                 .apply_conf_change(&cc)
-                .map(|cs| Py_ConfState { inner: cs })
+                .map(|cs| Py_ConfState {
+                    inner: RefMutOwner::new(cs),
+                })
                 .map_err(|e| Py_RaftError(e).into())
         })?
     }
@@ -233,13 +238,13 @@ impl Py_RawNode_Ref {
 
     pub fn get_raft(&mut self) -> PyResult<Py_Raft_Ref> {
         self.inner.map_as_mut(|inner| Py_Raft_Ref {
-            inner: RustRef::new(&mut inner.raft),
+            inner: RefMutContainer::new_raw(&mut inner.raft),
         })
     }
 
     pub fn store(&mut self) -> PyResult<Py_Storage_Ref> {
         self.inner.map_as_mut(|inner| Py_Storage_Ref {
-            inner: RustRef::new(inner.mut_store()),
+            inner: RefMutContainer::new_raw(inner.mut_store()),
         })
     }
 
diff --git a/src/raftpb_bindings/conf_change.rs b/src/raftpb_bindings/conf_change.rs
index 8403686..543817f 100644
--- a/src/raftpb_bindings/conf_change.rs
+++ b/src/raftpb_bindings/conf_change.rs
@@ -1,7 +1,11 @@
 use prost::Message as ProstMessage;
 use protobuf::Message as PbMessage;
 use pyo3::{intern, prelude::*, pyclass::CompareOp, types::PyBytes};
-use utils::{errors::to_pyresult, implement_type_conversion, reference::RustRef};
+use utils::{
+    errors::to_pyresult,
+    implement_type_conversion,
+    reference::{RefMutContainer, RefMutOwner},
+};
 
 use super::{conf_change_type::Py_ConfChangeType, conf_change_v2::Py_ConfChangeV2};
 
@@ -13,13 +17,13 @@ use raft::{
 #[derive(Clone)]
 #[pyclass(name = "ConfChange")]
 pub struct Py_ConfChange {
-    pub inner: ConfChange,
+    pub inner: RefMutOwner<ConfChange>,
 }
 
 #[derive(Clone)]
 #[pyclass(name = "ConfChange_Ref")]
 pub struct Py_ConfChange_Ref {
-    pub inner: RustRef<ConfChange>,
+    pub inner: RefMutContainer<ConfChange>,
 }
 
 #[derive(FromPyObject)]
@@ -35,40 +39,40 @@ impl Py_ConfChange {
     #[new]
     pub fn new() -> Self {
         Py_ConfChange {
-            inner: ConfChange::new(),
+            inner: RefMutOwner::new(ConfChange::new()),
         }
     }
 
     #[staticmethod]
     pub fn default() -> Self {
         Py_ConfChange {
-            inner: ConfChange::default(),
+            inner: RefMutOwner::new(ConfChange::default()),
         }
     }
 
     #[staticmethod]
     pub fn decode(v: &[u8]) -> PyResult<Py_ConfChange> {
         Ok(Py_ConfChange {
-            inner: to_pyresult(ProstMessage::decode(v))?,
+            inner: RefMutOwner::new(to_pyresult(ProstMessage::decode(v))?),
         })
     }
 
     pub fn make_ref(&mut self) -> Py_ConfChange_Ref {
         Py_ConfChange_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
     pub fn __repr__(&self) -> String {
-        format!("{:?}", self.inner)
+        format!("{:?}", self.inner.inner)
     }
 
     pub fn __richcmp__(&self, py: Python, rhs: Py_ConfChange_Mut, op: CompareOp) -> PyObject {
         let rhs: ConfChange = rhs.into();
 
         match op {
-            CompareOp::Eq => (self.inner == rhs).into_py(py),
-            CompareOp::Ne => (self.inner != rhs).into_py(py),
+            CompareOp::Eq => (self.inner.inner == rhs).into_py(py),
+            CompareOp::Ne => (self.inner.inner != rhs).into_py(py),
             _ => py.NotImplemented(),
         }
     }
@@ -104,7 +108,7 @@ impl Py_ConfChange_Ref {
 
     pub fn clone(&mut self) -> PyResult<Py_ConfChange> {
         Ok(Py_ConfChange {
-            inner: self.inner.map_as_ref(|inner| inner.clone())?,
+            inner: RefMutOwner::new(self.inner.map_as_ref(|inner| inner.clone())?),
         })
     }
 
@@ -184,7 +188,7 @@ impl Py_ConfChange_Ref {
     pub fn as_v1(&mut self) -> PyResult<Option<Py_ConfChange_Ref>> {
         self.inner.map_as_mut(|inner| {
             Some(Py_ConfChange_Ref {
-                inner: RustRef::new(inner),
+                inner: RefMutContainer::new_raw(inner),
             })
         })
     }
@@ -201,7 +205,9 @@ impl Py_ConfChange_Ref {
             cc.mut_changes().push(single);
             cc.set_context(inner.take_context());
 
-            Py_ConfChangeV2 { inner: cc }
+            Py_ConfChangeV2 {
+                inner: RefMutOwner::new(cc),
+            }
         })
     }
 }
diff --git a/src/raftpb_bindings/conf_change_single.rs b/src/raftpb_bindings/conf_change_single.rs
index df09ba2..3aa8266 100644
--- a/src/raftpb_bindings/conf_change_single.rs
+++ b/src/raftpb_bindings/conf_change_single.rs
@@ -1,7 +1,11 @@
 use prost::Message as ProstMessage;
 use protobuf::Message as PbMessage;
 use pyo3::{intern, prelude::*, pyclass::CompareOp, types::PyBytes};
-use utils::{errors::to_pyresult, implement_type_conversion, reference::RustRef};
+use utils::{
+    errors::to_pyresult,
+    implement_type_conversion,
+    reference::{RefMutContainer, RefMutOwner},
+};
 
 use super::conf_change_type::Py_ConfChangeType;
 
@@ -10,13 +14,13 @@ use raft::eraftpb::ConfChangeSingle;
 #[derive(Clone)]
 #[pyclass(name = "ConfChangeSingle")]
 pub struct Py_ConfChangeSingle {
-    pub inner: ConfChangeSingle,
+    pub inner: RefMutOwner<ConfChangeSingle>,
 }
 
 #[derive(Clone)]
 #[pyclass(name = "ConfChangeSingle_Ref")]
 pub struct Py_ConfChangeSingle_Ref {
-    pub inner: RustRef<ConfChangeSingle>,
+    pub inner: RefMutContainer<ConfChangeSingle>,
 }
 
 #[derive(FromPyObject)]
@@ -32,40 +36,40 @@ impl Py_ConfChangeSingle {
     #[new]
     pub fn new() -> Self {
         Py_ConfChangeSingle {
-            inner: ConfChangeSingle::new(),
+            inner: RefMutOwner::new(ConfChangeSingle::new()),
         }
     }
 
     #[staticmethod]
     pub fn default() -> Self {
         Py_ConfChangeSingle {
-            inner: ConfChangeSingle::default(),
+            inner: RefMutOwner::new(ConfChangeSingle::default()),
         }
     }
 
     #[staticmethod]
     pub fn decode(v: &[u8]) -> PyResult<Py_ConfChangeSingle> {
         Ok(Py_ConfChangeSingle {
-            inner: to_pyresult(ProstMessage::decode(v))?,
+            inner: RefMutOwner::new(to_pyresult(ProstMessage::decode(v))?),
         })
     }
 
     pub fn make_ref(&mut self) -> Py_ConfChangeSingle_Ref {
         Py_ConfChangeSingle_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
     pub fn __repr__(&self) -> String {
-        format!("{:?}", self.inner)
+        format!("{:?}", self.inner.inner)
     }
 
     pub fn __richcmp__(&self, py: Python, rhs: Py_ConfChangeSingle_Mut, op: CompareOp) -> PyObject {
         let rhs: ConfChangeSingle = rhs.into();
 
         match op {
-            CompareOp::Eq => (self.inner == rhs).into_py(py),
-            CompareOp::Ne => (self.inner != rhs).into_py(py),
+            CompareOp::Eq => (self.inner.inner == rhs).into_py(py),
+            CompareOp::Ne => (self.inner.inner != rhs).into_py(py),
             _ => py.NotImplemented(),
         }
     }
@@ -101,7 +105,7 @@ impl Py_ConfChangeSingle_Ref {
 
     pub fn clone(&self) -> PyResult<Py_ConfChangeSingle> {
         Ok(Py_ConfChangeSingle {
-            inner: self.inner.map_as_ref(|x| x.clone())?,
+            inner: RefMutOwner::new(self.inner.map_as_ref(|x| x.clone())?),
         })
     }
 
diff --git a/src/raftpb_bindings/conf_change_v2.rs b/src/raftpb_bindings/conf_change_v2.rs
index ebdb3e4..4396ccd 100644
--- a/src/raftpb_bindings/conf_change_v2.rs
+++ b/src/raftpb_bindings/conf_change_v2.rs
@@ -8,7 +8,10 @@ use pyo3::{
 };
 use raft::eraftpb::ConfChangeV2;
 use utils::{
-    errors::to_pyresult, implement_type_conversion, reference::RustRef, unsafe_cast::make_mut,
+    errors::to_pyresult,
+    implement_type_conversion,
+    reference::{RefMutContainer, RefMutOwner},
+    unsafe_cast::make_mut,
 };
 
 use super::{
@@ -20,13 +23,13 @@ use super::{
 #[derive(Clone)]
 #[pyclass(name = "ConfChangeV2")]
 pub struct Py_ConfChangeV2 {
-    pub inner: ConfChangeV2,
+    pub inner: RefMutOwner<ConfChangeV2>,
 }
 
 #[derive(Clone)]
 #[pyclass(name = "ConfChangeV2_Ref")]
 pub struct Py_ConfChangeV2_Ref {
-    pub inner: RustRef<ConfChangeV2>,
+    pub inner: RefMutContainer<ConfChangeV2>,
 }
 
 #[derive(FromPyObject)]
@@ -42,40 +45,40 @@ impl Py_ConfChangeV2 {
     #[new]
     pub fn new() -> Self {
         Py_ConfChangeV2 {
-            inner: ConfChangeV2::new(),
+            inner: RefMutOwner::new(ConfChangeV2::new()),
         }
     }
 
     #[staticmethod]
     pub fn default() -> Self {
         Py_ConfChangeV2 {
-            inner: ConfChangeV2::default(),
+            inner: RefMutOwner::new(ConfChangeV2::default()),
         }
     }
 
     #[staticmethod]
     pub fn decode(v: &[u8]) -> PyResult<Py_ConfChangeV2> {
         Ok(Py_ConfChangeV2 {
-            inner: to_pyresult(ProstMessage::decode(v))?,
+            inner: RefMutOwner::new(to_pyresult(ProstMessage::decode(v))?),
         })
     }
 
     pub fn make_ref(&mut self) -> Py_ConfChangeV2_Ref {
         Py_ConfChangeV2_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
     pub fn __repr__(&self) -> String {
-        format!("{:?}", self.inner)
+        format!("{:?}", self.inner.inner)
     }
 
     pub fn __richcmp__(&self, py: Python, rhs: Py_ConfChangeV2_Mut, op: CompareOp) -> PyObject {
         let rhs: ConfChangeV2 = rhs.into();
 
         match op {
-            CompareOp::Eq => (self.inner == rhs).into_py(py),
-            CompareOp::Ne => (self.inner != rhs).into_py(py),
+            CompareOp::Eq => (self.inner.inner == rhs).into_py(py),
+            CompareOp::Ne => (self.inner.inner != rhs).into_py(py),
             _ => py.NotImplemented(),
         }
     }
@@ -117,7 +120,7 @@ impl Py_ConfChangeV2_Ref {
 
     pub fn clone(&self) -> PyResult<Py_ConfChangeV2> {
         Ok(Py_ConfChangeV2 {
-            inner: self.inner.map_as_ref(|x| x.clone())?,
+            inner: RefMutOwner::new(self.inner.map_as_ref(|x| x.clone())?),
         })
     }
 
@@ -132,7 +135,7 @@ impl Py_ConfChangeV2_Ref {
                 .get_changes()
                 .iter()
                 .map(|cs| Py_ConfChangeSingle_Ref {
-                    inner: RustRef::new(unsafe { make_mut(cs) }),
+                    inner: RefMutContainer::new_raw(unsafe { make_mut(cs) }),
                 })
                 .collect::<Vec<_>>()
                 .into_py(py)
@@ -202,7 +205,7 @@ impl Py_ConfChangeV2_Ref {
 
     pub fn into_v2(&mut self) -> PyResult<Py_ConfChangeV2> {
         self.inner.map_as_mut(|inner| Py_ConfChangeV2 {
-            inner: inner.clone(),
+            inner: RefMutOwner::new(inner.clone()),
         })
     }
 }
diff --git a/src/raftpb_bindings/conf_state.rs b/src/raftpb_bindings/conf_state.rs
index 3922f7e..2ba6a1f 100644
--- a/src/raftpb_bindings/conf_state.rs
+++ b/src/raftpb_bindings/conf_state.rs
@@ -9,18 +9,18 @@ use raft::eraftpb::ConfState;
 
 use utils::errors::{runtime_error, to_pyresult};
 use utils::implement_type_conversion;
-use utils::reference::RustRef;
+use utils::reference::{RefMutContainer, RefMutOwner};
 
 #[derive(Clone)]
 #[pyclass(name = "ConfState")]
 pub struct Py_ConfState {
-    pub inner: ConfState,
+    pub inner: RefMutOwner<ConfState>,
 }
 
 #[derive(Clone)]
 #[pyclass(name = "ConfState_Ref")]
 pub struct Py_ConfState_Ref {
-    pub inner: RustRef<ConfState>,
+    pub inner: RefMutContainer<ConfState>,
 }
 
 #[derive(FromPyObject)]
@@ -37,7 +37,7 @@ impl Py_ConfState {
     pub fn new(voters: Option<&PyList>, learners: Option<&PyList>) -> PyResult<Self> {
         if voters.and(learners).is_none() {
             Ok(Py_ConfState {
-                inner: ConfState::new(),
+                inner: RefMutOwner::new(ConfState::new()),
             })
         } else if voters.or(learners).is_none() {
             Err(runtime_error(
@@ -47,7 +47,7 @@ impl Py_ConfState {
             let voters = voters.unwrap().extract::<Vec<u64>>()?;
             let learners = learners.unwrap().extract::<Vec<u64>>()?;
             Ok(Py_ConfState {
-                inner: ConfState::from((voters, learners)),
+                inner: RefMutOwner::new(ConfState::from((voters, learners))),
             })
         }
     }
@@ -55,33 +55,33 @@ impl Py_ConfState {
     #[staticmethod]
     pub fn default() -> Self {
         Py_ConfState {
-            inner: ConfState::default(),
+            inner: RefMutOwner::new(ConfState::default()),
         }
     }
 
     #[staticmethod]
     pub fn decode(v: &[u8]) -> PyResult<Py_ConfState> {
         Ok(Py_ConfState {
-            inner: to_pyresult(ProstMessage::decode(v))?,
+            inner: RefMutOwner::new(to_pyresult(ProstMessage::decode(v))?),
         })
     }
 
     pub fn make_ref(&mut self) -> Py_ConfState_Ref {
         Py_ConfState_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
     pub fn __repr__(&self) -> String {
-        format!("{:?}", self.inner)
+        format!("{:?}", self.inner.inner)
     }
 
     pub fn __richcmp__(&self, py: Python, rhs: Py_ConfState_Mut, op: CompareOp) -> PyObject {
         let rhs: ConfState = rhs.into();
 
         match op {
-            CompareOp::Eq => (self.inner == rhs).into_py(py),
-            CompareOp::Ne => (self.inner != rhs).into_py(py),
+            CompareOp::Eq => (self.inner.inner == rhs).into_py(py),
+            CompareOp::Ne => (self.inner.inner != rhs).into_py(py),
             _ => py.NotImplemented(),
         }
     }
@@ -117,7 +117,7 @@ impl Py_ConfState_Ref {
 
     pub fn clone(&self) -> PyResult<Py_ConfState> {
         Ok(Py_ConfState {
-            inner: self.inner.map_as_ref(|inner| inner.clone())?,
+            inner: RefMutOwner::new(self.inner.map_as_ref(|inner| inner.clone())?),
         })
     }
 
diff --git a/src/raftpb_bindings/entry.rs b/src/raftpb_bindings/entry.rs
index 12cdf16..9900fea 100644
--- a/src/raftpb_bindings/entry.rs
+++ b/src/raftpb_bindings/entry.rs
@@ -4,21 +4,22 @@ use pyo3::pyclass::CompareOp;
 use pyo3::types::PyBytes;
 use pyo3::{intern, prelude::*};
 use raft::eraftpb::Entry;
+use utils::errors::to_pyresult;
 use utils::implement_type_conversion;
-use utils::{errors::to_pyresult, reference::RustRef};
+use utils::reference::{RefMutContainer, RefMutOwner};
 
 use super::entry_type::Py_EntryType;
 
 #[derive(Clone)]
 #[pyclass(name = "Entry")]
 pub struct Py_Entry {
-    pub inner: Entry,
+    pub inner: RefMutOwner<Entry>,
 }
 
 #[derive(Clone)]
 #[pyclass(name = "Entry_Ref")]
 pub struct Py_Entry_Ref {
-    pub inner: RustRef<Entry>,
+    pub inner: RefMutContainer<Entry>,
 }
 
 #[derive(FromPyObject)]
@@ -34,40 +35,40 @@ impl Py_Entry {
     #[new]
     pub fn new() -> Self {
         Py_Entry {
-            inner: Entry::new(),
+            inner: RefMutOwner::new(Entry::new()),
         }
     }
 
     #[staticmethod]
     pub fn default() -> Self {
         Py_Entry {
-            inner: Entry::default(),
+            inner: RefMutOwner::new(Entry::default()),
         }
     }
 
     #[staticmethod]
     pub fn decode(v: &[u8]) -> PyResult<Py_Entry> {
         Ok(Py_Entry {
-            inner: to_pyresult(ProstMessage::decode(v))?,
+            inner: RefMutOwner::new(to_pyresult(ProstMessage::decode(v))?),
         })
     }
 
     pub fn make_ref(&mut self) -> Py_Entry_Ref {
         Py_Entry_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
     pub fn __repr__(&self) -> String {
-        format!("{:?}", self.inner)
+        format!("{:?}", self.inner.inner)
     }
 
     pub fn __richcmp__(&self, py: Python, rhs: Py_Entry_Mut, op: CompareOp) -> PyObject {
         let rhs: Entry = rhs.into();
 
         match op {
-            CompareOp::Eq => (self.inner == rhs).into_py(py),
-            CompareOp::Ne => (self.inner != rhs).into_py(py),
+            CompareOp::Eq => (self.inner.inner == rhs).into_py(py),
+            CompareOp::Ne => (self.inner.inner != rhs).into_py(py),
             _ => py.NotImplemented(),
         }
     }
@@ -98,7 +99,7 @@ impl Py_Entry_Ref {
 
     pub fn clone(&self) -> PyResult<Py_Entry> {
         Ok(Py_Entry {
-            inner: self.inner.map_as_ref(|x| x.clone())?,
+            inner: RefMutOwner::new(self.inner.map_as_ref(|x| x.clone())?),
         })
     }
 
diff --git a/src/raftpb_bindings/hard_state.rs b/src/raftpb_bindings/hard_state.rs
index 3698062..a344acb 100644
--- a/src/raftpb_bindings/hard_state.rs
+++ b/src/raftpb_bindings/hard_state.rs
@@ -4,18 +4,22 @@ use pyo3::{intern, prelude::*, pyclass::CompareOp, types::PyBytes};
 
 use raft::eraftpb::HardState;
 
-use utils::{errors::to_pyresult, implement_type_conversion, reference::RustRef};
+use utils::{
+    errors::to_pyresult,
+    implement_type_conversion,
+    reference::{RefMutContainer, RefMutOwner},
+};
 
 #[derive(Clone)]
 #[pyclass(name = "HardState")]
 pub struct Py_HardState {
-    pub inner: HardState,
+    pub inner: RefMutOwner<HardState>,
 }
 
 #[derive(Clone)]
 #[pyclass(name = "HardState_Ref")]
 pub struct Py_HardState_Ref {
-    pub inner: RustRef<HardState>,
+    pub inner: RefMutContainer<HardState>,
 }
 
 #[derive(FromPyObject)]
@@ -31,40 +35,40 @@ impl Py_HardState {
     #[new]
     pub fn new() -> Self {
         Py_HardState {
-            inner: HardState::new(),
+            inner: RefMutOwner::new(HardState::new()),
         }
     }
 
     #[staticmethod]
     pub fn default() -> Self {
         Py_HardState {
-            inner: HardState::default(),
+            inner: RefMutOwner::new(HardState::default()),
         }
     }
 
     #[staticmethod]
     pub fn decode(v: &[u8]) -> PyResult<Py_HardState> {
         Ok(Py_HardState {
-            inner: to_pyresult(ProstMessage::decode(v))?,
+            inner: RefMutOwner::new(to_pyresult(ProstMessage::decode(v))?),
         })
     }
 
     pub fn make_ref(&mut self) -> Py_HardState_Ref {
         Py_HardState_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
     pub fn __repr__(&mut self) -> String {
-        format!("{:?}", self.inner)
+        format!("{:?}", self.inner.inner)
     }
 
     pub fn __richcmp__(&self, py: Python, rhs: Py_HardState_Mut, op: CompareOp) -> PyObject {
         let rhs: HardState = rhs.into();
 
         match op {
-            CompareOp::Eq => (self.inner == rhs).into_py(py),
-            CompareOp::Ne => (self.inner != rhs).into_py(py),
+            CompareOp::Eq => (self.inner.inner == rhs).into_py(py),
+            CompareOp::Ne => (self.inner.inner != rhs).into_py(py),
             _ => py.NotImplemented(),
         }
     }
@@ -100,7 +104,7 @@ impl Py_HardState_Ref {
 
     pub fn clone(&self) -> PyResult<Py_HardState> {
         Ok(Py_HardState {
-            inner: self.inner.map_as_ref(|x| x.clone())?,
+            inner: RefMutOwner::new(self.inner.map_as_ref(|x| x.clone())?),
         })
     }
 
diff --git a/src/raftpb_bindings/message.rs b/src/raftpb_bindings/message.rs
index 6c36c6e..02d8a79 100644
--- a/src/raftpb_bindings/message.rs
+++ b/src/raftpb_bindings/message.rs
@@ -8,9 +8,12 @@ use pyo3::{
 };
 
 use raft::eraftpb::Message;
-use utils::{errors::to_pyresult, implement_type_conversion, unsafe_cast::make_mut};
-
-use utils::reference::RustRef;
+use utils::{
+    errors::to_pyresult,
+    implement_type_conversion,
+    reference::{RefMutContainer, RefMutOwner},
+    unsafe_cast::make_mut,
+};
 
 use super::{
     entry::{Py_Entry_Mut, Py_Entry_Ref},
@@ -21,13 +24,13 @@ use super::{
 #[derive(Clone)]
 #[pyclass(name = "Message")]
 pub struct Py_Message {
-    pub inner: Message,
+    pub inner: RefMutOwner<Message>,
 }
 
 #[derive(Clone)]
 #[pyclass(name = "Message_Ref")]
 pub struct Py_Message_Ref {
-    pub inner: RustRef<Message>,
+    pub inner: RefMutContainer<Message>,
 }
 
 #[derive(FromPyObject)]
@@ -43,40 +46,40 @@ impl Py_Message {
     #[new]
     pub fn new() -> Self {
         Py_Message {
-            inner: Message::new(),
+            inner: RefMutOwner::new(Message::new()),
         }
     }
 
     #[staticmethod]
     pub fn default() -> Self {
         Py_Message {
-            inner: Message::default(),
+            inner: RefMutOwner::new(Message::default()),
         }
     }
 
     #[staticmethod]
     pub fn decode(v: &[u8]) -> PyResult<Py_Message> {
         Ok(Py_Message {
-            inner: to_pyresult(ProstMessage::decode(v))?,
+            inner: RefMutOwner::new(to_pyresult(ProstMessage::decode(v))?),
         })
     }
 
     pub fn make_ref(&mut self) -> Py_Message_Ref {
         Py_Message_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
     pub fn __repr__(&self) -> String {
-        format!("{:?}", self.inner)
+        format!("{:?}", self.inner.inner)
     }
 
     pub fn __richcmp__(&self, py: Python, rhs: Py_Message_Mut, op: CompareOp) -> PyObject {
         let rhs: Message = rhs.into();
 
         match op {
-            CompareOp::Eq => (self.inner == rhs).into_py(py),
-            CompareOp::Ne => (self.inner != rhs).into_py(py),
+            CompareOp::Eq => (self.inner.inner == rhs).into_py(py),
+            CompareOp::Ne => (self.inner.inner != rhs).into_py(py),
             _ => py.NotImplemented(),
         }
     }
@@ -112,7 +115,7 @@ impl Py_Message_Ref {
 
     pub fn clone(&self) -> PyResult<Py_Message> {
         Ok(Py_Message {
-            inner: self.inner.map_as_ref(|x| x.clone())?,
+            inner: RefMutOwner::new(self.inner.map_as_ref(|x| x.clone())?),
         })
     }
 
@@ -237,7 +240,7 @@ impl Py_Message_Ref {
                 .get_entries()
                 .iter()
                 .map(|entry| Py_Entry_Ref {
-                    inner: RustRef::new(unsafe { make_mut(entry) }),
+                    inner: RefMutContainer::new_raw(unsafe { make_mut(entry) }),
                 })
                 .collect::<Vec<_>>();
 
@@ -285,7 +288,7 @@ impl Py_Message_Ref {
 
     pub fn get_snapshot(&mut self) -> PyResult<Py_Snapshot_Ref> {
         self.inner.map_as_mut(|inner| Py_Snapshot_Ref {
-            inner: RustRef::new(inner.mut_snapshot()),
+            inner: RefMutContainer::new_raw(inner.mut_snapshot()),
         })
     }
 
diff --git a/src/raftpb_bindings/snapshot.rs b/src/raftpb_bindings/snapshot.rs
index 90a977b..edd5916 100644
--- a/src/raftpb_bindings/snapshot.rs
+++ b/src/raftpb_bindings/snapshot.rs
@@ -3,20 +3,24 @@ use protobuf::Message as PbMessage;
 use pyo3::{intern, prelude::*, pyclass::CompareOp, types::PyBytes};
 
 use raft::eraftpb::Snapshot;
-use utils::{errors::to_pyresult, implement_type_conversion, reference::RustRef};
+use utils::{
+    errors::to_pyresult,
+    implement_type_conversion,
+    reference::{RefMutContainer, RefMutOwner},
+};
 
 use super::snapshot_metadata::{Py_SnapshotMetadata_Mut, Py_SnapshotMetadata_Ref};
 
 #[derive(Clone)]
 #[pyclass(name = "Snapshot")]
 pub struct Py_Snapshot {
-    pub inner: Snapshot,
+    pub inner: RefMutOwner<Snapshot>,
 }
 
 #[derive(Clone)]
 #[pyclass(name = "Snapshot_Ref")]
 pub struct Py_Snapshot_Ref {
-    pub inner: RustRef<Snapshot>,
+    pub inner: RefMutContainer<Snapshot>,
 }
 
 #[derive(FromPyObject)]
@@ -32,32 +36,32 @@ impl Py_Snapshot {
     #[new]
     pub fn new() -> Self {
         Py_Snapshot {
-            inner: Snapshot::new(),
+            inner: RefMutOwner::new(Snapshot::new()),
         }
     }
 
     #[staticmethod]
     pub fn default() -> Py_Snapshot {
         Py_Snapshot {
-            inner: Snapshot::default(),
+            inner: RefMutOwner::new(Snapshot::default()),
         }
     }
 
     #[staticmethod]
     pub fn decode(v: &[u8]) -> PyResult<Py_Snapshot> {
         Ok(Py_Snapshot {
-            inner: to_pyresult(ProstMessage::decode(v))?,
+            inner: RefMutOwner::new(to_pyresult(ProstMessage::decode(v))?),
         })
     }
 
     pub fn make_ref(&mut self) -> Py_Snapshot_Ref {
         Py_Snapshot_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
     pub fn __repr__(&self) -> String {
-        format!("{:?}", self.inner)
+        format!("{:?}", self.inner.inner)
     }
 
     pub fn __bool__(&self) -> bool {
@@ -68,8 +72,8 @@ impl Py_Snapshot {
         let rhs: Snapshot = rhs.into();
 
         match op {
-            CompareOp::Eq => (self.inner == rhs).into_py(py),
-            CompareOp::Ne => (self.inner != rhs).into_py(py),
+            CompareOp::Eq => (self.inner.inner == rhs).into_py(py),
+            CompareOp::Ne => (self.inner.inner != rhs).into_py(py),
             _ => py.NotImplemented(),
         }
     }
@@ -109,7 +113,7 @@ impl Py_Snapshot_Ref {
 
     pub fn clone(&self) -> PyResult<Py_Snapshot> {
         Ok(Py_Snapshot {
-            inner: self.inner.map_as_ref(|inner| inner.clone())?,
+            inner: RefMutOwner::new(self.inner.map_as_ref(|inner| inner.clone())?),
         })
     }
 
@@ -134,7 +138,7 @@ impl Py_Snapshot_Ref {
 
     pub fn get_metadata(&mut self) -> PyResult<Py_SnapshotMetadata_Ref> {
         self.inner.map_as_mut(|inner| Py_SnapshotMetadata_Ref {
-            inner: RustRef::new(inner.mut_metadata()),
+            inner: RefMutContainer::new_raw(inner.mut_metadata()),
         })
     }
 
diff --git a/src/raftpb_bindings/snapshot_metadata.rs b/src/raftpb_bindings/snapshot_metadata.rs
index 6ac88e6..6cf1eba 100644
--- a/src/raftpb_bindings/snapshot_metadata.rs
+++ b/src/raftpb_bindings/snapshot_metadata.rs
@@ -4,20 +4,24 @@ use pyo3::{intern, prelude::*, pyclass::CompareOp, types::PyBytes};
 
 use raft::eraftpb::SnapshotMetadata;
 
-use utils::{errors::to_pyresult, implement_type_conversion, reference::RustRef};
+use utils::{
+    errors::to_pyresult,
+    implement_type_conversion,
+    reference::{RefMutContainer, RefMutOwner},
+};
 
 use super::conf_state::{Py_ConfState_Mut, Py_ConfState_Ref};
 
 #[derive(Clone)]
 #[pyclass(name = "SnapshotMetadata")]
 pub struct Py_SnapshotMetadata {
-    pub inner: SnapshotMetadata,
+    pub inner: RefMutOwner<SnapshotMetadata>,
 }
 
 #[derive(Clone)]
 #[pyclass(name = "SnapshotMetadata_Ref")]
 pub struct Py_SnapshotMetadata_Ref {
-    pub inner: RustRef<SnapshotMetadata>,
+    pub inner: RefMutContainer<SnapshotMetadata>,
 }
 
 #[derive(FromPyObject)]
@@ -33,40 +37,40 @@ impl Py_SnapshotMetadata {
     #[new]
     pub fn new() -> Self {
         Py_SnapshotMetadata {
-            inner: SnapshotMetadata::new(),
+            inner: RefMutOwner::new(SnapshotMetadata::new()),
         }
     }
 
     #[staticmethod]
     pub fn default() -> Py_SnapshotMetadata {
         Py_SnapshotMetadata {
-            inner: SnapshotMetadata::default(),
+            inner: RefMutOwner::new(SnapshotMetadata::default()),
         }
     }
 
     #[staticmethod]
     pub fn decode(v: &[u8]) -> PyResult<Py_SnapshotMetadata> {
         Ok(Py_SnapshotMetadata {
-            inner: to_pyresult(ProstMessage::decode(v))?,
+            inner: RefMutOwner::new(to_pyresult(ProstMessage::decode(v))?),
         })
     }
 
     pub fn make_ref(&mut self) -> Py_SnapshotMetadata_Ref {
         Py_SnapshotMetadata_Ref {
-            inner: RustRef::new(&mut self.inner),
+            inner: RefMutContainer::new(&mut self.inner),
         }
     }
 
     pub fn __repr__(&self) -> String {
-        format!("{:?}", self.inner)
+        format!("{:?}", self.inner.inner)
     }
 
     pub fn __richcmp__(&self, py: Python, rhs: Py_SnapshotMetadata_Mut, op: CompareOp) -> PyObject {
         let rhs: SnapshotMetadata = rhs.into();
 
         match op {
-            CompareOp::Eq => (self.inner == rhs).into_py(py),
-            CompareOp::Ne => (self.inner != rhs).into_py(py),
+            CompareOp::Eq => (self.inner.inner == rhs).into_py(py),
+            CompareOp::Ne => (self.inner.inner != rhs).into_py(py),
             _ => py.NotImplemented(),
         }
     }
@@ -102,7 +106,7 @@ impl Py_SnapshotMetadata_Ref {
 
     pub fn clone(&self) -> PyResult<Py_SnapshotMetadata> {
         Ok(Py_SnapshotMetadata {
-            inner: self.inner.map_as_ref(|inner| inner.clone())?,
+            inner: RefMutOwner::new(self.inner.map_as_ref(|inner| inner.clone())?),
         })
     }
 
@@ -137,7 +141,7 @@ impl Py_SnapshotMetadata_Ref {
 
     pub fn get_conf_state(&mut self) -> PyResult<Py_ConfState_Ref> {
         self.inner.map_as_mut(|inner| Py_ConfState_Ref {
-            inner: RustRef::new(inner.mut_conf_state()),
+            inner: RefMutContainer::new_raw(inner.mut_conf_state()),
         })
     }
 
diff --git a/src/utils/errors.rs b/src/utils/errors.rs
index e8c85d4..749e22d 100644
--- a/src/utils/errors.rs
+++ b/src/utils/errors.rs
@@ -1,4 +1,5 @@
 use core::panic;
+use std::fmt::Display;
 
 use pyo3::{
     create_exception,
@@ -109,7 +110,7 @@ impl From<Py_StorageError> for PyErr {
 
 // Convert 'PyErr' to 'raft::Error' for passing the error to raft-rs
 // TODO: Complete below error handling logics.
-pub fn makeNativeRaftError(py: Python, py_err: PyErr) -> raft::Error {
+pub fn make_native_raft_error(py: Python, py_err: PyErr) -> raft::Error {
     let args = py_err.to_object(py).getattr(py, "args").unwrap();
     let args = args.downcast::<PyTuple>(py).unwrap();
 
@@ -165,7 +166,7 @@ pub fn makeNativeRaftError(py: Python, py_err: PyErr) -> raft::Error {
 
     if py_err.is_instance_of::<StoreError>(py) {
         let err_kind = args.get_item(0).unwrap();
-        return makeNativeStorageError(py_err, err_kind);
+        return make_native_storage_error(py_err, err_kind);
     }
 
     if py_err.is_instance_of::<CodecError>(py) {
@@ -176,7 +177,7 @@ pub fn makeNativeRaftError(py: Python, py_err: PyErr) -> raft::Error {
     panic!("Unreachable")
 }
 
-fn makeNativeStorageError(py_err: PyErr, err_kind: &PyAny) -> raft::Error {
+fn make_native_storage_error(py_err: PyErr, err_kind: &PyAny) -> raft::Error {
     if err_kind.is_instance_of::<CompactedError>() {
         return raft::Error::Store(raft::StorageError::Compacted);
     }
@@ -226,13 +227,15 @@ create_exception!(rraft, UnavailableError, RaftStorageError);
 create_exception!(rraft, LogTemporarilyUnavailableError, RaftStorageError);
 create_exception!(rraft, OtherError, RaftStorageError);
 
+create_exception!(rraft, DestroyedRefUsedError, PyException);
+
 #[inline]
 pub fn runtime_error(msg: &str) -> PyErr {
     PyException::new_err(msg.to_string())
 }
 
 #[inline]
-pub fn to_pyresult<T, E: std::fmt::Display>(res: Result<T, E>) -> PyResult<T> {
+pub fn to_pyresult<T, E: Display>(res: Result<T, E>) -> PyResult<T> {
     res.map_err(|err| PyRuntimeError::new_err(err.to_string()))
 }
 
diff --git a/src/utils/reference.rs b/src/utils/reference.rs
index e7ad22f..0b6fcb3 100644
--- a/src/utils/reference.rs
+++ b/src/utils/reference.rs
@@ -1,74 +1,103 @@
-// Ref:: https://github.com/huggingface/tokenizers/tree/main/bindings/python
+// Ref:
+// RefMutContainer implementation is greatly inspired from huggingface/tokenizer's python binding's.
+// https://github.com/huggingface/tokenizers/blob/main/bindings/python/src/utils/mod.rs
 use pyo3::prelude::*;
-use pyo3::PyErr;
-use std::sync::{Arc, Mutex};
+use std::ops::{Deref, DerefMut};
+use std::ptr::NonNull;
+use std::sync::{Arc, Mutex, Weak};
 
-use crate::errors::runtime_error;
+use crate::errors::DestroyedRefUsedError;
 use crate::errors::DESTROYED_ERR_MSG;
 
 #[derive(Clone)]
-pub struct RefMutContainer<T> {
-    inner: Arc<Mutex<Option<*mut T>>>,
+pub struct RefMutOwner<T> {
+    pub inner: T,
+    // List of references that need to be cleaned up.
+    refs: Vec<Weak<Mutex<Option<NonNull<T>>>>>,
 }
 
-impl<T> RefMutContainer<T> {
-    pub fn new(content: &mut T) -> Self {
+unsafe impl<T: Send> Send for RefMutOwner<T> {}
+unsafe impl<T: Sync> Sync for RefMutOwner<T> {}
+
+impl<T> RefMutOwner<T> {
+    pub fn new(inner: T) -> Self {
         Self {
-            inner: Arc::new(Mutex::new(Some(content))),
+            inner,
+            refs: vec![],
         }
     }
+}
 
-    pub fn map<F: FnOnce(&T) -> U, U>(&self, f: F) -> Option<U> {
-        let lock = self.inner.lock().unwrap();
-        let ptr = lock.as_ref()?;
-        Some(f(unsafe { ptr.as_ref().unwrap() }))
+impl<T> Deref for RefMutOwner<T> {
+    type Target = T;
+
+    fn deref(&self) -> &Self::Target {
+        &self.inner
     }
+}
 
-    pub fn map_mut<F: FnOnce(&mut T) -> U, U>(&mut self, f: F) -> Option<U> {
-        let lock = self.inner.lock().unwrap();
-        let ptr = lock.as_ref()?;
-        Some(f(unsafe { ptr.as_mut().unwrap() }))
+impl<T> DerefMut for RefMutOwner<T> {
+    fn deref_mut(&mut self) -> &mut T {
+        &mut self.inner
     }
 }
 
-impl<T> Drop for RefMutContainer<T> {
+impl<T> Drop for RefMutOwner<T> {
     fn drop(&mut self) {
-        self.inner.lock().unwrap().take();
+        self.refs.iter_mut().for_each(|weak_ref| {
+            if let Some(arc) = weak_ref.upgrade() {
+                if let Ok(mut ptr) = arc.lock() {
+                    ptr.take();
+                }
+            }
+        });
     }
 }
 
-unsafe impl<T: Send> Send for RefMutContainer<T> {}
-unsafe impl<T: Sync> Sync for RefMutContainer<T> {}
-
 #[derive(Clone)]
-pub struct RustRef<FromRust>(pub RefMutContainer<FromRust>);
+pub struct RefMutContainer<T> {
+    inner: Arc<Mutex<Option<NonNull<T>>>>,
+}
+
+impl<T> RefMutContainer<T> {
+    pub fn new(content: &mut RefMutOwner<T>) -> Self {
+        let arc = Arc::new(Mutex::new(NonNull::new(&mut content.inner)));
+        content.refs.push(Arc::downgrade(&arc));
+        RefMutContainer { inner: arc }
+    }
 
-impl<FromRust> RustRef<FromRust> {
-    pub fn new(s: &mut FromRust) -> Self {
-        Self(RefMutContainer::new(s))
+    pub fn new_raw(content: &mut T) -> Self {
+        RefMutContainer {
+            inner: Arc::new(Mutex::new(NonNull::new(content))),
+        }
     }
 
-    /// Provides a way to access a reference to the underlying data
     pub fn map_as_ref<F, U>(&self, f: F) -> PyResult<U>
     where
-        F: FnOnce(&FromRust) -> U,
+        F: FnOnce(&T) -> U,
     {
-        self.0.map(f).ok_or_else(Self::destroyed_error)
+        let lock = self.inner.lock().unwrap();
+        let ptr = lock
+            .as_ref()
+            .ok_or(DestroyedRefUsedError::new_err(DESTROYED_ERR_MSG))?;
+        Ok(f(unsafe { ptr.as_ref() }))
     }
 
-    /// Provides a way to access a mutable reference to the underlying data
     pub fn map_as_mut<F, U>(&mut self, f: F) -> PyResult<U>
     where
-        F: FnOnce(&mut FromRust) -> U,
+        F: FnOnce(&mut T) -> U,
     {
-        self.0.map_mut(f).ok_or_else(Self::destroyed_error)
-    }
-
-    pub fn destroyed_error() -> PyErr {
-        runtime_error(DESTROYED_ERR_MSG)
+        let mut lock = self.inner.lock().unwrap();
+        let ptr = lock
+            .as_mut()
+            .ok_or(DestroyedRefUsedError::new_err(DESTROYED_ERR_MSG))?;
+        Ok(f(unsafe { ptr.as_mut() }))
     }
 }
 
+unsafe impl<T: Send> Send for RefMutContainer<T> {}
+unsafe impl<T: Sync> Sync for RefMutContainer<T> {}
+
 #[macro_export]
 // This macro accepts the raft-rs (Rust) type as the first argument and the Py type as the second argument,
 // And adds some boilerplate codes implementing the From trait for conversion between the two types.
@@ -79,7 +108,7 @@ macro_rules! implement_type_conversion {
         impl From<$Py_Typ_Mut<'_>> for $Typ {
             fn from(val: $Py_Typ_Mut<'_>) -> Self {
                 match val {
-                    $Py_Typ_Mut::Owned(x) => x.inner.clone(),
+                    $Py_Typ_Mut::Owned(x) => x.inner.inner.clone(),
                     $Py_Typ_Mut::RefMut(mut x) => {
                         x.inner.map_as_mut(|x| x.clone()).expect(DESTROYED_ERR_MSG)
                     }
@@ -90,7 +119,7 @@ macro_rules! implement_type_conversion {
         impl From<&mut $Py_Typ_Mut<'_>> for $Typ {
             fn from(val: &mut $Py_Typ_Mut<'_>) -> Self {
                 match val {
-                    $Py_Typ_Mut::Owned(x) => x.inner.clone(),
+                    $Py_Typ_Mut::Owned(x) => x.inner.inner.clone(),
                     $Py_Typ_Mut::RefMut(x) => {
                         x.inner.map_as_mut(|x| x.clone()).expect(DESTROYED_ERR_MSG)
                     }


Test patch:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 624316f..5410fcc 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -1,4 +1,4 @@
-name: Test Automation
+name: Build, Lint, and Check all harness tests pass
 
 on:
   pull_request:
@@ -9,34 +9,32 @@ permissions:
   contents: read
 
 jobs:
-  test-rraft-py:
+  test:
     runs-on: ubuntu-latest
     steps:
     - uses: actions/checkout@v3
+
     - name: Set up Python
       uses: actions/setup-python@v3
       with:
         python-version: "3.10"
+
     - name: Set up pip and requirements
       run: |
         python -m pip install --upgrade pip
         pip install -r requirements.txt
+
     - name: Install protobuf compiler
       run: |
         sudo apt install -y protobuf-compiler
+
     - name: Set up Rust toolchain
       uses: actions-rs/toolchain@v1
       with:
         toolchain: nightly
-        components: rustfmt, clippy
-    - name: Set up Cargo
-      uses: actions-rs/cargo@v1
-    - name: Use rust nightly
-      run: |
-        rustup toolchain install nightly
-        rustup override set nightly
+        override: true
+
     - name: Build and Test
       run: |
-        make lint
         make install
-        make test
+        make test
\ No newline at end of file
diff --git a/harness/tests/test_raft.py b/harness/tests/test_raft.py
index b43f1db..a647934 100644
--- a/harness/tests/test_raft.py
+++ b/harness/tests/test_raft.py
@@ -3550,11 +3550,13 @@ def new_test_learner_raft(
     storage: MemStorage_Ref,
     logger: Logger_Ref,
 ) -> Interface:
+    initial_state = storage.initial_state()
+
     assert not (
-        storage.initial_state().initialized() and not peers
+        initial_state.initialized() and not peers
     ), f"new_test_raft with empty peers on initialized store"
 
-    if peers and not storage.initial_state().initialized():
+    if peers and not initial_state.initialized():
         storage.initialize_with_conf_state(ConfState(peers, learners))
 
     cfg = new_test_config(id, election, heartbeat)
@@ -4250,7 +4252,8 @@ def test_advance_commit_index_by_vote_request(use_prevote: bool):
             e.set_data(v1.encode())
         else:
             e.set_entry_type(EntryType.EntryConfChangeV2)
-            e.set_data(cc.as_v2().encode())
+            v2 = cc.as_v2()
+            e.set_data(v2.encode())
 
         # propose a confchange entry but don't let it commit
         nt.ignore(MessageType.MsgAppendResponse)
@@ -4381,7 +4384,8 @@ def test_advance_commit_index_by_vote_response(use_prevote: bool):
             e.set_data(v1.encode())
         else:
             e.set_entry_type(EntryType.EntryConfChangeV2)
-            e.set_data(cc.as_v2().encode())
+            v2 = cc.as_v2()
+            e.set_data(v2.encode())
 
         # propose a confchange entry but don't let it commit
         nt.ignore(MessageType.MsgAppendResponse)
diff --git a/harness/tests/test_raw_node.py b/harness/tests/test_raw_node.py
index 59a858e..a55b577 100644
--- a/harness/tests/test_raw_node.py
+++ b/harness/tests/test_raw_node.py
@@ -100,11 +100,12 @@ def new_raw_node_with_config(
     storage: MemStorage,
     logger: Logger_Ref,
 ) -> InMemoryRawNode:
+    initial_state = storage.initial_state()
     assert not (
-        storage.initial_state().initialized() and not peers
+        initial_state.initialized() and not peers
     ), f"new_raw_node with empty peers on initialized store"
 
-    if peers and not storage.initial_state().initialized():
+    if peers and not initial_state.initialized():
         storage.wl().apply_snapshot(new_snapshot(1, 1, peers))
 
     return InMemoryRawNode(config, storage, logger)
@@ -399,7 +400,8 @@ def handle_committed_entries(
         assert cs == exp
 
         conf_index = last_index
-        if cc.as_v2().enter_joint():
+        v2 = cc.as_v2()
+        if v2.enter_joint():
             # If this is an auto-leaving joint conf change, it will have
             # appended the entry that auto-leaves, so add one to the last
             # index that forms the basis of our expectations on