Mostro Spam & Abuse Mitigation — Design Options #710
arkanoider
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
My question to Opus 4.7 Extra High:
Ok! Great job...now I want to make some order in our discussion and have more structured plan having your opinion, i add two details :
So adding this two details, prepare me a nice list of options considering both privacy mode availability and also without it. Put the list of your prferred soltuions in these order:
first the most effective with less code modifcations down to the most effective but with high code impact. Prepare your response in a nice markdown format i can copy on github ideas!
Mostro Spam & Abuse Mitigation — Design Options
Context
Two concrete facts are shaping this plan:
m/44'/1237'/38383'/0/0),mostrodalways has a stable per-user handle. This massively simplifies anti-spam and anti-Sybil design.Two scenarios are considered throughout:
Design Principles
mostrodwithout touching NIP-69.Option List
Ordered by effectiveness × (inverse) code-impact. Earlier options = highest ROI.
1. Per-identity takes-in-flight quota (directly kills the current attack)
Problem addressed: The live attack — fresh keypair instantly takes an order and griefs the maker.
Mechanism:
Action::TakeBuy/Action::TakeSell, count open orders wheretaker_identity_pubkey == event.sender. Reject if >= N.Scenario A (no privacy mode): full enforcement, identity key always known.
Scenario B (privacy mode): reputation-mode users are fully covered; privacy-mode takers fall under a combined global cap (see Option 5).
Code impact: ~30–80 lines.
src/app/take_buy.rs,src/app/take_sell.rs— add pre-flight count query.src/db.rs— one indexed query onorderstable filtered by taker pubkey and status.settings.tpl.toml— newmax_in_flight_takes_tier0/1/2/3.Complexity: Trivial.
Effectiveness: Very high for the concrete attack in production today.
2. Minimum identity age at
mostrod(first-seen, not self-claimed)Problem addressed: Fresh keypair used for abusive takes.
Mechanism:
mostrodrecordsfirst_seen_atfor every identity pubkey the first time it sends any message.TakeBuy,TakeSell,NewOrder), requirenow - first_seen_at >= min_age_seconds(e.g., 60–300s).mostrod's first-seen timestamp, not a self-reported kind 0created_at. It cannot be backdated.Scenario A: full enforcement.
Scenario B: only applied to reputation-mode messages; privacy-mode messages still need Option 5/6.
Code impact: ~50 lines.
src/db.rs— addfirst_seen_atcolumn touserstable (migration).src/app.rscheck_trade_indexor a newcheck_identity_age— reject if too young.Complexity: Low.
Effectiveness: High against bots that generate-and-trade in one shot. Combine with Option 1 for full coverage.
3. Onboarding PoW bound to identity key (replaces bonds, no sats required)
Problem addressed: Cheap Sybil identity generation undermines Options 1 and 2.
Mechanism:
NewOrder/TakeBuy/TakeSell.noncesuch thatH(identity_pubkey || nonce)has D leading zero bits. D configurable, e.g., 22–26 bits (seconds-to-minutes on a phone, GPU-hours for thousands of identities).userstable. Never required again for that identity.Scenario A: full enforcement.
Scenario B: same; complementary with Option 6 for privacy-mode sessions.
Code impact: ~150–250 lines.
Action::RegisterIdentitywith{identity_pubkey, nonce}payload.src/util.rs.onboarding_pow_nonce,onboarding_pow_bitscolumns tousers.src/app.rshandle_message_actionfor trading actions.Complexity: Low-to-medium.
Effectiveness: High. Makes Sybil attacks expensive in CPU and combines multiplicatively with Options 1 and 2.
4. Tiered trust with reputation-based promotion
Problem addressed: Single-size-fits-all limits are either too tight for honest users or too loose for attackers.
Mechanism:
users/ ratings tables:total_rating,total_reviews,first_seen_at.Scenario A: works uniformly.
Scenario B: privacy-mode users are pinned to Trial tier by design (no persistent identity = no reputation; documented tradeoff).
Code impact: ~200–400 lines.
src/db.rs— tier helper function.src/app/order.rs,src/app/take_buy.rs,src/app/take_sell.rs— consult tier for quotas.src/config/types.rs— per-tier settings.Complexity: Medium.
Effectiveness: High. Turns every other control (PoW, quotas, epoch limits) into a graduated knob.
5. Per-identity, per-epoch action limits (freshness + bounded state)
Problem addressed: Burst spam within a short window; unbounded counter growth.
Mechanism:
kind: 38385info event.NewOrdercount (by tier).TakeBuy+TakeSellcount (by tier).Scenario A: full effect.
Scenario B: privacy-mode users share a global per-epoch pool (small, deliberate); reputation-mode users have per-identity allocations.
Code impact: ~250–400 lines.
epoch_counterstable or in-memory map with TTL.src/app.rsrun-loop wrapper.src/util.rsor wherever the info event is emitted.Complexity: Medium.
Effectiveness: High, especially combined with Option 4. Makes burst attacks ineffective regardless of identity count.
6. Blind-signature "epoch tokens" for privacy mode (only if privacy mode is kept)
Problem addressed: Sybil spam from ephemeral trade keys in Full Privacy Mode.
Mechanism:
mostrodcan verify them but can't link them back to the issuing identity.mostrodmarks it spent.Scenario A (privacy mode removed): Not needed — skip entirely.
Scenario B: This is the anonymous rate-limit primitive.
Code impact: ~500–1000 lines + one crypto dependency.
Action::RequestEpochTokensandAction::RedeemEpochTokenhandling.blind-rsa-signaturesor custom Schnorr).Complexity: Medium-high.
Effectiveness: High — but only relevant in Scenario B. If privacy mode is dropped, this option is discarded.
7. Dynamic per-action PoW with book-load scaling
Problem addressed: Static PoW either hurts honest mobile users or fails to deter GPU-armed attackers.
Mechanism:
pow: u8into per-action difficulties:pow_new_order,pow_take_*,pow_rate_user, etc.pow_new_orderscales up when the book has > X pending orders (load-shedding).Scenario A/B: identical behavior.
Code impact: ~150–300 lines.
src/config/types.rs— expand PoW fields.src/app.rs— move PoW check inside action dispatch (currently gatekeeper inrunloop at line ~315).Complexity: Medium.
Effectiveness: Medium-high. Best as a complement to quotas and tiers, not as a primary defense.
8. Sanity filters on order content
Problem addressed: Low-effort spam that obviously doesn't correspond to real trading intent.
Mechanism:
|premium| > 25%).(kind, fiat_code, fiat_amount, payment_method, premium)) from the same identity within a TTL.min_payment_amount/ range is outside sensible bands.Scenario A/B: identical.
Code impact: ~100–200 lines, concentrated in
src/app/order.rs.Complexity: Low.
Effectiveness: Medium. Catches lazy bots; sophisticated attackers adapt. Cheap insurance.
9. Signed-nonce challenge for borderline requests
Problem addressed: Heuristic-flagged but not clearly malicious orders; fire-and-forget bots.
Mechanism:
mostrodreplies withaction: "challenge"containing a random nonce.Scenario A/B: identical.
Code impact: ~150 lines.
Action::ChallengeandAction::ChallengeResponse.Complexity: Low-medium.
Effectiveness: Medium. Mostly valuable as a soft gate between "obviously fine" and "obviously spam."
10. Dispute / abandonment penalty on taker identity
Problem addressed: Attackers who grief makers by taking and abandoning orders, even within quotas.
Mechanism:
abandon_countper identity (order taken, never progressed tofiat-sentwithin a timeout; or disputes adjudicated against taker).userstable structure already in place.Scenario A/B: identical, but relies on identity key being present (weak in privacy mode).
Code impact: ~200–300 lines.
src/db.rs— schema additions.src/app/dispute.rs,src/app/cancel.rs— update counters.Complexity: Medium.
Effectiveness: Medium-high against persistent griefers; complements Options 1 and 4.
11. RLN-style ZK nullifier rate-limiting (only for Scenario B)
Problem addressed: Anonymous per-user rate-limiting with automatic slashing on double-posting, fully preserving privacy mode.
Mechanism:
H(secret, epoch, slot)and a SNARK proof of "commitment in the registered set."Scenario A (privacy mode removed): Not applicable.
Scenario B: strongest anonymous anti-Sybil primitive available.
Code impact: 3,000+ lines, plus ZK toolchain (e.g.,
arkworks,halo2), circuit audit, mobile proof-generation work.Complexity: High.
Effectiveness: Very high for its niche. Only worth the investment if privacy mode is preserved and blind-sig tokens (Option 6) prove insufficient.
Recommended Roadmap
If privacy mode is removed (Scenario A — simpler, recommended)
Phase 1 — Stop the current attack (days):
Phase 2 — Structural anti-Sybil (weeks):
Phase 3 — Polish (weeks):
Options 6 and 11 are dropped.
If privacy mode is retained (Scenario B)
Phases 1–3 as above, plus:
Phase 4 — Privacy-mode anti-Sybil:
Why This Ordering
Guiding Tradeoffs
mostrodpolicy — stop the attack in production today and buy time to implement the structural pieces (3, 4, 5) deliberately.Beta Was this translation helpful? Give feedback.
All reactions