Our Personal Data Server from scratch!
0

Configure Feed

Select the types of activity you want to include in your feed.

store: warn & skip instead of failing on unreadable event payloads

Lewis: May this revision serve well! <lu5a@proton.me>

author
Lewis
date (Jul 24, 2026, 8:27 PM +0300) commit 7c75b70d parent eac45fa6 change-id ypqkppyq
+49 -18
+49 -18
crates/tranquil-store/src/eventlog/payload.rs
··· 42 42 InvalidTimestamp(u64), 43 43 #[error("invalid ops DAG-CBOR in payload: {0}")] 44 44 InvalidDagCborOps(String), 45 - #[error("invalid handle in payload: {0}")] 46 - InvalidHandle(String), 47 45 #[error("invalid CID length: got {got}, expected {expected}")] 48 46 InvalidCidLength { got: usize, expected: usize }, 49 47 } ··· 188 186 }) 189 187 .transpose()?; 190 188 191 - let handle = payload 192 - .handle 193 - .as_ref() 194 - .map(|h| Handle::new(h.as_str()).map_err(|_| PayloadError::InvalidHandle(h.clone()))) 195 - .transpose()?; 189 + let handle = payload.handle.as_ref().and_then(|h| { 190 + Handle::new(h.as_str()) 191 + .inspect_err(|_| { 192 + tracing::warn!( 193 + value = %h, 194 + "ignoring an invalid event handle" 195 + ); 196 + }) 197 + .ok() 198 + }); 196 199 197 200 Ok(SequencedEvent { 198 201 seq: SequenceNumber::from_raw(raw.seq.as_i64()), ··· 218 221 .transpose()? 219 222 .flatten(), 220 223 ops, 221 - blobs: payload 222 - .blobs 223 - .clone() 224 - .map(|v| v.into_iter().map(CidLink::from).collect()), 224 + blobs: payload.blobs.clone().map(|v| { 225 + v.into_iter() 226 + .filter_map(|c| { 227 + CidLink::new(c.clone()) 228 + .inspect_err(|_| { 229 + tracing::warn!( 230 + value = %c, 231 + "skipping an event blob reference that isn't a valid CID" 232 + ); 233 + }) 234 + .ok() 235 + }) 236 + .collect() 237 + }), 225 238 blocks: payload.blocks.clone().map(EventBlocks::Inline), 226 239 handle, 227 240 active: payload.active, 228 241 status: payload.status.and_then(u8_to_account_status), 229 - rev: payload.rev.clone().map(Tid::from), 242 + rev: payload.rev.clone().and_then(|r| { 243 + Tid::new(r.clone()) 244 + .inspect_err(|_| { 245 + tracing::warn!( 246 + value = %r, 247 + "ignoring an event rev that isn't a valid TID" 248 + ); 249 + }) 250 + .ok() 251 + }), 230 252 }) 231 253 } 232 254 ··· 242 264 Did::new("did:plc:testuser1234567890abcdef").unwrap() 243 265 } 244 266 245 - fn test_cid_link() -> CidLink { 246 - let hash = sha2::Digest::finalize(sha2::Sha256::new()); 267 + fn test_cid_link(seed: u8) -> CidLink { 268 + let hash = sha2::Sha256::digest([seed]); 247 269 let mh = multihash::Multihash::<64>::wrap(0x12, &hash).unwrap(); 248 270 let c = cid::Cid::new_v1(0x71, mh); 249 271 CidLink::from_cid(&c) 250 272 } 251 273 274 + fn test_rev(seq: u64) -> Tid { 275 + const ALPHABET: &[u8] = b"234567abcdefghijklmnopqrstuvwxyz"; 276 + let s: String = (0..13) 277 + .rev() 278 + .map(|i| ALPHABET[((seq >> (i * 5)) & 0x1F) as usize] as char) 279 + .collect(); 280 + Tid::new(s).expect("generated TID is valid") 281 + } 282 + 252 283 #[test] 253 284 fn round_trip_minimal_payload() { 254 285 let event = SequencedEvent { ··· 280 311 281 312 #[test] 282 313 fn round_trip_full_commit_payload() { 283 - let cid = test_cid_link(); 314 + let cid = test_cid_link(1); 284 315 let ops = serde_json::json!([{"action": "create", "path": "app.bsky.feed.post/abc"}]); 285 316 286 317 let event = SequencedEvent { ··· 292 323 prev_cid: Some(cid.clone()), 293 324 prev_data_cid: Some(cid.clone()), 294 325 ops: Some(ops.clone()), 295 - blobs: Some(vec![CidLink::from("bafkreibtest".to_owned())]), 326 + blobs: Some(vec![test_cid_link(2)]), 296 327 blocks: Some(EventBlocks::Inline(vec![EventBlockInline { 297 328 cid_bytes: cid_link_to_bytes(&cid).unwrap(), 298 329 data: b"hello block".to_vec(), ··· 300 331 handle: Some(Handle::new("test.bsky.social").unwrap()), 301 332 active: None, 302 333 status: None, 303 - rev: Some(Tid::from("rev123".to_owned())), 334 + rev: Some(test_rev(123)), 304 335 }; 305 336 306 337 let encoded = encode_payload(&event); ··· 416 447 417 448 #[test] 418 449 fn cid_bytes_round_trip() { 419 - let cid = test_cid_link(); 450 + let cid = test_cid_link(1); 420 451 let bytes = cid_link_to_bytes(&cid).unwrap(); 421 452 assert_eq!(bytes.len(), CID_BYTE_LEN); 422 453 let recovered = bytes_to_cid_link(&bytes).unwrap().unwrap();