@@ -153,7 +153,9 @@ class CDeterministicMNList
153
153
// for multiple CDeterministicMNList until mnMap is actually changed.
154
154
// Calls of AddMN, RemoveMN and (in some cases) UpdateMN reset this cache;
155
155
// 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);
157
159
158
160
public:
159
161
CDeterministicMNList () = default ;
@@ -165,6 +167,36 @@ class CDeterministicMNList
165
167
assert (nHeight >= 0 );
166
168
}
167
169
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
+
168
200
template <typename Stream, typename Operation>
169
201
inline void SerializationOpBase (Stream& s, Operation ser_action)
170
202
{
@@ -205,7 +237,10 @@ class CDeterministicMNList
205
237
mnMap = MnMap ();
206
238
mnUniquePropertyMap = MnUniquePropertyMap ();
207
239
mnInternalIdMap = MnInternalIdMap ();
208
- m_cached_sml = nullptr ;
240
+ {
241
+ LOCK (m_cached_sml_mutex);
242
+ m_cached_sml = nullptr ;
243
+ }
209
244
}
210
245
211
246
[[nodiscard]] size_t GetAllMNsCount () const
@@ -327,6 +362,7 @@ class CDeterministicMNList
327
362
328
363
/* *
329
364
* Calculates CSimplifiedMNList for current list and cache it
365
+ * Thread safety: Uses internal mutex for thread-safe cache access
330
366
*/
331
367
gsl::not_null<std::shared_ptr<const CSimplifiedMNList>> to_sml () const ;
332
368
0 commit comments