Skip to content
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

refactor(x/crosschain): save relationship between bridgeCall and quoteInfo #812

Merged
merged 1 commit into from
Nov 18, 2024

Conversation

zakir-code
Copy link
Contributor

@zakir-code zakir-code commented Nov 18, 2024

Summary by CodeRabbit

  • New Features

    • Introduced a new message type QuoteInfo for enhanced quote handling in cross-chain transactions.
    • Added methods to create and manipulate QuoteInfo objects, including converting the Oracle field to an Ethereum address.
  • Bug Fixes

    • Improved logic for handling outgoing bridge calls by ensuring the existence of quoteInfo before processing.
  • Refactor

    • Renamed and updated methods related to quote handling for clarity and consistency.

These changes streamline cross-chain operations and enhance user experience with improved quote management.

Copy link

coderabbitai bot commented Nov 18, 2024

Walkthrough

The changes in this pull request introduce a new message type, QuoteInfo, to the fx.gravity.crosschain.v1 package, which includes several fields relevant to bridge calls. Additionally, modifications are made to various methods in the keeper package to enhance the handling of bridge call quotes, replacing previous quote ID logic with the new QuoteInfo structure. This includes updates to method signatures and the addition of utility functions for creating and manipulating QuoteInfo objects.

Changes

File Path Change Summary
api/fx/gravity/crosschain/v1/types.pulsar.go Added new message type QuoteInfo with fields: id, token, fee, oracle, gas_limit, expiry.
proto/fx/gravity/crosschain/v1/types.proto Introduced QuoteInfo message definition with fields: uint64 id, string token, string fee, string oracle, uint64 gas_limit, uint64 expiry.
x/crosschain/keeper/abci.go Updated cleanupTimeOutBridgeCall method to use GetOutgoingBridgeCallQuoteInfo instead of GetOutgoingBridgeCallQuoteId.
x/crosschain/keeper/bridge_call_out.go Renamed methods and variables related to quote handling, updated signatures to use QuoteInfo. Added logic for fee transfer based on QuoteInfo.
x/crosschain/types/types.go Added NewQuoteInfo function to construct QuoteInfo and OracleAddress method to convert Oracle field to Ethereum address.

Possibly related PRs

🐇 In the land of code where rabbits play,
A new QuoteInfo hops in today.
With fields so bright, it guides the way,
For bridge calls and fees, come what may!
So let’s cheer for changes, hip-hip-hooray! 🎉

Warning

Rate limit exceeded

@zakir-code has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 20 minutes and 44 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 509f4cd and fab0116.


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 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.
    • Generate unit testing code for this file.
    • 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 generate unit testing code for this file.
    • @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 generate unit testing code.
    • @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.

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 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

@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: 3

🧹 Outside diff range and nitpick comments (6)
proto/fx/gravity/crosschain/v1/types.proto (1)

209-220: LGTM! Consider adding field documentation.

The QuoteInfo message structure is well-designed with appropriate field types and protobuf options. The fee field correctly uses cosmos.Int for handling large numbers with non-nullable constraint.

Consider adding comments to document the purpose and constraints of each field. Example:

 message QuoteInfo {
+  // Unique identifier for the quote
   uint64 id = 1;
+  // Token contract address or identifier
   string token = 2;
+  // Fee amount in cosmos.Int format
   string fee = 3 [
     (cosmos_proto.scalar) = "cosmos.Int",
     (gogoproto.customtype) = "cosmossdk.io/math.Int",
     (gogoproto.nullable) = false
   ];
+  // Oracle address that provided the quote
   string oracle = 4;
+  // Maximum gas limit for the bridge call
   uint64 gas_limit = 5;
+  // Block height or timestamp when the quote expires
   uint64 expiry = 6;
 }
x/crosschain/keeper/abci.go (1)

171-182: Consider adding logging for bridge call cleanup actions

