Skip to content

fix: include network cursor ID and rule identity in alert_id (#252) - #352

Merged
Valreb001 merged 1 commit into
Tx-wats:mainfrom
blizzj:fix/issue-252-alert-id-collision
Oct 21, 2026
Merged

Valreb001 merged 1 commit into
Tx-wats:mainfrom
blizzj:fix/issue-252-alert-id-collision

Conversation

@blizzj

@blizzj blizzj commented Oct 20, 2026 •

Copy link
Copy Markdown

Fixes #252

Problem

alert_id() only hashed contract_id, tx_hash and rule_triggered, contradicting the README/AlertPayload docs which say it derives from (network, contract_id, tx_hash, rule_type, rule_triggered). Two rules with identical labels on one contract (e.g. two LargeTransfer(>=100XLM) rules routed to different webhooks) produced the same ID and one was silently deduplicated away by receivers.

Changes

  • alert_id() now hashes the network cursor ID (Network::cursor_id, so custom networks custom@https://… are distinguished), rule_type (previously omitted), rule_triggered and the rule's index within the contract's rules list.
  • EvalContext gains a network_id: String field; check_no_activity() gains a rule_index: usize parameter so NoActivity incident/recovery alerts and cooldown summaries use the same scheme.
  • Docs updated (README.md, docs/alert-rules.md, docs/configuration.md, AlertPayload doc comment) to describe the exact hash inputs.
  • CHANGELOG.md notes the breaking ID change: receivers persisting alert_id for dedup will see new values after upgrading.
  • Collision test added: identical_rules_on_one_contract_do_not_collide asserts two identical LargeTransfer rules fire with distinct IDs, and that the same rule on a different network also differs. Existing determinism test extended to cover network and rule-index sensitivity.

Notes

  • Breaking for receivers: stored alert_id dedup entries will not match post-upgrade alerts (values change once).
  • rule_index is the position in the contract's rules list; reordering or inserting rules above an existing rule changes its alert IDs.

Test plan

  • cargo test -p txwatch-rules (unit + collision tests)
  • cargo test -p txwatch-poller (integration, updated EvalContext literals)
  • cargo bench -p txwatch-rules --bench evaluate still compiles

closes #252
closes #257
closes #258
closes #261

)

alert_id() only hashed contract_id, tx_hash and rule_triggered, so two
rules with identical labels on one contract produced the same ID and
were deduplicated away by receivers. Hash the network cursor ID, rule
type and the rule's index within the contract's rule list instead.
@drips-wave

drips-wave Bot commented Oct 20, 2026

Copy link
Copy Markdown

@blizzj Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Valreb001
Valreb001 merged commit 22ae1f3 into Tx-wats:main Oct 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants