@@ -179,7 +179,9 @@ class CDeterministicMNList
179179 // for multiple CDeterministicMNList until mnMap is actually changed.
180180 // Calls of AddMN, RemoveMN and (in some cases) UpdateMN reset this cache;
181181 // it happens also for indirect calls such as ApplyDiff
182- mutable std::shared_ptr<const CSimplifiedMNList> m_cached_sml;
182+ // Thread safety: Protected by its own mutex for thread-safe access
183+ mutable Mutex m_cached_sml_mutex;
184+ mutable std::shared_ptr<const CSimplifiedMNList> m_cached_sml GUARDED_BY (m_cached_sml_mutex);
183185
184186public:
185187 CDeterministicMNList () = default ;
@@ -191,6 +193,36 @@ class CDeterministicMNList
191193 assert (nHeight >= 0 );
192194 }
193195
196+ // Copy constructor
197+ CDeterministicMNList (const CDeterministicMNList& other) :
198+ blockHash (other.blockHash),
199+ nHeight (other.nHeight),
200+ nTotalRegisteredCount (other.nTotalRegisteredCount),
201+ mnMap (other.mnMap),
202+ mnInternalIdMap (other.mnInternalIdMap),
203+ mnUniquePropertyMap (other.mnUniquePropertyMap)
204+ {
205+ LOCK (other.m_cached_sml_mutex );
206+ m_cached_sml = other.m_cached_sml ;
207+ }
208+
209+ // Assignment operator
210+ CDeterministicMNList& operator =(const CDeterministicMNList& other)
211+ {
212+ if (this != &other) {
213+ blockHash = other.blockHash ;
214+ nHeight = other.nHeight ;
215+ nTotalRegisteredCount = other.nTotalRegisteredCount ;
216+ mnMap = other.mnMap ;
217+ mnInternalIdMap = other.mnInternalIdMap ;
218+ mnUniquePropertyMap = other.mnUniquePropertyMap ;
219+
220+ LOCK2 (m_cached_sml_mutex, other.m_cached_sml_mutex );
221+ m_cached_sml = other.m_cached_sml ;
222+ }
223+ return *this ;
224+ }
225+
194226 template <typename Stream, typename Operation>
195227 inline void SerializationOpBase (Stream& s, Operation ser_action)
196228 {
@@ -215,7 +247,10 @@ class CDeterministicMNList
215247 mnMap = MnMap ();
216248 mnUniquePropertyMap = MnUniquePropertyMap ();
217249 mnInternalIdMap = MnInternalIdMap ();
218- m_cached_sml = nullptr ;
250+ {
251+ LOCK (m_cached_sml_mutex);
252+ m_cached_sml = nullptr ;
253+ }
219254
220255 SerializationOpBase (s, CSerActionUnserialize ());
221256
@@ -344,6 +379,7 @@ class CDeterministicMNList
344379
345380 /* *
346381 * Calculates CSimplifiedMNList for current list and cache it
382+ * Thread safety: Uses internal mutex for thread-safe cache access
347383 */
348384 gsl::not_null<std::shared_ptr<const CSimplifiedMNList>> to_sml () const ;
349385
0 commit comments