The cleanup logic handles two cases (refund and resend) but doesn't log these important state transitions. Consider adding debug logs to help with monitoring and debugging.

 quoteInfo, found := k.GetOutgoingBridgeCallQuoteInfo(ctx, data.Nonce)
 if !found {
+    k.Logger(ctx).Debug("cleaning up timed out bridge call - initiating refund", "nonce", data.Nonce)
     // 1. handler bridge call refund
     if err = k.RefundOutgoingBridgeCall(ctx, data); err != nil {
         return true
     }
 } else {
+    k.Logger(ctx).Debug("cleaning up timed out bridge call - resending", "nonce", data.Nonce)
     // 1. resend bridge call
     if err = k.ResendBridgeCall(ctx, *data, quoteInfo); err != nil {
         return true
     }
 }
x/crosschain/keeper/bridge_call_out.go (2)

422-443: Add input validation and documentation

The QuoteInfo methods would benefit from:

  1. Input validation for nonce
  2. Godoc comments explaining the methods' purpose and parameters

Apply this diff:

+// SetOutgoingBridgeCallQuoteInfo stores the quote information for a bridge call
+// nonce must be greater than 0
 func (k Keeper) SetOutgoingBridgeCallQuoteInfo(ctx sdk.Context, nonce uint64, quoteInfo types.QuoteInfo) {
+    if nonce == 0 {
+        panic("nonce cannot be zero")
+    }
     store := ctx.KVStore(k.storeKey)
     store.Set(types.GetBridgeCallQuoteKey(nonce), k.cdc.MustMarshal(&quoteInfo))
 }

+// GetOutgoingBridgeCallQuoteInfo retrieves the quote information for a bridge call
+// returns the quote info and whether it was found
 func (k Keeper) GetOutgoingBridgeCallQuoteInfo(ctx sdk.Context, nonce uint64) (types.QuoteInfo, bool) {
+    if nonce == 0 {
+        return types.QuoteInfo{}, false
+    }
     store := ctx.KVStore(k.storeKey)
     bz := store.Get(types.GetBridgeCallQuoteKey(nonce))
     if bz == nil {
         return types.QuoteInfo{}, false
     }
     quoteInfo := types.QuoteInfo{}
     k.cdc.MustUnmarshal(bz, &quoteInfo)
     return quoteInfo, true
 }

+// DeleteOutgoingBridgeCallQuoteInfo removes the quote information for a bridge call
 func (k Keeper) DeleteOutgoingBridgeCallQuoteInfo(ctx sdk.Context, nonce uint64) {
+    if nonce == 0 {
+        return
+    }
     store := ctx.KVStore(k.storeKey)
     store.Delete(types.GetBridgeCallQuoteKey(nonce))
 }

Line range hint 445-466: Add validations and handle edge cases

The function needs improvements in several areas:

  1. Input validation for bridgeCall and quoteInfo
  2. Proper error handling for timeout calculation
  3. Transaction safety for quote info transfer

Apply this diff:

 func (k Keeper) ResendBridgeCall(ctx sdk.Context, bridgeCall types.OutgoingBridgeCall, quoteInfo types.QuoteInfo) error {
+    if bridgeCall.Nonce == 0 {
+        return types.ErrInvalid.Wrap("invalid bridge call nonce")
+    }
+    if quoteInfo.Fee.IsNil() {
+        return types.ErrInvalid.Wrap("invalid quote info")
+    }
     bridgeCallTimeout := k.CalExternalTimeoutHeight(ctx, GetBridgeCallTimeout)
     if bridgeCallTimeout <= 0 {
         return types.ErrInvalid.Wrapf("bridge call timeout height")
     }
     oldBridgeCallNonce := bridgeCall.Nonce
-    k.DeleteOutgoingBridgeCallQuoteInfo(ctx, oldBridgeCallNonce)
     newBridgeCallNonce := k.autoIncrementID(ctx, types.KeyLastBridgeCallID)
     bridgeCall.Nonce = newBridgeCallNonce
     bridgeCall.Timeout = bridgeCallTimeout
+    // Set new quote info before deleting old one to maintain data consistency
+    k.SetOutgoingBridgeCallQuoteInfo(ctx, newBridgeCallNonce, quoteInfo)
     k.SetOutgoingBridgeCall(ctx, &bridgeCall)
-    k.SetOutgoingBridgeCallQuoteInfo(ctx, newBridgeCallNonce, quoteInfo)
+    k.DeleteOutgoingBridgeCallQuoteInfo(ctx, oldBridgeCallNonce)
     ctx.EventManager().EmitEvent(sdk.NewEvent(types.EventTypeBridgeCallResend,
         sdk.NewAttribute(types.AttributeKeyBridgeCallResendOldNonce, fmt.Sprintf("%d", oldBridgeCallNonce)),
         sdk.NewAttribute(types.AttributeKeyBridgeCallResendNewNonce, fmt.Sprintf("%d", newBridgeCallNonce))),
     )
     return k.erc20Keeper.ReSetCache(ctx, types.NewOriginTokenKey(k.moduleName, oldBridgeCallNonce), types.NewOriginTokenKey(k.moduleName, newBridgeCallNonce))
 }
