这是indexloc提供的服务,不要输入任何密码
Skip to content

fix: prevent bank balances query failure due to dispatch FA #411

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 26, 2025

Conversation

beer-1
Copy link
Member

@beer-1 beer-1 commented May 26, 2025

Description

  • Do balance query one by one to prevent balance query failure

Author Checklist

All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.

I have...

  • included the correct type prefix in the PR title, you can find examples of the prefixes below:
  • confirmed ! in the type prefix if API or client breaking change
  • targeted the correct branch
  • provided a link to the relevant issue or specification
  • reviewed "Files changed" and left comments if necessary
  • included the necessary unit and integration tests
  • updated the relevant documentation or specification, including comments for documenting Go code
  • confirmed all CI checks have passed

Reviewers Checklist

All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.

I have...

  • confirmed the correct type prefix in the PR title
  • confirmed all author checklist items have been addressed
  • reviewed state machine logic, API design and naming, documentation is accurate, tests and test coverage

@beer-1 beer-1 self-assigned this May 26, 2025
@beer-1 beer-1 requested a review from a team as a code owner May 26, 2025 08:43
Copy link

coderabbitai bot commented May 26, 2025

📝 Walkthrough

Walkthrough

The changes update balance retrieval and iteration methods in MoveBankKeeper to rely on store walking and collection pagination, replacing manual key iteration. Error handling is adjusted to return zero balances when fetches fail, simplifying the logic.

Changes

File(s) Change Summary
x/move/keeper/bank.go Modified balance retrieval and iteration methods to use store walking and pagination; relaxed error handling; streamlined iteration logic.

Poem

In the fields of code, I hop with glee,
Store-walking now sets my balances free.
No more manual loops or keys to chase,
Errors forgiven, zero takes their place.
Pagination’s smoother, less to debug—
A rabbit’s work, all tidy and snug! 🐇


📜 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 543dc62 and a169c08.

