Skip to content

feat: parse anti-abuse bond tags from kind-38385 info event#601

Merged
Catrya merged 3 commits into
mainfrom
feat/anti-abuse-bond-info-tags
May 26, 2026
Merged

feat: parse anti-abuse bond tags from kind-38385 info event#601
Catrya merged 3 commits into
mainfrom
feat/anti-abuse-bond-info-tags

Conversation

@AndreaDiazCorreia

@AndreaDiazCorreia AndreaDiazCorreia commented May 22, 2026

Copy link
Copy Markdown
Member

Closes #594

Summary

Adds the reader/cache layer for the seven new anti-abuse bond tags shipped on mostrod's kind-38385 info event (ad1f74a). Required by the upcoming Anti-Abuse Bond Support work in #591.

Scope is intentionally limited to parsing and caching. UI, trade-flow integration, and payout deadline computation land with #591.

Three-state semantics

bond_enabled is the only bond tag emitted unconditionally on modern daemons. Modelled as a BondPolicy enum rather than bool? to prevent silently collapsing "tag absent" with bond_enabled = "false":

  • unsupported — tag absent (legacy daemon)
  • disabledbond_enabled = "false"
  • enabledbond_enabled = "true" (six other bond tags present)

Changes

  • lib/features/mostro/mostro_instance.dart: new BondPolicy and BondApplyTo enums, seven new fields on MostroInstance, matching getters on the NostrEvent extension with defensive parsing.
  • test/features/mostro/mostro_instance_test.dart: unit tests covering the three policy states, enum parsing, and malformed values.

Summary by CodeRabbit

  • New Features

    • Instances can now advertise anti-abuse bond support, scope (take/make/both) and configurable bond parameters; parsing trims whitespace, treats missing/invalid values as unspecified, and makes payout-claim-window optional when not provided.
  • Tests

    • Expanded test coverage for bond flag parsing, scope mapping, boolean/numeric validation and bounds, and related edge cases.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 22, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b7e5a039-28db-462b-beca-b480f1d054e1

📥 Commits

Reviewing files that changed from the base of the PR and between ab51fdc and 835d151.

📒 Files selected for processing (2)
  • lib/features/mostro/mostro_instance.dart
  • test/features/mostro/mostro_instance_test.dart

Walkthrough

Models Mostro's anti-abuse bond as a three-state enum, adds nullable bond parameters, trims/nullable tag parsing, wires values into MostroInstance.fromEvent, and adds comprehensive tests for absent/disabled/enabled states and edge cases.

Changes

Anti-Abuse Bond Support

Layer / File(s) Summary
Bond Policy Data Model
lib/features/mostro/mostro_instance.dart
BondPolicy enum distinguishes three states (unsupported, disabled, enabled); BondApplyTo enum models trade-side applicability (take, make, both); MostroInstance gains required bondPolicy and nullable bond-parameter fields.
Bond Tag Parsing from NostrEvent
lib/features/mostro/mostro_instance.dart
_getOptionalTagValue helper safely retrieves tag values; new parsing getters interpret bond_enabled as three-state, map bond_apply_to to enum, and parse nullable numeric/boolean bond parameters with range/validity checks; bondPayoutClaimWindowDays becomes nullable.
Bond Data Constructor & Factory Integration
lib/features/mostro/mostro_instance.dart
Constructor accepts bond fields with bondPolicy defaulting to BondPolicy.unsupported; fromEvent factory passes parsed bond values from NostrEvent extension into the constructor.
Bond Parsing Test Suite
test/features/mostro/mostro_instance_test.dart
Test helper builds baseline NostrEvent; tests validate legacy behavior (absent/empty/whitespace tag), disabled behavior, enabled behavior with parameters, BondApplyTo mapping and unknown handling, boolean parsing, defensive numeric parsing and range checks, and coexistence with other info-event fields.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • mostronatorcoder

Poem