api/fx/gravity/crosschain/v1/types.pulsar.go (2)

9258-9264: Consider adding field validation and documentation.

The QuoteInfo struct could benefit from:

  1. Input validation for critical fields:
    • fee should be a valid cosmos-sdk Int
    • oracle should be a valid address
    • expiry should be a future timestamp
  2. Documentation explaining:
    • The purpose of each field
    • Valid value ranges
    • Relationships between fields

9253-9264: Consider enhancing the quote information model.

The QuoteInfo message provides a good foundation for storing bridge call quotes. Consider these architectural improvements:

  1. Add version field for future compatibility
  2. Consider using a more precise type for fees (e.g., fixed-point decimal)
  3. Add status field to track quote lifecycle
  4. Consider adding audit fields (created_at, updated_at)

Also applies to: 9511-9523

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 509f4cd and fab0116.

⛔ Files ignored due to path filters (1)
  • x/crosschain/types/types.pb.go is excluded by !**/*.pb.go
📒 Files selected for processing (5)
  • api/fx/gravity/crosschain/v1/types.pulsar.go (6 hunks)
  • proto/fx/gravity/crosschain/v1/types.proto (1 hunks)
  • x/crosschain/keeper/abci.go (1 hunks)
  • x/crosschain/keeper/bridge_call_out.go (1 hunks)
  • x/crosschain/types/types.go (1 hunks)
🔇 Additional comments (7)
proto/fx/gravity/crosschain/v1/types.proto (1)

Line range hint 182-207: Verify the relationship between OutgoingBridgeCall and QuoteInfo.

The PR objective mentions saving the relationship between bridgeCall and quoteInfo, but there's no direct reference between these messages in the proto definitions.

Let's verify how this relationship is implemented:

Also applies to: 209-220

✅ Verification successful

Let me gather more information about the relationship implementation by checking the key and type definitions.


Based on the gathered information, I can now provide the final response:

The relationship between OutgoingBridgeCall and QuoteInfo is correctly implemented through a KV store mapping.

The relationship is maintained through:

  • A one-to-one mapping between bridge call nonce and QuoteInfo in the KV store
  • CRUD operations in the keeper:
    • SetOutgoingBridgeCallQuoteInfo: Creates/updates the mapping
    • GetOutgoingBridgeCallQuoteInfo: Retrieves QuoteInfo by bridge call nonce
    • DeleteOutgoingBridgeCallQuoteInfo: Removes the mapping
  • The relationship is properly handled during bridge call lifecycle (creation, resend, refund)

No direct reference in the proto definition is needed as the relationship is managed at the storage level using the bridge call nonce as the key.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check how QuoteInfo is referenced from OutgoingBridgeCall in the codebase

# Search for files that might contain the relationship implementation
echo "Files that might contain the relationship implementation:"
fd -e go -e proto | rg -l "OutgoingBridgeCall|QuoteInfo"

# Search for code that links these types
echo -e "\nCode that links OutgoingBridgeCall and QuoteInfo:"
rg -A 5 "OutgoingBridgeCall.*QuoteInfo|QuoteInfo.*OutgoingBridgeCall"

Length of output: 4731


Script:

#!/bin/bash
# Check the key definition and type implementations
echo "Checking key definition for bridge call quote:"
rg "GetBridgeCallQuoteKey|KeyLastBridgeCallID" -A 3

echo -e "\nChecking QuoteInfo type definition:"
rg "type QuoteInfo struct" -A 5

Length of output: 3572

x/crosschain/keeper/abci.go (3)

171-172: Verify error handling for GetOutgoingBridgeCallQuoteInfo

The code correctly uses the tuple return pattern (value, found) for checking quote info existence. However, we should verify that the GetOutgoingBridgeCallQuoteInfo method properly handles all error cases.

#!/bin/bash
# Search for the implementation and error handling in GetOutgoingBridgeCallQuoteInfo
ast-grep --pattern 'func $_ GetOutgoingBridgeCallQuoteInfo($_) ($_, $_) {
  $$$
}'

Line range hint 171-189: Verify the atomicity of cleanup operations

The code performs multiple state changes (refund/resend followed by deletion). We should ensure that these operations are atomic and that the state remains consistent if any operation fails.

#!/bin/bash
# Search for any existing transaction handling or recovery mechanisms
rg -A 5 'BeginBlock|EndBlock|SavePoint|Commit' 

179-179: Verify the updated ResendBridgeCall signature

The ResendBridgeCall method has been updated to accept quoteInfo as a parameter. Let's verify its implementation to ensure proper handling of the new parameter.

✅ Verification successful

ResendBridgeCall implementation correctly matches the updated signature

The method signature has been properly updated to accept three parameters: ctx sdk.Context, bridgeCall types.OutgoingBridgeCall, and quoteInfo types.QuoteInfo. The implementation shows proper handling of bridge call resending with nonce management.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for the ResendBridgeCall implementation
ast-grep --pattern 'func $_ ResendBridgeCall($_, $_, $_) error {
  $$$
}'

Length of output: 249


Script:

#!/bin/bash
# Search for the ResendBridgeCall implementation with rg
rg -U "func.*ResendBridgeCall.*\{" -A 10

Length of output: 979

x/crosschain/types/types.go (1)

522-524: LGTM!

The method safely converts the Oracle hex string to an Ethereum address using the appropriate Ethereum type.

api/fx/gravity/crosschain/v1/types.pulsar.go (2)

7689-8379: LGTM: Generated reflection code is complete and correct.

The protobuf reflection implementation is properly generated with comprehensive error handling and proper edge case management.


9511-9523: Verify protobuf generation is up-to-date.

The protobuf metadata has been updated to include the new QuoteInfo message. Please ensure:

  1. The protobuf generation is reproducible
  2. The proto file changes are committed

Also applies to: 9569-9569, 9583-9585

✅ Verification successful

Let me gather more information about the protobuf generation setup to verify if everything is properly configured.


Based on the gathered information, I can now provide the final response:

Protobuf generation setup is correctly configured and up-to-date

The verification shows:

  • The QuoteInfo message is properly defined in proto/fx/gravity/crosschain/v1/types.proto
  • The protobuf generation setup is properly configured with protocgen.sh and protocgen-pulsar.sh
  • No uncommitted changes exist in proto files
  • The generated code matches the proto definition
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that protobuf generation is up-to-date

# Find and check the proto file
fd -e proto | xargs grep -l "QuoteInfo"

# Verify protobuf generation command in Makefile
fd Makefile | xargs grep -A 5 "proto-gen"

Length of output: 629


Script:

#!/bin/bash
# Check the content of protocgen.sh and proto file
cat scripts/protocgen.sh
cat proto/fx/gravity/crosschain/v1/types.proto

# Check if there are any uncommitted changes in proto files
git status --porcelain "**/*.proto"

Length of output: 8393

x/crosschain/keeper/bridge_call_out.go Show resolved Hide resolved
x/crosschain/keeper/bridge_call_out.go Show resolved Hide resolved
x/crosschain/types/types.go Show resolved Hide resolved
@zakir-code zakir-code merged commit 6612629 into main Nov 18, 2024
12 checks passed
@zakir-code zakir-code deleted the fx0x55/save-quote branch November 18, 2024 08:25
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