diff --git a/src/app/sync.rs b/src/app/sync.rs index 52c97ce..42af91b 100644 --- a/src/app/sync.rs +++ b/src/app/sync.rs @@ -293,8 +293,7 @@ impl AppaService { return Ok(None); } self.save_peer_response(folder, &peer, &roster, peer_endpoints, &capability)?; - self.receive_peer_audit_events(context, &peer) - .await?; + self.receive_peer_audit_events(context, &peer).await?; if summary.root_hash == manifest_root_hash(local_manifest)? { tracing::debug!(folder = %folder.name, peer = %peer.id, "Folder roots match; skipping manifest transfer"); return Ok(None); @@ -339,48 +338,48 @@ impl AppaService { peer: &iroh::EndpointAddr, ) -> AppResult<()> { loop { - let events = match context - .node - .request_audit_events( - peer.clone(), - context.folder.id, - context.folder.capability.clone(), - self.state_store.join_invite(context.folder.id)?, - self.state_store - .audit_heads(context.folder.id)? - .into_iter() - .map(|head| (head.author_device_id, head.sequence)) - .collect(), - ) - .await - { - Ok(events) => events, - Err(error) => { - tracing::debug!(folder = %context.folder.name, peer = %peer.id, %error, "peer did not provide audit events"); - return Ok(()); - } - }; - let is_last_page = events.len() < MAX_AUDIT_EVENTS_PER_RESPONSE; - for event in events { - if event.folder_id != context.folder.id { - anyhow::bail!("peer returned an audit event for another folder"); - } - if let Err(error) = self.state_store.append_audit_event(&event) { - let detail = format!( - "rejected audit event from {}: {error}", - event.author_device_id - ); - self.state_store.record_audit_fault( + let events = match context + .node + .request_audit_events( + peer.clone(), context.folder.id, - &event.author_device_id, - &detail, - )?; - anyhow::bail!(detail); + context.folder.capability.clone(), + self.state_store.join_invite(context.folder.id)?, + self.state_store + .audit_heads(context.folder.id)? + .into_iter() + .map(|head| (head.author_device_id, head.sequence)) + .collect(), + ) + .await + { + Ok(events) => events, + Err(error) => { + tracing::debug!(folder = %context.folder.name, peer = %peer.id, %error, "peer did not provide audit events"); + return Ok(()); + } + }; + let is_last_page = events.len() < MAX_AUDIT_EVENTS_PER_RESPONSE; + for event in events { + if event.folder_id != context.folder.id { + anyhow::bail!("peer returned an audit event for another folder"); + } + if let Err(error) = self.state_store.append_audit_event(&event) { + let detail = format!( + "rejected audit event from {}: {error}", + event.author_device_id + ); + self.state_store.record_audit_fault( + context.folder.id, + &event.author_device_id, + &detail, + )?; + anyhow::bail!(detail); + } + } + if is_last_page { + break; } - } - if is_last_page { - break; - } } context .node diff --git a/src/app/tests.rs b/src/app/tests.rs index 13f7dbc..ce7c2a7 100644 --- a/src/app/tests.rs +++ b/src/app/tests.rs @@ -292,9 +292,10 @@ async fn synchronizes_audit_events_written_before_the_author_was_revoked() -> an target.sync_once(target_folder.path()).await?; let target_events = target.state_store.audit_events(source_config.id)?; + let historical_event_hash = historical_event.hash()?; assert!(target_events.iter().any(|event| { event.author_device_id == former_member.public().to_string() - && event.hash() == historical_event.hash() + && event.hash().is_ok_and(|hash| hash == historical_event_hash) })); source_node.shutdown().await?; Ok(()) diff --git a/src/domain/audit.rs b/src/domain/audit.rs index adcdcdd..7040ddc 100644 --- a/src/domain/audit.rs +++ b/src/domain/audit.rs @@ -86,10 +86,9 @@ impl AuditEvent { AuditEventKind::RosterUpdated | AuditEventKind::OwnerIdentityRestored, Some(MemberRole::Owner), ) => true, - ( - AuditEventKind::ManifestCommitted, - Some(MemberRole::Owner | MemberRole::Member), - ) => true, + (AuditEventKind::ManifestCommitted, Some(MemberRole::Owner | MemberRole::Member)) => { + true + } _ => false, }; if !is_authorized {