feat(channel): storage TTL extension, partial settlement, Deposit event - #24
Open
shawnmuggle wants to merge 3 commits into
Open
Conversation
- Extend instance storage TTL as a side effect of top_up, settle, close, and close_start, and add a public extend() entrypoint so long-lived channels are not archived while in use. - Cap settle/close payouts at the channel balance and advance WithdrawnAmount only by the amount actually transferred, so a commitment exceeding the balance no longer locks the recipient out; the shortfall stays claimable with the same commitment after a top up. - Emit a Deposit event from top_up (including the constructor's initial deposit) so recipients can observe funding in real time. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR hardens the Soroban channel contract for long-lived “metered service” usage by preventing instance-storage archival during normal operation, allowing partial settlement when commitments exceed balance, and emitting a deposit event for observability.
Changes:
- Extend instance storage TTL on
top_up,settle,close, andclose_start, and add a publicextend()entrypoint. - Implement capped (partial) payouts for
settle/close, advancingWithdrawnAmountonly by the amount actually transferred. - Emit a
Deposit { from, amount }contract event ontop_up(including constructor-funded deposits), and update docs/tests/snapshots accordingly.
Reviewed changes
Copilot reviewed 34 out of 34 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| README.md | Document extend entrypoint, partial-settlement semantics, and storage lifetime behavior. |
| contracts/channel/src/lib.rs | Add TTL extension logic/constants, extend() entrypoint, Deposit event emission in top_up, and capped withdrawal helper used by settle/close. |
| contracts/channel/src/event.rs | Introduce Deposit contract event definition and documentation. |
| contracts/channel/src/test.rs | Update/add tests for capped close/settle behavior and deposit-event emission. |
| contracts/channel/test_snapshots/test/test_top_up_zero.1.json | Update snapshot TTL expectations (instance live_until) after TTL extension behavior. |
| contracts/channel/test_snapshots/test/test_top_up_emits_deposit_event.1.json | New snapshot covering deposit event emission. |
| contracts/channel/test_snapshots/test/test_top_up_after_creation.1.json | Update snapshot TTL expectations after TTL extension behavior. |
| contracts/channel/test_snapshots/test/test_settle.1.json | Update snapshot TTL expectations after TTL extension behavior. |
| contracts/channel/test_snapshots/test/test_settle_partial_then_top_up.1.json | New snapshot covering partial settlement followed by top-up and re-settlement. |
| contracts/channel/test_snapshots/test/test_settle_older_commitment_no_op.1.json | Update snapshot TTL expectations after TTL extension behavior. |
| contracts/channel/test_snapshots/test/test_settle_incremental.1.json | Update snapshot TTL expectations after TTL extension behavior. |
| contracts/channel/test_snapshots/test/test_settle_during_close_start.1.json | Update snapshot TTL expectations after TTL extension behavior. |
| contracts/channel/test_snapshots/test/test_settle_after_close_start_effective.1.json | Update snapshot TTL expectations after TTL extension behavior. |
| contracts/channel/test_snapshots/test/test_refund_twice.1.json | Update snapshot TTL expectations after TTL extension behavior. |
| contracts/channel/test_snapshots/test/test_refund_too_early.1.json | Update snapshot TTL expectations after TTL extension behavior. |
| contracts/channel/test_snapshots/test/test_refund_before_close_start_fails.1.json | Update snapshot TTL expectations after TTL extension behavior. |
| contracts/channel/test_snapshots/test/test_refund_at_exact_effective_ledger.1.json | Update snapshot TTL expectations after TTL extension behavior. |
| contracts/channel/test_snapshots/test/test_refund_after_close.1.json | Update snapshot TTL expectations after TTL extension behavior. |
| contracts/channel/test_snapshots/test/test_open_zero_amount.1.json | Update snapshot TTL expectations after TTL extension behavior. |
| contracts/channel/test_snapshots/test/test_invalid_signature.1.json | Update snapshot TTL expectations after TTL extension behavior. |
| contracts/channel/test_snapshots/test/test_close.1.json | Update snapshot TTL expectations after TTL extension behavior. |
| contracts/channel/test_snapshots/test/test_close_zero_amount.1.json | Update snapshot TTL expectations after TTL extension behavior. |
| contracts/channel/test_snapshots/test/test_close_twice.1.json | Update snapshot TTL expectations after TTL extension behavior. |
| contracts/channel/test_snapshots/test/test_close_start_resets_waiting_period.1.json | Update snapshot TTL expectations after TTL extension behavior. |
| contracts/channel/test_snapshots/test/test_close_start_fails_after_effective.1.json | Update snapshot TTL expectations after TTL extension behavior. |
| contracts/channel/test_snapshots/test/test_close_start_fails_after_close.1.json | Update snapshot TTL expectations after TTL extension behavior. |
| contracts/channel/test_snapshots/test/test_close_start_and_refund.1.json | Update snapshot TTL expectations after TTL extension behavior. |
| contracts/channel/test_snapshots/test/test_close_full_balance_no_refund_event.1.json | Update snapshot TTL expectations after TTL extension behavior. |
| contracts/channel/test_snapshots/test/test_close_during_close_start.1.json | Update snapshot TTL expectations after TTL extension behavior. |
| contracts/channel/test_snapshots/test/test_close_amount_exceeds_balance.1.json | Update snapshot to reflect capped payout + WithdrawnAmount advancement semantics on close. |
| contracts/channel/test_snapshots/test/test_close_after_settle.1.json | Update snapshot TTL expectations after TTL extension behavior. |
| contracts/channel/test_snapshots/test/test_close_after_close_start_effective.1.json | Update snapshot TTL expectations after TTL extension behavior. |
| contracts/channel-factory/test_snapshots/test/test_open.1.json | Update factory snapshot to new channel wasm hash/exports and new instance TTL expectations. |
| contracts/channel-factory/test_snapshots/test/test_open_zero_amount.1.json | Update factory snapshot to new channel wasm hash/exports and new instance TTL expectations. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+855
to
875
| /// Top up emits a Deposit event, and the constructor's initial deposit does too. | ||
| #[test] | ||
| fn test_top_up_emits_deposit_event() { | ||
| let env = Env::default(); | ||
| env.mock_all_auths(); | ||
|
|
||
| let auth_key = SigningKey::from_bytes(&[29u8; 32]); | ||
| let auth_pubkey = BytesN::from_array(&env, &auth_key.verifying_key().to_bytes()); | ||
|
|
||
| let to = Address::generate(&env); | ||
| let funder = Address::generate(&env); | ||
|
|
||
| let (token_addr, _token, asset_admin) = create_token(&env); | ||
| asset_admin.mint(&funder, &1000); | ||
|
|
||
| let channel_id = env.register(Contract, (token_addr.clone(), funder.clone(), auth_pubkey.clone(), to.clone(), 500i128, 100u32)); | ||
| let client = ContractClient::new(&env, &channel_id); | ||
|
|
||
| client.top_up(&200); | ||
| assert!(has_event_type(&env, &channel_id, "deposit")); | ||
| } |
Comment on lines
+358
to
+360
| pub fn extend(env: &Env) { | ||
| Self::extend_instance_ttl(env); | ||
| } |
Address review feedback on PR stellar-experimental#24: - Assert the constructor and top_up each emit their own Deposit event (env.events().all() holds only the last invocation's events, so each assertion isolates a single emitter). - Add test_extend verifying extend() requires no auth and extends the instance storage TTL. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Closes #23.
Hardens the channel contract for long-lived metered-service channels (funder opens a channel with a deposit, then pays per-request via cumulative commitments over days/weeks):
top_up,settle,close, andclose_startnow extend the instance storage TTL (threshold ~30 days, extend to ~60 days) as a side effect, and a new publicextend()entrypoint lets anyone bump it explicitly, so an in-use channel is not archived. Documented under a new "Storage lifetime" section.settle/closepayouts are capped at the channel balance, andWithdrawnAmountadvances only by the amount actually transferred. A commitment exceeding the balance no longer panics and locks the recipient out; the shortfall stays claimable with the same commitment after a futuretop_up. Forclosethe docs note this recoverability is best-effort, since close makes the channel immediately refundable.top_up(including the constructor's initial deposit) emitsDeposit { from, amount }so recipients can observe funding in real time. Direct token transfers to the contract address remain observable only via token events (doc note added).Tests: updated
test_close_amount_exceeds_balanceto the new capped-payout semantics, addedtest_settle_partial_then_top_upandtest_top_up_emits_deposit_event. All 30 tests pass locally, along withmake fmt-check,make doc-check, andmake readme-check(README regenerated viamake readme).🤖 Generated with Claude Code