Skip to content

YNU-457: skip empty assets in app allocations validation#416

Merged
philanton merged 3 commits into
mainfrom
fix/app-state-empty-assets
Nov 7, 2025
Merged

YNU-457: skip empty assets in app allocations validation#416
philanton merged 3 commits into
mainfrom
fix/app-state-empty-assets

Conversation

@dimast-x
Copy link
Copy Markdown
Contributor

@dimast-x dimast-x commented Nov 5, 2025

Summary by CodeRabbit

  • Bug Fixes
    • Improved allocation validation: operations now fail if allocations reference assets that were never deposited or fully withdrawn, while allowing transactions to proceed when zero-balance assets have no allocations — preventing incorrect redistribution errors.
  • Tests
    • Added coverage for withdrawn and never-deposited asset scenarios to ensure correct success/error responses and balance adjustments.

@dimast-x dimast-x requested a review from a team as a code owner November 5, 2025 09:07
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Nov 5, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds multiple tests covering allocations referencing withdrawn or never-deposited assets and updates allocation validation to treat zero-balance assets specially: if an asset's app-session balance is zero, a non-zero allocation for that asset triggers an error; otherwise validation for that asset is skipped.

Changes

Cohort / File(s) Summary
Test Coverage
clearnode/app_session_service_test.go
Adds multiple test cases to TestAppSessionService_SubmitAppState covering: operating with withdrawn assets that don't require allocations, error when allocations reference withdrawn assets, and error when allocations reference never-deposited assets. Tests assert success/error messages and balance adjustments.
Allocation Validation
clearnode/rpc_router_private.go
Updates verifyAllocations to: for assets with zero app-session balance, return an error if allocationSum contains a non-zero allocation for that asset; otherwise skip validation for that asset. For non-zero balances, existing redistribution/equality checks remain.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant RPC
    participant verifyAllocations as verifyAllocations()
    Note over RPC,verifyAllocations: SubmitAppState -> verifyAllocations
    Client->>RPC: SubmitAppState(with allocations)
    RPC->>verifyAllocations: iterate assets in appSessionBalance
    alt asset balance == 0
        verifyAllocations->>verifyAllocations: check allocationSum[asset]
        alt allocationSum[asset] != 0
            verifyAllocations-->>RPC: return error "asset not deposited"
        else allocationSum[asset] == 0
            verifyAllocations-->>RPC: continue (skip validation)
        end
    else asset balance != 0
        verifyAllocations->>verifyAllocations: require allocationSum[asset] == allocated amount
        alt mismatch
            verifyAllocations-->>RPC: return redistribution error
        else match
            verifyAllocations-->>RPC: ok
        end
    end
    RPC-->>Client: response (success or error)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Review points:
    • verifyAllocations conditional: verify correctness of zero-balance handling and error message content.
    • New tests in app_session_service_test.go: ensure test coverage matches intended behavior and mocks/setup reflect real session state.
    • Confirm no regressions in other allocation paths (redistribution/mismatch cases).

Possibly related PRs

Suggested reviewers

  • philanton

Poem

🐰 Soft thumps upon the code I prance,
Withdrawn coins skip the allocation dance,
Tests hop in to show the way,
Errors catch the stray,
A tiny fix — a brighter day! 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: modifying app allocations validation to skip empty assets, which is reflected in the production logic changes to verifyAllocations in rpc_router_private.go.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/app-state-empty-assets

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b44a340 and 4d9aada.

