@@ -210,41 +210,51 @@ module ol_framework::page_rank_lazy {
210210
211211 // Mark a user's trust score as stale
212212 public (friend ) fun mark_as_stale (user: address ) acquires UserTrustRecord {
213- walk_stale (user, &vector ::empty <address >(), &mut 0 );
213+ let visited = vector ::empty <address >();
214+ let processed_count: u64 = 0 ; // Initialize as a mutable local variable
215+ walk_stale (user, &mut visited, &mut processed_count); // Pass as a mutable reference
214216 }
217+
215218 // Internal helper function with cycle detection for marking nodes as stale
216219 // Uses vouch module to get outgoing vouches
217220 fun walk_stale (
218221 user: address ,
219- visited: &vector <address >,
220- processed_count: &mut u64
222+ visited: &mut vector <address >,
223+ processed_count: &mut u64 // Changed to mutable reference
221224 ) acquires UserTrustRecord {
222-
223- // Circuit breaker: stop processing if we've hit our limit
224- assert !(*processed_count < MAX_PROCESSED_ADDRESSES , error::invalid_state (EMAX_PROCESSED_ADDRESSES ));
225-
226- // Skip if we've already visited this node (cycle detection)
225+ // Skip if we've already visited this node in the current traversal (cycle detection)
226+ // This also ensures we only count/process each unique node once.
227227 if (vector ::contains (visited, &user)) {
228228 return
229229 };
230230
231- // Increment the number of addresses we've processed
231+ // Check if the global limit for processed nodes has been reached *before* processing this one.
232+ // If *processed_count is already at the limit, we can't process another new node.
233+ if (*processed_count >= MAX_PROCESSED_ADDRESSES ) {
234+ return
235+ };
236+
237+ // This node is new and will be processed. Increment the global count.
232238 *processed_count = *processed_count + 1 ;
233239
234- // Mark this user's record as stale if it exists
240+ // Process the current 'user' node:
241+ // 1. Mark its UserTrustRecord as stale if it exists.
235242 if (exists <UserTrustRecord >(user)) {
236243 let record = borrow_global_mut <UserTrustRecord >(user);
237244 record.is_stale = true ;
238245 };
239246
240- // Get outgoing vouches from vouch module
241- let (outgoing_vouches, _) = vouch::get_given_vouches (user);
242-
243- // Create a new visited list that includes the current node
244- let new_visited = *visited; // Clone the visited list
245- vector ::push_back (&mut new_visited, user);
247+ // 2. Add this node to the visited set for the current traversal.
248+ vector ::push_back (visited, user);
246249
250+ // If the user is not initialized in the vouch system, they cannot have outgoing vouches.
251+ // Staleness propagation stops here for this path, but 'user' itself has been processed and counted.
252+ if (!vouch::is_init (user)) {
253+ return
254+ };
247255
256+ // Now walk their outgoing vouches
257+ let (outgoing_vouches, _) = vouch::get_given_vouches (user);
248258 if (vector ::length (&outgoing_vouches) == 0 ) {
249259 return
250260 };
@@ -254,20 +264,10 @@ module ol_framework::page_rank_lazy {
254264 let len = vector ::length (&outgoing_vouches);
255265 while (i < len) {
256266 let each_vouchee = vector ::borrow (&outgoing_vouches, i);
257- // Mark this user's record as stale if it exists
258- if (exists <UserTrustRecord >(*each_vouchee)) {
259- let record = borrow_global_mut <UserTrustRecord >(user);
260- record.is_stale = true ;
261- };
262-
263- // Pass the updated visited list to avoid cycles
264- walk_stale (*each_vouchee, &new_visited, processed_count);
265-
266- // If we've hit the circuit breaker, stop processing
267- if (*processed_count >= MAX_PROCESSED_ADDRESSES ) {
268- break
269- };
270-
267+ // Pass the same mutable reference to processed_count.
268+ // The checks at the beginning of the recursive call (visited and limit)
269+ // will handle whether to proceed for 'each_vouchee'.
270+ walk_stale (*each_vouchee, visited, processed_count);
271271 i = i + 1 ;
272272 };
273273 }
0 commit comments