feat: event schema versioning, creator invoice cap, recipient validation - #552
Merged
Conversation
…ion (Stellar-split#502 Stellar-split#503 Stellar-split#505) Issue Stellar-split#502 — Soroban Event Schema Versioning - Add pub const *_V: u32 = 1 version constants for every event type in events.rs - Include migration guide comment block describing version history policy - Add invoice_limit_updated and recipient_account_missing event functions with version constant as first topic element Issue Stellar-split#503 — Invoice Count Per Creator Cap - Add CreatorInvoiceLimitReached = 36 to ContractError - Add open_invoice_count_key (persistent) and max_open_invoices_key (instance) to storage_keys.rs and lib.rs inline helpers - Enforce cap in _create_invoice_inner: panics with CreatorInvoiceLimitReached when open_count >= max (default 100 via DEFAULT_MAX_OPEN_INVOICES) - Decrement counter in _release_full (when no failed payouts) and cancel_invoice - Add set_max_open_invoices(env, admin, new_limit) admin function that stores the cap and emits InvoiceLimitUpdated(new_limit) Issue Stellar-split#505 — Recipient Account Existence Validation - Add RecipientAccountMissing = 37 to ContractError - Add failed_payouts_key (persistent Vec<Address>) to storage_keys.rs and lib.rs - In _release_full payout loop: call try_invoke_contract(balance) before each transfer; on failure store recipient in failed_payouts_key and emit RecipientAccountMissing, skip the transfer, continue - Gate invoice status -> Released and counter decrement on failed_payouts empty - Add retry_failed_payout(env, invoice_id, recipient): re-validates existence, executes transfer, removes from failed list, finalises when list empties Storage snapshot - Register open_invoice_count_key, max_open_invoices_key, failed_payouts_key in storage_snapshot.rs - Add corresponding XDR entries to tests/snapshots/storage_keys.json Closes Stellar-split#502 Closes Stellar-split#503 Closes Stellar-split#505
|
@Favourejiro 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! 🚀 |
…p-recipient-validation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements three issues in a single coherent change-set. All three touch
events.rs,error.rs,lib.rs,storage_keys.rs,storage_snapshot.rs, and the snapshot JSON.Issue #502 — Soroban Event Schema Versioning
What changed
pub const *_V: u32 = 1version constants for every event type at the top ofevents.rs, with a migration guide comment block explaining the policy.invoice_limit_updated,recipient_account_missing) includes the version constant as the first topic element.Migration guide (see top of
events.rs): bump the relevant_Vconstant and add a note to the version-history comment whenever a topic list or data payload shape changes.Issue #503 — Invoice Count Per Creator Cap
What changed
ContractError::CreatorInvoiceLimitReached = 36added.open_invoice_count_key(creator)(persistentu32),max_open_invoices_key()(instanceu32, default 100)._create_invoice_inner: checksopen_count >= maxand panics withCreatorInvoiceLimitReachedbefore creating. Increments counter on success._release_full: decrements counter once all payouts complete (gated on no failed payouts — see Recipient Account Existence Validation #505).cancel_invoice: decrements counter on Cancelled transition.set_max_open_invoices(env, admin, new_limit)— requiresAdminRole::Operator, stores cap, emitsInvoiceLimitUpdated(new_limit).Issue #505 — Recipient Account Existence Validation
What changed
ContractError::RecipientAccountMissing = 37added.failed_payouts_key(invoice_id)(persistentVec<Address>)._release_fullpayout loop: before each transfer callsenv.try_invoke_contract(balance)on the funding token. If that returnsErr, the recipient is appended toFailedPayouts,RecipientAccountMissingis emitted, and the loop continues — no panic.Released(and the open-invoice counter only decrements) whenFailedPayoutsis empty.retry_failed_payout(env, invoice_id, recipient): re-validates account existence, executes the transfer, removes from the failed list, and finalises the invoice when the list empties.Storage Snapshot
Three new keys registered in
storage_snapshot.rsandtests/snapshots/storage_keys.json:open_invoice_count_key(Symbol, Address) → u32max_open_invoices_keySymbol → u32failed_payouts_key(Symbol, u64) → Vec<Address>Closes #502
Closes #503
Closes #505