From c9282cb18a4e5e0e3dc43c8c01132e54d14ad42e Mon Sep 17 00:00:00 2001 From: prosolis <5590409+prosolis@users.noreply.github.com> Date: Wed, 15 Jul 2026 00:20:34 -0700 Subject: [PATCH] mischief: retry web contract insert on transient failure, refund only on lost race --- internal/plugin/adventure_mischief.go | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/internal/plugin/adventure_mischief.go b/internal/plugin/adventure_mischief.go index 1a77403..e93b6e4 100644 --- a/internal/plugin/adventure_mischief.go +++ b/internal/plugin/adventure_mischief.go @@ -941,12 +941,23 @@ func (p *AdventurePlugin) placeWebMischief(order peteclient.MischiefOrder) misch WindowEndsAt: now.Add(mischiefWindow), } if err := insertMischiefContract(c); err != nil { - // The one-live-per-target index rejected us — a rival contract is already - // on this target (ours isn't: we checked order_guid up top). Refund and - // bounce; the buyer lost a race, not money. - refund() - slog.Warn("mischief: web contract insert rejected", "order", order.GUID, "target", targetID, "err", err) - return mischiefWebResult{Status: mischiefWebBouncedIneligible, Detail: "someone already sent a monster their way"} + // Distinguish the one legitimate rejection from a transient write failure, + // the same way the Matrix path does — the two want opposite handling. + if liveMischiefForTarget(targetID) != nil { + // A rival contract is already on this target (ours isn't: we checked + // order_guid up top). Refund and terminally bounce; the buyer lost a + // race, not money. + refund() + slog.Warn("mischief: web contract lost the race", "order", order.GUID, "target", targetID) + return mischiefWebResult{Status: mischiefWebBouncedIneligible, Detail: "someone already sent a monster their way"} + } + // A real write failure with no rival to blame. Leave the debit in place + // and the order pending — the guid makes the next poll's re-run a no-op on + // the money and a clean retry on the insert, which is the whole point of + // keying on it. Refunding here would both drop a placeable hit and, worse, + // hand out a free contract if the retry then succeeded against the credit. + slog.Warn("mischief: web contract insert failed, will retry", "order", order.GUID, "target", targetID, "err", err) + return mischiefWebResult{Retry: true} } p.announceMischiefContract(c, tier)