@@ -153,7 +153,9 @@ class CDeterministicMNList
153153 // for multiple CDeterministicMNList until mnMap is actually changed.
154154 // Calls of AddMN, RemoveMN and (in some cases) UpdateMN reset this cache;
155155 // it happens also for indirect calls such as ApplyDiff
156- mutable std::shared_ptr<const CSimplifiedMNList> m_cached_sml;
156+ // Thread safety: Protected by its own mutex for thread-safe access
157+ mutable Mutex m_cached_sml_mutex;
158+ mutable std::shared_ptr<const CSimplifiedMNList> m_cached_sml GUARDED_BY (m_cached_sml_mutex);
157159
158160public:
159161 CDeterministicMNList () = default ;
@@ -165,6 +167,36 @@ class CDeterministicMNList
165167 assert (nHeight >= 0 );
166168 }
167169
170+ // Copy constructor
171+ CDeterministicMNList (const CDeterministicMNList& other) :
172+ blockHash (other.blockHash),
173+ nHeight (other.nHeight),
174+ nTotalRegisteredCount (other.nTotalRegisteredCount),
175+ mnMap (other.mnMap),
176+ mnInternalIdMap (other.mnInternalIdMap),
177+ mnUniquePropertyMap (other.mnUniquePropertyMap)
178+ {
179+ LOCK (other.m_cached_sml_mutex );
180+ m_cached_sml = other.m_cached_sml ;
181+ }
182+
183+ // Assignment operator
184+ CDeterministicMNList& operator =(const CDeterministicMNList& other)
185+ {
186+ if (this != &other) {
187+ blockHash = other.blockHash ;
188+ nHeight = other.nHeight ;
189+ nTotalRegisteredCount = other.nTotalRegisteredCount ;
190+ mnMap = other.mnMap ;
191+ mnInternalIdMap = other.mnInternalIdMap ;
192+ mnUniquePropertyMap = other.mnUniquePropertyMap ;
193+
194+ LOCK2 (m_cached_sml_mutex, other.m_cached_sml_mutex );
195+ m_cached_sml = other.m_cached_sml ;
196+ }
197+ return *this ;
198+ }
199+
168200 template <typename Stream, typename Operation>
169201 inline void SerializationOpBase (Stream& s, Operation ser_action)
170202 {
@@ -205,7 +237,10 @@ class CDeterministicMNList
205237 mnMap = MnMap ();
206238 mnUniquePropertyMap = MnUniquePropertyMap ();
207239 mnInternalIdMap = MnInternalIdMap ();
208- m_cached_sml = nullptr ;
240+ {
241+ LOCK (m_cached_sml_mutex);
242+ m_cached_sml = nullptr ;
243+ }
209244 }
210245
211246 [[nodiscard]] size_t GetAllMNsCount () const
@@ -327,6 +362,7 @@ class CDeterministicMNList
327362
328363 /* *
329364 * Calculates CSimplifiedMNList for current list and cache it
365+ * Thread safety: Uses internal mutex for thread-safe cache access
330366 */
331367 gsl::not_null<std::shared_ptr<const CSimplifiedMNList>> to_sml () const ;
332368
0 commit comments