I nibble tags in midnight code,
Three states, small and neatly sowed,
Parsers trim and gently cope,
Tests hop through each edge-case slope,
A rabbit cheers the bonded node. 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and concisely summarizes the main change: adding parsing of anti-abuse bond tags from the kind-38385 info event.
Linked Issues check ✅ Passed The PR implementation fully satisfies issue #594's requirements: implements three-state bond_enabled semantics, parses all seven bond tags with correct types and validation, and caches them via NostrEvent extension getters for downstream consumption without UI/trade-flow integration.
Out of Scope Changes check ✅ Passed All changes are directly scoped to parsing and caching bond tags; no out-of-scope work like UI, trade-flow integration, or payout deadline computation is included, correctly staying within issue #594 boundaries.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ 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 feat/anti-abuse-bond-info-tags

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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f77f9d6d66

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread lib/features/mostro/mostro_instance.dart Outdated
Comment thread lib/features/mostro/mostro_instance.dart Outdated

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 2

🤖 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 `@lib/features/mostro/mostro_instance.dart`:
- Around line 204-207: The getter bondSlashNodeSharePct currently parses any
double; update it to parse using
double.tryParse(_getOptionalTagValue('bond_slash_node_share_pct')) and then
validate the parsed value is between 0.0 and 1.0 inclusive, returning null for
parse failures or out-of-range values so downstream logic never sees invalid
percentages; use the existing _getOptionalTagValue call and return the validated
double only when value != null && value >= 0.0 && value <= 1.0.
- Around line 129-133: _guard optional-tag parsing in _getOptionalTagValue: the
predicate passed to firstWhere must check t.length>0 before accessing t[0] to
avoid runtime errors for malformed tags, and returned tag values should map
empty strings to null. Change the predicate to (t) => t.length > 0 && t[0] ==
key, keep orElse: () => [], then after finding tag check tag.length < 2 => null,
then treat an empty tag[1] (tag[1].isEmpty) as null before returning the string.
🪄 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: 0caceccf-9f2e-4670-8af2-e53a089cc425

📥 Commits

Reviewing files that changed from the base of the PR and between df7490c and f77f9d6.

📒 Files selected for processing (2)
  • lib/features/mostro/mostro_instance.dart
  • test/features/mostro/mostro_instance_test.dart

Comment thread lib/features/mostro/mostro_instance.dart
Comment thread lib/features/mostro/mostro_instance.dart

@ermeme ermeme Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code review

No la aprobaría todavía.

Lo que me frena

  • bondSlashOnWaitingTimeout convierte cualquier valor no-true en false.
    Eso aplana valores malformados ("foo", "", etc.) en un estado válido y hace que un dato corrupto sea indistinguible de un false real.
  • Dado que el resto de los nuevos campos ya usan tryParse/null para no inventar valores, aquí esperaría la misma defensa: null para valores inválidos, o al menos un parser explícito para true/false בלבד.

Lo que sí está bien

  • La separación entre unsupported y disabled para bond_enabled tiene sentido.
  • La cobertura de tests para los nuevos campos numéricos está bien encaminada.

Si ajustan el parser booleano, sí lo vería en condiciones de aprobar.

@ermeme ermeme Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code review

Still not approvable.

Blocking issue

  • bondSlashOnWaitingTimeout still collapses every non-true value into false.
    That means malformed input like "foo" or "" becomes indistinguishable from a deliberate false.
    Since the rest of the new bond fields are parsed defensively (tryParse/null), this one should follow the same pattern and return null for invalid values, or use a strict boolean parser.

What looks good

  • The unsupported vs disabled split for bond_enabled is correct.
  • The new tests around the optional numeric fields are useful.

Fix that parser and I’d be comfortable approving it.

Comment thread lib/features/mostro/mostro_instance.dart
ermeme[bot]
ermeme Bot previously approved these changes May 22, 2026

@ermeme ermeme Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code review

Approved.

Re-checked the exact head SHA and the blocker is gone:

  • bond_slash_on_waiting_timeout now returns null for malformed values.
  • The test suite covers both valid booleans and malformed inputs explicitly.

The rest of the bond parsing looks solid enough to merge.

@coderabbitai coderabbitai Bot left a comment

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.

🧹 Nitpick comments (1)
lib/features/mostro/mostro_instance.dart (1)

170-181: ⚡ Quick win

Strict-parse bond_enabled so malformed values don’t masquerade as disabled.

