feat: supplier payout batching, per-address rate limiting, dispute evidence versioning, dispute withdrawal - #327
Merged
Conversation
…idence versioning, dispute withdrawal (shakurJJ#284 shakurJJ#285 shakurJJ#286 shakurJJ#287) - shakurJJ#284: add set_payout_mode(), claim_payout(), get_pending_payout() and check_address_outflow() helper; batched mode accumulates milestone payments per-supplier until claim_payout is called in one transfer - shakurJJ#285: add set_address_outflow_limit(), get_address_outflow_limit() and check_address_outflow() sliding-window helper; every payout checks both the global circuit breaker and the per-address cap independently - shakurJJ#286: add submit_dispute_evidence(), get_dispute_evidence() and DisputeEvidence struct; evidence entries are append-only per disputed milestone; emits dispute_evidence_submitted event per entry - shakurJJ#287: add withdraw_dispute(); buyer-only, reverts Disputed milestone back to ProofSubmitted, decrements open_dispute_count, removes from active disputes list; emits dispute_withdrawn event Also fix two pre-existing broken tests: - test_admin_action_log_capped_and_ordered: advance ledger each iteration so entries have strictly increasing sequence numbers - test_shipment_created_event_includes_all_role_addresses: advance ledger past 0 before creating shipment so created_at > 0 All 105 tests pass.
…mit-evidence-dispute-withdrawal
|
@Good-Coded 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! 🚀 |
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 four features from the backlog in a single, cohesive change. All 105 tests pass (including fixes for two pre-existing broken tests in the original repo).
Changes
#284 — Supplier payout batching
Adds opt-in batched payout mode per supplier so milestone payments accumulate as a claimable balance instead of triggering a SAC transfer on every confirmation.
New public functions:
set_payout_mode(supplier, batched: bool)— toggles Batched vs Immediate per supplier; requires supplier authclaim_payout(supplier, token)— transfers the full accumulated balance in one call and resets it to zero; panics if balance is zeroget_pending_payout(supplier) -> i128— read-only getterImplementation notes:
PayoutMode::Immediate— zero behaviour change for existing suppliersDataKey::PendingPayout(supplier)persistent storageconfirm_milestone,release_held_payment, andbatch_confirm_milestonesall respect the modecheck_address_outflow(required by feat: per-address outflow rate limiting #285) is called before the credit either path#285 — Per-address outflow rate limiting
Adds an admin-configurable sliding-window outflow cap scoped per supplier address, independent of the existing global circuit breaker.
New public functions:
set_address_outflow_limit(admin, address, limit, window_ledgers)— admin-only;limit = 0disables the per-address capget_address_outflow_limit(address) -> (i128, u32, u32, i128)— returns(limit, window_ledgers, window_start, window_outflow)New internal helper:
check_address_outflow(env, address, payment)— mirrors the circuit breaker pattern using persistent storage; called inconfirm_milestone,release_held_payment, andbatch_confirm_milestonesBehaviour:
window_ledgershave elapsed#286 — Dispute evidence versioning
Allows supplier, logistics, or buyer to append versioned evidence entries to a disputed milestone while it is open, giving the arbiter richer context for off-chain review.
New public functions:
submit_dispute_evidence(caller, shipment_id, milestone_index, evidence_hash, evidence_type)— appends oneDisputeEvidenceentry; callable only while the milestone isDisputed; emitsdispute_evidence_submittedget_dispute_evidence(shipment_id, milestone_index) -> Vec<DisputeEvidence>— returns entries in submission orderNew type:
DisputeEvidence { submitter, evidence_hash, evidence_type, submitted_ledger }Behaviour:
resolve_dispute) is entirely unchanged#287 — Buyer-initiated dispute withdrawal
Allows a buyer to retract their own open dispute, unfreezing the milestone back to
ProofSubmittedwithout requiring arbiter intervention.New public function:
withdraw_dispute(buyer, shipment_id, milestone_index)— buyer-only, only whileDisputed; reverts milestone toProofSubmitted, decrementsopen_dispute_count, removes entry from the global active disputes list, emitsdispute_withdrawnBehaviour:
confirm_milestoneimmediately or raise a new dispute subject to the normal cooldown rulesresolve_disputeon a withdrawn dispute (milestone is no longerDisputed)Pre-existing test fixes
Two tests in the original repo were broken due to the Soroban test environment starting at ledger sequence 0:
test_admin_action_log_capped_and_ordered— advanced the ledger by 1 each iteration so audit entries have strictly increasing sequence numberstest_shipment_created_event_includes_all_role_addresses— advanced ledger to 1 before creating the shipment socreated_at > 0Test coverage
Total: 105 tests, 0 failures.
Closes #284
Closes #285
Closes #286
Closes #287