📒 Files selected for processing (2)
  • clearnode/app_session_service_test.go (1 hunks)
  • clearnode/rpc_router_private.go (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-04T19:14:48.928Z
Learnt from: dimast-x
Repo: erc7824/nitrolite PR: 411
File: clearnode/custody.go:542-553
Timestamp: 2025-11-04T19:14:48.928Z
Learning: In clearnode/custody.go's handleClosed function, when unlocking escrow funds on channel close, the code intentionally passes the channelEscrowAccountBalance (which may be negative) directly to ledger.Record for the wallet account. When the escrow balance is negative (e.g., resize confirmation received for a channel not in resizing state), this causes a debit to the unified wallet account, which is the expected behavior to equalize accounting. Temporary negative unified balances in this scenario are acceptable.

Applied to files:

  • clearnode/app_session_service_test.go
  • clearnode/rpc_router_private.go
🧬 Code graph analysis (2)
clearnode/app_session_service_test.go (3)
clearnode/pkg/rpc/api.go (4)
  • VersionNitroRPCv0_4 (33-33)
  • AppSessionIntentOperate (640-640)
  • Version (27-27)
  • AppAllocation (626-633)
clearnode/ledger.go (2)
  • NewAccountID (44-50)
  • GetWalletLedger (56-58)
clearnode/rpc_router_private.go (2)
  • SubmitAppStateParams (48-54)
  • AppAllocation (62-66)
clearnode/rpc_router_private.go (1)
clearnode/rpc.go (1)
  • RPCErrorf (147-151)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Build and Publish (Clearnode)
  • GitHub Check: Test (Integration) / Test Integration
  • GitHub Check: Analyze (go)
🔇 Additional comments (3)
clearnode/rpc_router_private.go (1)

786-791: LGTM! Validation gap successfully addressed.

The fix correctly implements the validation logic suggested in previous reviews. Zero-balance assets can now be:

  • Omitted from allocations (allowed)
  • Included with zero allocation (allowed)
  • Included with non-zero allocation (rejected with clear error)

This prevents users from allocating withdrawn or never-deposited assets.

clearnode/app_session_service_test.go (2)

534-571: LGTM! Test validates withdrawn asset allocation error.

This test directly verifies the new validation logic that prevents allocating withdrawn assets. The error assertion correctly matches the expected error message from the validation function.


573-604: LGTM! Test covers never-deposited asset scenario.

This test validates a distinct error path where an asset was never deposited (not in appSessionBalance), unlike the withdrawn asset scenario. The error assertion correctly expects the "unknown asset" error from the second validation loop.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @dimast-x, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request resolves an issue where the application's state validation incorrectly enforced allocation requirements for assets that had been fully withdrawn from a session. By introducing a check to skip zero-balance assets during the allocation verification process, the system now behaves as expected, allowing operations on remaining assets without being hindered by historical, zero-balance assets. This enhances the flexibility and correctness of app state management.

Highlights

  • Allocation Validation Logic: The core validation logic for application allocations has been updated to correctly handle assets with a zero balance, preventing unnecessary allocation requirements for fully withdrawn assets.
  • New Test Case: A new test case, Operate_WithdrawnAsset_NotRequired, has been added to app_session_service_test.go to specifically validate that operations on active assets do not fail due to a lack of allocations for previously withdrawn assets.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@codecov
Copy link
Copy Markdown

codecov Bot commented Nov 5, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @dimast-x, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request resolves an issue where the application's allocation validation incorrectly required allocations for assets that had been fully withdrawn and held a zero balance. The change introduces a modification to the verifyAllocations function to explicitly skip assets with zero balances, ensuring that the system only validates allocations for currently held assets. This enhances the robustness and correctness of asset management within application sessions.

Highlights

  • Allocation Validation Logic: The core validation logic for application allocations has been updated to correctly handle assets with zero balances, preventing unnecessary validation errors.
  • New Test Case: A new test case has been introduced to specifically verify that operations on active assets proceed correctly without requiring allocations for assets that have been fully withdrawn and thus have a zero balance.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request fixes an issue where operations on an app session would incorrectly fail if an asset with a zero balance was not included in the allocations. The change in verifyAllocations correctly skips validation for such assets. A new test case, Operate_WithdrawnAsset_NotRequired, has been added to verify this fix, which is a great addition. My review includes a couple of suggestions to improve the robustness of the new test by handling potential errors when fetching balances.

Comment thread clearnode/app_session_service_test.go
Comment thread clearnode/app_session_service_test.go
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request addresses a bug in the application session state validation. Previously, the validation logic incorrectly required allocations for assets with a zero balance, which caused failures for assets that had been fully withdrawn from a session. The fix correctly skips zero-balance assets during validation. A new test case has been added to confirm that operations on assets with positive balances can proceed without needing to specify allocations for zero-balance assets. The change is logical, well-targeted, and properly tested.

@dimast-x dimast-x requested a review from philanton November 5, 2025 09:12
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0f5a2a7 and b44a340.

📒 Files selected for processing (2)
  • clearnode/app_session_service_test.go (1 hunks)
  • clearnode/rpc_router_private.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
clearnode/app_session_service_test.go (3)
clearnode/pkg/rpc/api.go (4)
  • VersionNitroRPCv0_4 (33-33)
  • AppSessionIntentOperate (640-640)
  • Version (27-27)
  • AppAllocation (626-633)
clearnode/ledger.go (2)
  • NewAccountID (44-50)
  • GetWalletLedger (56-58)
clearnode/rpc_router_private.go (2)
  • SubmitAppStateParams (48-54)
  • AppAllocation (62-66)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Build and Publish (Clearnode)
  • GitHub Check: Test (Integration) / Test Integration
  • GitHub Check: Analyze (go)
🔇 Additional comments (1)
clearnode/app_session_service_test.go (1)

486-532: Test coverage: add case for zero-balance asset with non-zero allocation.

The test validates that zero-balance assets can be omitted from allocations (happy path). However, it doesn't cover the edge case where a zero-balance asset is included with a non-zero allocation, which should fail validation.

Consider adding a test case like:

t.Run("Operate_WithdrawnAsset_NonZeroAllocation_Error", func(t *testing.T) {
	db, cleanup := setupTestDB(t)
	defer cleanup()

	service := createTestAppSessionService(db, nil)
	session := createTestAppSession(t, db, "test-session-invalid-alloc", rpc.VersionNitroRPCv0_4,
		[]string{userAddressA.Hex(), userAddressB.Hex()}, []int64{1, 1}, 2)
	sessionAccountID := NewAccountID(session.SessionID)

	// USDC deposited then fully withdrawn (balance = 0)
	setupAppSessionBalances(t, db, sessionAccountID, map[common.Address]map[string]int{
		userAddressA: {"usdc": 100},
	})
	require.NoError(t, GetWalletLedger(db, userAddressA).Record(sessionAccountID, "usdc", decimal.NewFromInt(-100), nil))

	// Try to operate with non-zero USDC allocation despite zero balance
	params := &SubmitAppStateParams{
		AppSessionID: session.SessionID,
		Intent:       rpc.AppSessionIntentOperate,
		Version:      2,
		Allocations: []AppAllocation{
			{Participant: userAddressA.Hex(), AssetSymbol: "usdc", Amount: decimal.NewFromInt(50)},
			{Participant: userAddressB.Hex(), AssetSymbol: "usdc", Amount: decimal.NewFromInt(50)},
		},
	}

	_, err := service.SubmitAppState(context.Background(), params, rpcSigners(userAddressA, userAddressB), rpcSigners(userAddressA, userAddressB))
	require.Error(t, err)
	assert.Contains(t, err.Error(), "zero balance but non-zero allocation")
})

This will verify that the validation gap (flagged in rpc_router_private.go) is properly addressed.

Comment thread clearnode/rpc_router_private.go
@dimast-x dimast-x changed the title fix: skip empty assets in app allocations validation fix(clearnode): skip empty assets in app allocations validation Nov 5, 2025
@dimast-x dimast-x changed the title fix(clearnode): skip empty assets in app allocations validation YNU-457: skip empty assets in app allocations validation Nov 5, 2025
@philanton philanton merged commit 33f0e7b into main Nov 7, 2025
13 checks passed
@philanton philanton deleted the fix/app-state-empty-assets branch November 7, 2025 13:26
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.

4 participants