Skip to content

fix(admin-disputes): confirm Mostro reply before reporting settle/cancel success#171

Open
AndreaDiazCorreia wants to merge 2 commits into
mainfrom
fix/admsettle-false-success
Open

fix(admin-disputes): confirm Mostro reply before reporting settle/cancel success#171
AndreaDiazCorreia wants to merge 2 commits into
mainfrom
fix/admsettle-false-success

Conversation

@AndreaDiazCorreia
Copy link
Copy Markdown
Member

@AndreaDiazCorreia AndreaDiazCorreia commented May 26, 2026

Closes #170

Summary

execute_admin_settle_dispute and execute_admin_cancel_dispute used admin_send_dm (fire-and-forget) and then printed
Dispute settled/canceled successfully! unconditionally, regardless of whether the daemon accepted the request. This caused the CLI to report success for operations that never happened — including the case reported in #170, where a non-existent order_id produced a backend log error but a green tick on the CLI.

Both handlers now follow the same pattern as execute_take_dispute: send the message, wait for Mostro's reply, validate the sender, and only print the success message when the daemon replies with the matching action (AdminSettled / AdminCanceled).

Changes

  • execute_admin_settle_dispute: replace admin_send_dm with the send_dm + wait_for_dm + parse_dm_events flow. Accept only Action::AdminSettled as success; route Action::CantDo through print_commands_results so the backend reason is surfaced to the operator; bail with an explicit error on mismatched actions.
  • execute_admin_cancel_dispute: same treatment, accepting Action::AdminCanceled as success.
  • Wrap wait_for_dm errors (notably WaitForDmTimeout) with context guiding the operator to verify the order id and check backend logs.

Known limitation

When the order_id does not exist, the daemon currently logs the InvalidOrderId error locally but does not enqueue a CantDo DM back to the sender. With this PR the CLI will surface that case as a timeout error rather than false success — a correct, actionable result. A complete fix requires the daemon to reply with CantDo(NotFound); that is being tracked in a separate issue against the mostro repo.

Summary by CodeRabbit

  • Bug Fixes
    • Admin dispute cancellation operations now properly validate completion status before returning.
    • Admin dispute settlement operations now properly validate completion status before returning.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 26, 2026

Warning

Review limit reached

@AndreaDiazCorreia, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 36 minutes and 36 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6cd56ad8-0362-40ad-9043-1263373796f6

📥 Commits

Reviewing files that changed from the base of the PR and between 0c864b3 and a339d8e.

📒 Files selected for processing (1)
  • src/parser/dms.rs

Walkthrough

This PR refactors admin dispute settlement and cancellation commands to await and validate Mostro's DM responses before reporting success, replacing fire-and-forget behavior that masked operation failures (resolving issue #170).

Changes

Admin Dispute Response Validation

Layer / File(s) Summary
Admin cancel dispute command response validation
src/cli/take_dispute.rs
Binds admin_keys for reuse in send/await flow, replaces immediate success with send_dmwait_for_dmparse_dm_events, validates responder pubkey, and branches on returned action (AdminCanceled success, CantDo via print_commands_results, other actions error).
Admin settle dispute command response validation
src/cli/take_dispute.rs
Binds admin_keys for reuse in send/await flow, replaces immediate success with send_dmwait_for_dmparse_dm_events, validates responder pubkey, and branches on returned action (AdminSettled success, CantDo via print_commands_results, other actions error).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • MostroP2P/mostro-cli#137: Introduces the admin_send_dm helper pattern that this PR replaces with explicit send/await/validate flow in execute_admin_cancel_dispute and execute_admin_settle_dispute.
  • MostroP2P/mostro-cli#123: Introduces the original admin cancel/settle dispute implementations that this PR refines to await and validate DM responses.
  • MostroP2P/mostro-cli#142: Updates CLI DM-response flow patterns to properly await and validate specific Action variants, using the same wait_for_dm and parse_dm_events approach.

Suggested reviewers

  • Catrya
  • grunch

Poem

🐰 Two admin commands now listen with care,
Awaiting true answers from Mostro's DM air,
No false victories claimed without proof,
Each response validated—error or truth!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: confirm Mostro reply before reporting success for settle/cancel dispute operations.
Linked Issues check ✅ Passed The PR implementation meets the requirements of issue #170: instead of fire-and-forget success reporting, it now waits for Mostro's reply, validates responses, and only reports success when the daemon confirms with matching actions.
Out of Scope Changes check ✅ Passed All changes in src/cli/take_dispute.rs are directly scoped to fixing the admin settle/cancel dispute flow to match the objectives outlined in issue #170.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/admsettle-false-success

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/cli/take_dispute.rs (1)