Line 178 currently treats every non-"true" value as BondPolicy.disabled. That conflates malformed payloads with an explicit bond_enabled="false" policy.

Proposed change
-  /// - Any other value → [BondPolicy.disabled].
+  /// - `"false"` → [BondPolicy.disabled].
+  /// - Any other value → [BondPolicy.unsupported] (defensive fallback).
   BondPolicy get bondPolicy {
-    final raw = _getOptionalTagValue('bond_enabled');
-    if (raw == null) return BondPolicy.unsupported;
-    return raw.toLowerCase() == 'true'
-        ? BondPolicy.enabled
-        : BondPolicy.disabled;
+    final raw = _getOptionalTagValue('bond_enabled')?.toLowerCase();
+    switch (raw) {
+      case 'true':
+        return BondPolicy.enabled;
+      case 'false':
+        return BondPolicy.disabled;
+      case null:
+      default:
+        return BondPolicy.unsupported;
+    }
   }
🤖 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 `@lib/features/mostro/mostro_instance.dart` around lines 170 - 181, The
bondPolicy getter currently maps any non-"true" tag to BondPolicy.disabled;
instead, parse strictly: call _getOptionalTagValue('bond_enabled') as before,
return BondPolicy.unsupported if null, return BondPolicy.enabled only if
raw.toLowerCase() == 'true', return BondPolicy.disabled only if
raw.toLowerCase() == 'false', and for any other value return
BondPolicy.unsupported (or treat as malformed). Update the bondPolicy getter to
perform these explicit checks (referencing bondPolicy, _getOptionalTagValue, and
the BondPolicy enum) so malformed values don't masquerade as disabled.
🤖 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.

Nitpick comments:
In `@lib/features/mostro/mostro_instance.dart`:
- Around line 170-181: The bondPolicy getter currently maps any non-"true" tag
to BondPolicy.disabled; instead, parse strictly: call
_getOptionalTagValue('bond_enabled') as before, return BondPolicy.unsupported if
null, return BondPolicy.enabled only if raw.toLowerCase() == 'true', return
BondPolicy.disabled only if raw.toLowerCase() == 'false', and for any other
value return BondPolicy.unsupported (or treat as malformed). Update the
bondPolicy getter to perform these explicit checks (referencing bondPolicy,
_getOptionalTagValue, and the BondPolicy enum) so malformed values don't
masquerade as disabled.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2ef586d6-bcc9-4af3-ad10-359ba1f171f8

📥 Commits

Reviewing files that changed from the base of the PR and between 2f2a51f and ab51fdc.

📒 Files selected for processing (2)
  • lib/features/mostro/mostro_instance.dart
  • test/features/mostro/mostro_instance_test.dart

@ermeme ermeme Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hermes Agent Review

I found one blocking issue before approval. See the inline comment.

Blocking

  • The empty-tag guard was removed from _getTagValue, so a malformed empty tag can now throw a RangeError when any getter reads it.

Comment thread lib/features/mostro/mostro_instance.dart Outdated

@ermeme ermeme Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hermes Agent Review

Re-checked the current head SHA. The previous blocking issue is fixed, but I still found one correctness problem before approval.

Blocking

  • bondPolicy still maps any non-true / non-missing value to BondPolicy.disabled. That means malformed payloads like bond_enabled="foo" are indistinguishable from an intentional false, which breaks the three-state semantics the PR is introducing. I would return null/unsupported for malformed values, or parse false explicitly and treat everything else as invalid.

Comment thread lib/features/mostro/mostro_instance.dart

@ermeme ermeme Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hermes Agent Review

Re-checked the current head 835d1516d30dc52546d9b024a93b6085e9b34c6d. The bond parsing is now strict, the empty-tag guard is in place, and the tests cover the malformed cases. LGTM.

@Catrya Catrya left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

tACK

@Catrya Catrya merged commit e46854f into main May 26, 2026
2 checks passed
@Catrya Catrya deleted the feat/anti-abuse-bond-info-tags branch May 26, 2026 18:12
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.

Read & cache new anti-abuse-bond tags from the kind-38385 info event

2 participants