📒 Files selected for processing (1)
  • x/move/keeper/bank.go (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: golangci-lint
  • GitHub Check: Analyze (go)
  • GitHub Check: Run test and upload codecov
🔇 Additional comments (1)
x/move/keeper/bank.go (1)

68-71: Blindly swallowing ALL balance-fetch errors can hide serious issues

GetBalance now converts any upstream error into a silent 0 balance.
While this prevents dispatch-FA panics, it also masks unexpected bugs (e.g. serialization, permission, or store read failures) and makes them impossible to detect at higher layers.

Suggested direction:

-	if err != nil {
-		// ignore fetching error due to dispatchable fungible assets
-		return sdkmath.ZeroInt(), nil
-	}
+	if err != nil {
+		// Only ignore the known “dispatchable asset” failure.
+		if errors.Is(err, types.ErrDispatchFungibleAsset) { // pseudo-code
+			return sdkmath.ZeroInt(), nil
+		}
+
+		// Propagate all other errors
+		return sdkmath.ZeroInt(), err
+	}

At minimum, differentiate the error kinds or emit a log/telemetry event so operators can notice silent data loss.
Please verify whether types.ErrDispatchFungibleAsset (or a similar sentinel) exists and update the guard accordingly.

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

github-actions bot commented May 26, 2025

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

Copy link

@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

🧹 Nitpick comments (1)
x/move/keeper/bank.go (1)

212-213: Inconsistent error handling approach.

The comment suggests ignoring errors, but the method still returns the error. This creates inconsistency with the GetBalance method which now suppresses errors.

Clarify the error handling intention:

 if err != nil {
-  // ignore error from execute
-  return nil, nil, err
+  // Return error from execute - caller should handle appropriately
+  return nil, nil, err
 }

Or if errors should truly be ignored, implement consistent suppression:

 if err != nil {
-  // ignore error from execute
-  return nil, nil, err
+  // ignore error from execute due to dispatchable fungible assets
+  return nil, nil, nil
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1935bdf and 63b27be.

📒 Files selected for processing (1)
  • x/move/keeper/bank.go (4 hunks)
🔇 Additional comments (2)
x/move/keeper/bank.go (2)

102-133:

✅ Verification successful

Verify the new store walking approach for correctness and performance.

The method has been completely rewritten to use VMStore.Walk instead of manual iteration. While this change aligns with the PR objective of individual balance queries, there are several concerns:

  1. Performance: Each iteration now calls GetBalance individually, which executes a separate VM function call
  2. Error handling: Errors are propagated immediately, which could cause iteration to stop early
  3. Logic verification: Need to ensure the prefix-based walking covers all relevant entries

Let me verify the store walking logic and compare performance characteristics:

Consider adding error recovery or logging for debugging:

 return k.VMStore.Walk(ctx, new(collections.Range[[]byte]).Prefix(collections.NewPrefix(prefix)), func(_, value []byte) (stop bool, err error) {
   storeAddr, err := vmtypes.NewAccountAddressFromBytes(value)
   if err != nil {
+    // Log parsing error but continue iteration
+    k.Logger(ctx).Debug("failed to parse store address", "error", err, "value", fmt.Sprintf("%x", value))
-    return true, err
+    return false, nil
   }

🏁 Script executed:

#!/bin/bash
# Search for other usages of VMStore.Walk to understand the pattern
rg -A 15 "VMStore\.Walk" --type go

# Look for the old implementation pattern to understand what was replaced
rg -A 20 -B 5 "IterateAccountBalances" --type go

Length of output: 15579


IterateAccountBalances store-walk usage is sound

  • Prefix-based scanning (types.GetTableEntryPrefix) is consistent with all other VMStore.Walk calls and will cover every table entry.
  • Immediate error propagation matches the existing pattern in staking.go and keeper.go; silent error recovery isn’t used elsewhere.
  • Invoking GetBalance per entry incurs one VM call per denomination by design—if this per-balance granularity becomes a bottleneck, consider adding a batched query or caching layer in a follow-up.

No changes required.


69-70:

❓ Verification inconclusive

Critical concern: Error suppression may mask legitimate issues.

While ignoring errors from dispatchable fungible assets addresses the immediate dispatch FA failure issue, returning zero balance for all errors could mask legitimate system failures like network issues, VM execution problems, or data corruption.

Consider implementing more granular error handling:

 if err != nil {
-  // ignore fetching error due to dispatchable fungible assets
-  return sdkmath.ZeroInt(), nil
+  // Check if error is specifically related to dispatchable fungible assets
+  if isDispatchFAError(err) {
+    return sdkmath.ZeroInt(), nil
+  }
+  return sdkmath.ZeroInt(), err
 }

Let me verify what types of errors the ExecuteViewFunctionJSON can return to determine if blanket suppression is appropriate:


🏁 Script executed:

#!/bin/bash
# Search for error types returned by ExecuteViewFunctionJSON and related dispatch FA error patterns
rg -A 10 -B 5 "ExecuteViewFunctionJSON.*error|dispatch.*fungible.*asset.*error" --type go

Length of output: 91


🏁 Script executed:

#!/bin/bash
# 1. Locate all usages of ExecuteViewFunctionJSON in the repo
rg -n "ExecuteViewFunctionJSON" --type go

# 2. If any are found, show surrounding context (±5 lines) for each match
rg -n -A 5 -B 5 "ExecuteViewFunctionJSON" --type go

Length of output: 3578


🏁 Script executed:

#!/bin/bash
# Display the implementation of ExecuteViewFunctionJSON in handler.go
sed -n '530,600p' x/move/keeper/handler.go

Length of output: 1519


Refine error suppression to target only dispatchable FA errors

Blanket‐suppressing all errors and returning a zero balance may conceal genuine failures (e.g. payload build errors, VM aborts, gas or state issues). Instead, detect and ignore only the specific “dispatchable fungible asset” error, propagating all others:

 func (k MoveBankKeeper) GetBalance(… ) (sdkmath.Int, error) {
-   // ignore fetching error due to dispatchable fungible assets
-   return sdkmath.ZeroInt(), nil
+   // only suppress dispatchable FA errors
+   if isDispatchFAError(err) {
+     return sdkmath.ZeroInt(), nil
+   }
+   // propagate any other errors
+   return sdkmath.ZeroInt(), err
 }

• File: x/move/keeper/bank.go (around lines 69–70)
• Action:

  1. Determine which errors ExecuteViewFunctionJSON can return (payload, VM, gas, etc.).
  2. Implement isDispatchFAError(err) to match only the FA‐dispatch error.
  3. Ensure all other errors bubble up for proper visibility and handling.

Copy link

@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

♻️ Duplicate comments (1)
x/move/keeper/bank.go (1)

153-195: Address pagination logic issues identified in previous review.

The current implementation still has the same issues flagged in the previous review:

  1. Variable scope issue: The coin variable (line 153) is declared outside the pagination callback and reused, which can cause incorrect data if multiple items are processed.

  2. Error handling inconsistency: Mixed return values with some errors returning true (lines 163, 171, 177) and others returning false (line 157, 180).

Apply the fix suggested in the previous review to resolve variable scope and error handling issues:

-var coin sdk.Coin
 coins, pageRes, err := query.CollectionFilteredPaginate(ctx, k.VMStore, pageReq, func(_, value []byte) (bool, error) {
   storeAddr, err := vmtypes.NewAccountAddressFromBytes(value)
   if err != nil {
     return false, err
   }

   // load metadata from fungible store
   metadata, _, err := k.Balance(ctx, storeAddr)
   if err != nil {
-    return true, err
+    return false, err
   }

   // load denom from metadata
   denom, err := types.DenomFromMetadataAddress(
     ctx, k, metadata,
   )
   if err != nil {
-    return true, err
+    return false, err
   }

   // load balance from primary fungible store
   amount, err := k.GetBalance(ctx, addr, denom)
   if err != nil {
-    return true, err
+    return false, err
   }
   if !amount.IsPositive() {
     return false, nil
   }

-  coin = sdk.NewCoin(denom, amount)
   return true, nil
 }, func(_, value []byte) (sdk.Coin, error) {
-  return coin, nil
+  // Reconstruct coin in transform callback to avoid scope issues
+  storeAddr, err := vmtypes.NewAccountAddressFromBytes(value)
+  if err != nil {
+    return sdk.Coin{}, err
+  }
+  
+  metadata, _, err := k.Balance(ctx, storeAddr)
+  if err != nil {
+    return sdk.Coin{}, err
+  }
+  
+  denom, err := types.DenomFromMetadataAddress(ctx, k, metadata)
+  if err != nil {
+    return sdk.Coin{}, err
+  }
+  
+  amount, err := k.GetBalance(ctx, addr, denom)
+  if err != nil {
+    return sdk.Coin{}, err
+  }
+  
+  return sdk.NewCoin(denom, amount), nil
 }, func(o *query.CollectionsPaginateOptions[[]byte]) {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 63b27be and 543dc62.

📒 Files selected for processing (1)
  • x/move/keeper/bank.go (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Run test and upload codecov
  • GitHub Check: golangci-lint
  • GitHub Check: Analyze (go)
  • GitHub Check: Analyze (actions)
🔇 Additional comments (1)
x/move/keeper/bank.go (1)

69-70: LGTM: Error handling change aligns with PR objectives.

The relaxed error handling to return zero balance when fetching fails addresses the PR objective of preventing bank balance query failures due to dispatch FA issues. This is a sensible approach for maintaining system stability.

Copy link

codecov bot commented May 26, 2025

Codecov Report

Attention: Patch coverage is 55.31915% with 21 lines in your changes missing coverage. Please review.

Project coverage is 40.26%. Comparing base (1935bdf) to head (a169c08).
Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
x/move/keeper/bank.go 55.31% 15 Missing and 6 partials ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #411      +/-   ##
==========================================
- Coverage   40.33%   40.26%   -0.07%     
==========================================
  Files         296      296              
  Lines       27879    27815      -64     
==========================================
- Hits        11246    11201      -45     
+ Misses      14897    14885      -12     
+ Partials     1736     1729       -7     
Files with missing lines Coverage Δ
x/move/keeper/bank.go 45.59% <55.31%> (-3.91%) ⬇️

... and 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

@sh-cha sh-cha left a comment

Choose a reason for hiding this comment

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

lgtm

@beer-1 beer-1 merged commit 28e9c3f into main May 26, 2025
9 checks passed
@beer-1 beer-1 deleted the fix/prevent-bank-query-failure branch May 26, 2025 09:10
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.

2 participants