Skip to content

**Title:** fix: publish all four bulk payment contract events to the ledger - #570

Merged
Wilfred007 merged 4 commits into
Protocol-Guild:mainfrom
alfeedrips:fix/bulk-payment-event-publishing
Aug 20, 2026
Merged

**Title:** fix: publish all four bulk payment contract events to the ledger#570
Wilfred007 merged 4 commits into
Protocol-Guild:mainfrom
alfeedrips:fix/bulk-payment-event-publishing

Conversation

@alfeedrips

Copy link
Copy Markdown
Contributor

Body:

Summary

All four event types in contracts/bulk_payment/src/lib.rs were constructed as bare struct expressions and immediately dropped, so zero events were ever emitted to the Soroban ledger. This broke the backend contract event indexer (contractEventIndexer.ts) which depends on these events for real-time payment tracking and analytics, and violated on-chain auditability for bulk payments.

Changes

  • contracts/bulk_payment/src/lib.rs — Added .publish(&env) to all four event construction sites:

    • BatchExecutedEvent in execute_batch (line 161)
    • PaymentSkippedEvent in execute_batch_partial loop (line 217)
    • PaymentSentEvent in execute_batch_partial loop (line 228)
    • BatchPartialEvent in execute_batch_partial (line 253)
  • contracts/bulk_payment/src/test.rs — Added 2 new tests + helper:

    • has_event() helper that matches events by contract address and snake_case topic symbol via env.events().all() + Symbol::from_val
    • test_execute_batch_emits_batch_executed_event — verifies execute_batch publishes batch_executed_event
    • test_execute_batch_partial_emits_all_events — verifies execute_batch_partial publishes payment_sent_event, payment_skipped_event, and batch_partial_event when some payments succeed and others are skipped

Testing

cargo test -p bulk_payment

Result: 15/15 passing (13 existing + 2 new event emission tests)

Test Status
test_execute_batch_emits_batch_executed_event NEW - passes
test_execute_batch_partial_emits_all_events NEW - passes
All 13 pre-existing tests unchanged - pass

Tradeoffs

  • Event topic format: The #[contractevent] macro generates snake_case topic symbols (e.g., batch_executed_event for BatchExecutedEvent). The tests match on this format. If the macro behavior changes in a future Soroban SDK version, the tests will catch it.
  • No data field assertions: The tests verify event presence via topic matching but do not assert on the event data payload fields. This keeps tests resilient to serialization format changes while still confirming events are published. The snapshot files (test_snapshots/) capture the full event data for manual inspection if needed.

Architecture

The fix is minimal — each event struct already had the correct fields populated at the right call sites. The only change is appending .publish(&env) to convert the struct expression from a no-op into an actual Soroban event emission. The backend indexer (contractEventIndexer.ts) fetches all contract events from Soroban RPC generically, so no indexer-side changes are needed.

Out of scope

  • Sibling contract cross_asset_payment has the identical bug (separate issue)
  • Adding new event types or changing event field shapes
  • Indexer-side changes

Closes #390

“alfeedrips” added 4 commits August 19, 2026 14:54
The BatchExecutedEvent struct was being constructed as a bare expression
and immediately dropped, so no event was ever emitted to the ledger.
Add .publish(&env) call so the event reaches the Soroban event stream.
…h_partial

Both per-payment event structs were constructed and immediately dropped
inside the partial batch loop. Add .publish(&env) calls so each
individual payment outcome is emitted to the ledger.
The BatchPartialEvent struct was constructed as a bare expression and
immediately dropped at the end of execute_batch_partial. Add .publish(&env)
so the batch summary event reaches the ledger.
Add two tests that verify the .publish(&env) calls actually emit events
to the Soroban ledger:

- test_execute_batch_emits_batch_executed_event: checks that execute_batch
  publishes a BatchExecutedEvent with the correct topic.
- test_execute_batch_partial_emits_all_events: checks that
  execute_batch_partial publishes PaymentSentEvent, PaymentSkippedEvent,
  and BatchPartialEvent when some payments succeed and others are skipped.

Uses env.events().all() with Symbol matching via FromVal to inspect
the event topics emitted by the contract under test.
@Wilfred007
Wilfred007 merged commit 827deb4 into Protocol-Guild:main Aug 20, 2026
1 check passed
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.

Fix: bulk_payment contract events are constructed but never published

2 participants