# Anti-Abuse: Preventing Slot Blocking ## Problem Bad actors could abuse the reservation system by: 1. **Slot Squatting**: Reserving slots with no intention to attend 2. **Denial of Service**: Mass-reserving to block legitimate patients 3. **Competitor Sabotage**: Blocking a therapist's calendar 4. **Spam Queries**: Flooding the network with fake queries ## Defense Layers ### Layer 1: Rate Limiting (Protocol Level) ```rust pub struct RateLimits { /// Max reservations per sender per hour pub max_reservations_per_hour: u8, // Default: 3 /// Max pending (unconfirmed) reservations per sender pub max_pending_reservations: u8, // Default: 2 /// Min time between reservations (seconds) pub reservation_cooldown_secs: u32, // Default: 300 (5 min) /// Max queries per sender per minute pub max_queries_per_minute: u8, // Default: 10 } ``` **Implementation**: Each relay tracks sender activity and drops excessive requests. ### Layer 2: Reservation Deposits (Economic) Require a small proof-of-work or micro-deposit to make reservations: | Method | Cost to Attacker | UX Impact | |--------|------------------|-----------| | **Hashcash PoW** | CPU time (~1-5s per reservation) | Slight delay | | **Token Stake** | Loses stake on no-show | Requires token system | | **Reputation Bond** | Loses reputation on abuse | Requires history | **Recommended**: Start with Hashcash PoW — no external dependencies. ```rust pub struct ReservationProof { /// Hashcash proof-of-work (20-bit difficulty) pub pow_nonce: u64, /// Hash must start with N zero bits pub difficulty: u8, } impl ReservationProof { pub fn verify(&self, reservation_id: &[u8; 16]) -> bool { let hash = sha256([reservation_id, &self.pow_nonce.to_le_bytes()].concat()); leading_zeros(&hash) >= self.difficulty } } ``` ### Layer 3: Confirmation Requirements Therapists can require confirmation steps: ```rust pub enum ConfirmationMode { /// Auto-confirm (trust network) AutoConfirm, /// Require patient to solve CAPTCHA-like challenge ChallengeResponse { challenge: Vec }, /// Require callback to verify contact ContactVerification { method: ContactMethod }, /// Manual review by therapist ManualReview, } ``` ### Layer 4: No-Show Tracking Track reservation outcomes per sender: ```rust pub struct SenderReputation { pub address: [u8; 16], pub reservations_made: u32, pub reservations_honored: u32, pub reservations_cancelled: u32, // With notice pub no_shows: u32, // Without notice pub last_no_show: Option, } impl SenderReputation { pub fn honor_rate(&self) -> f32 { if self.reservations_made == 0 { return 0.5; } (self.reservations_honored as f32) / (self.reservations_made as f32) } pub fn is_blocked(&self) -> bool { self.no_shows >= 3 || self.honor_rate() < 0.5 } } ``` **Therapists can share blocklists** via signed messages: ```rust pub struct BlocklistEntry { pub blocked_address: [u8; 16], pub reason: BlockReason, pub reported_by: [u8; 16], pub signature: [u8; 64], pub timestamp: u64, } pub enum BlockReason { NoShow, Spam, Harassment, FakeIdentity, } ``` ### Layer 5: Reservation Limits per Therapist Therapists set their own limits: ```rust pub struct TherapistPolicy { /// Max pending reservations from new senders pub max_pending_new: u8, // Default: 1 /// Max pending from established senders pub max_pending_established: u8, // Default: 3 /// Require verification level for reservations pub min_verification_level: u8, // 0 = any, 2 = peer-endorsed /// Auto-reject senders with low honor rate pub min_honor_rate: f32, // Default: 0.7 } ``` ## Implementation Roadmap ### Phase 1: Basic Rate Limiting (Week 1) - [ ] Add `RateLimiter` to `ServiceRouter` - [ ] Track per-sender reservation counts - [ ] Drop excessive requests with `ServiceAction::RateLimited` ### Phase 2: Proof-of-Work (Week 2) - [ ] Add `ReservationProof` to reserve message payload - [ ] Verify PoW before processing reservation - [ ] Adaptive difficulty based on network load ### Phase 3: Reputation System (Week 3-4) - [ ] `SenderReputation` storage - [ ] Honor/no-show reporting from therapists - [ ] Blocklist propagation ### Phase 4: Therapist Policies (Week 4+) - [ ] Policy field in `SlotAnnounce` - [ ] Policy enforcement in reservation handling ## Example: Complete Anti-Abuse Flow ``` Patient Relay Therapist | | | |-- Query (CBT, 104xx) -->| | |<-- Matches (3 slots) ---| | | | | |-- Reserve (slot_id) --->| | | + PoW proof | | | (1.2s computation) | | | |-- Check rate limit ------>| | | (OK: 1st today) | | |-- Check reputation ------>| | | (OK: new sender, 0.5) | | |-- Forward reserve ------->| | | | | |<-- Confirm (pending) -----| |<-- Pending -------------| | | | | | [Patient attends] | | | |<-- Outcome: honored ------| | | (reputation += 1) | ``` ## Edge Cases ### New Users (No History) - Allow 1 pending reservation - Require PoW - Lower priority than established users ### Therapist Gaming the System - Therapists could falsely report no-shows - Mitigation: Require mutual confirmation (patient confirms attendance too) - Weight reports by reporter reputation ### Sybil Attacks (Many Fake Identities) - Each identity requires new Ed25519 keypair - PoW per reservation makes mass-blocking expensive - Cross-relay blocklist sharing limits damage ## Privacy Considerations - Reputation is tied to mesh address, not real identity - No-show reports don't reveal appointment details - Blocklists only contain addresses + reason, not personal data ## Metrics to Monitor | Metric | Healthy Range | Alert Threshold | |--------|---------------|-----------------| | Reservation/Confirm ratio | > 0.8 | < 0.5 | | Unique senders per relay | Growing | Flat with high volume | | PoW rejection rate | < 5% | > 20% | | Blocklist growth | Slow | Rapid spike |