92-136: ⚡ Quick win

Extract the shared admin dispute round-trip helper.

Cancel and settle now duplicate the same send/wait/parse/validate/error-mapping flow almost verbatim. A small helper parameterized by request action, expected reply action, and success text would keep these paths from drifting on the next change.

Also applies to: 184-228

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/cli/take_dispute.rs` around lines 92 - 136, Cancel and settle duplicate
the same send/wait/parse/validate/error-mapping flow; extract a single async
helper (e.g. admin_dispute_roundtrip) that accepts the request message, the
expected reply Action, and success text, then internally calls send_dm, awaits
wait_for_dm, calls parse_dm_events, validates sender against ctx.mostro_pubkey,
maps Action::CantDo to print_commands_results, and returns Ok on the expected
action (e.g. Action::AdminCanceled) or Err with the same error strings used now;
update the cancel and settle code paths to call this helper instead of
duplicating the logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/cli/take_dispute.rs`:
- Around line 106-113: The current map_err collapses send (sent_message.await?)
failures into a "receive response" error from wait_for_dm; separately await and
handle sent_message.await and map its error to a publish/network/auth-specific
message that mentions the dispute_id and the operation (e.g., AdminCancel), then
call wait_for_dm(...).map_err for genuine receive-timeouts with the existing "no
reply" hint (also referencing dispute_id, not order id); apply the same change
to the settle path (the analogous sent_message.await and wait_for_dm sequence
around lines 198-205).

---

Nitpick comments:
In `@src/cli/take_dispute.rs`:
- Around line 92-136: Cancel and settle duplicate the same
send/wait/parse/validate/error-mapping flow; extract a single async helper (e.g.
admin_dispute_roundtrip) that accepts the request message, the expected reply
Action, and success text, then internally calls send_dm, awaits wait_for_dm,
calls parse_dm_events, validates sender against ctx.mostro_pubkey, maps
Action::CantDo to print_commands_results, and returns Ok on the expected action
(e.g. Action::AdminCanceled) or Err with the same error strings used now; update
the cancel and settle code paths to call this helper instead of duplicating the
logic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0f6fce81-6011-4337-a525-47bd9cf29648

📥 Commits

Reviewing files that changed from the base of the PR and between 5623f71 and 0c864b3.

📒 Files selected for processing (1)
  • src/cli/take_dispute.rs

Comment thread src/cli/take_dispute.rs
Comment on lines +106 to +113
let recv_event = wait_for_dm(ctx, Some(admin_keys), sent_message)
.await
.map_err(|e| {
anyhow::anyhow!(
"Failed to receive response from Mostro for AdminCancel: {e}. \
The operation may not have completed; verify the order id exists and check backend logs."
)
})?;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Don't collapse send failures into a "receive response" error.

wait_for_dm(...) also returns errors from sent_message.await?, so a publish/network/auth failure will be reported here as if Mostro just never replied. The added hint also says "order id", but these commands take a dispute_id, which makes the failure path harder to diagnose.

Possible adjustment
-    let recv_event = wait_for_dm(ctx, Some(admin_keys), sent_message)
-        .await
-        .map_err(|e| {
-            anyhow::anyhow!(
-                "Failed to receive response from Mostro for AdminCancel: {e}. \
-                 The operation may not have completed; verify the order id exists and check backend logs."
-            )
-        })?;
+    let recv_event = wait_for_dm(ctx, Some(admin_keys), sent_message)
+        .await
+        .map_err(|e| {
+            anyhow::anyhow!(
+                "AdminCancel failed while sending the request or waiting for Mostro's response: {e}. \
+                 Verify the dispute id and check client/backend logs."
+            )
+        })?;

Apply the same change to the settle path.

Also applies to: 198-205

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/cli/take_dispute.rs` around lines 106 - 113, The current map_err
collapses send (sent_message.await?) failures into a "receive response" error
from wait_for_dm; separately await and handle sent_message.await and map its
error to a publish/network/auth-specific message that mentions the dispute_id
and the operation (e.g., AdminCancel), then call wait_for_dm(...).map_err for
genuine receive-timeouts with the existing "no reply" hint (also referencing
dispute_id, not order id); apply the same change to the settle path (the
analogous sent_message.await and wait_for_dm sequence around lines 198-205).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

admsettle reports success even when the order id does not exist

1 participant