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

feat(rfq-api): don't respond to passive quotes for requests with zap params [SLT-430, SLT-432] #3388

Merged
merged 5 commits into from
Nov 14, 2024

Conversation

dwasse
Copy link
Collaborator

@dwasse dwasse commented Nov 12, 2024

Summary by CodeRabbit

  • New Features

    • Introduced new fields ZapData and ZapNative in quote requests to enhance data handling.
    • Improved quote processing logic to differentiate between standard and "Zap" quotes.
  • Bug Fixes

    • Enhanced error logging in quote handling to ensure clarity in reporting.
  • Tests

    • Expanded test coverage for quote requests to include new fields and validate system behavior.

Copy link
Contributor

coderabbitai bot commented Nov 12, 2024

Walkthrough

The changes in this pull request introduce new fields to the QuoteData struct in the services/rfq/api/model/request.go file, allowing for optional data representation. The DestAmount, RelayerAddress, and QuoteID fields are modified to be pointers. Additionally, the PutRFQRequest method in the server.go file is updated to handle these new fields through a new function, isZapQuote. The test cases in rfq_test.go are also updated to validate the behavior of requests with the new fields. Error handling improvements are made in the WebSocket client.

Changes

File Path Change Summary
services/rfq/api/model/request.go - Added fields: ZapData string \json:"zap_data"`, ZapNative string `json:"zap_native"`.<br>- Modified fields: DestAmount, RelayerAddress, QuoteID to be pointers (*string`).
services/rfq/api/rest/rfq_test.go - Updated TestActiveRFQFallbackToPassive to include tests for requests with ZapData and ZapNative, checking for failure responses when these fields are included.
services/rfq/api/rest/server.go - Added method: isZapQuote(req *model.PutRFQRequest) bool.
- Modified PutRFQRequest to handle both activeQuote and passiveQuote, incorporating checks for "Zap" quotes.
services/rfq/api/rest/ws.go - Modified error logging in handleSendQuote to log errors only if they are not nil, improving clarity in error reporting.

Possibly related PRs

Suggested labels

size/m

Suggested reviewers

  • aureliusbtc
  • trajan0x
  • dwasse

🐇 In the fields where quotes do play,
New data hops in, brightening the day!
With pointers and strings, we dance and we weave,
Handling requests, oh what we believe!
Errors now whisper, not shout in despair,
A better tomorrow, with quotes in the air! 🌼

Warning

There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure.

🔧 golangci-lint

level=warning msg="[config_reader] The configuration option run.skip-files is deprecated, please use issues.exclude-files."
level=warning msg="[config_reader] The configuration option run.skip-dirs is deprecated, please use issues.exclude-dirs."
level=warning msg="[config_reader] The configuration option run.skip-dirs-use-default is deprecated, please use issues.exclude-dirs-use-default."
level=warning msg="[lintersdb] The linter "maligned" is deprecated (step 2) and deactivated. It should be removed from the list of disabled linters. https://golangci-lint.run/product/roadmap/#linter-deprecation-cycle"
level=warning msg="[lintersdb] The linter "exhaustivestruct" is deprecated (step 2) and deactivated. It should be removed from the list of disabled linters. https://golangci-lint.run/product/roadmap/#linter-deprecation-cycle"
level=warning msg="[lintersdb] The linter "ifshort" is deprecated (step 2) and deactivated. It should be removed from the list of disabled linters. https://golangci-lint.run/product/roadmap/#linter-deprecation-cycle"
level=warning msg="[lintersdb] The linter "interfacer" is deprecated (step 2) and deactivated. It should be removed from the list of disabled linters. https://golangci-lint.run/product/roadmap/#linter-deprecation-cycle"
level=warning msg="[lintersdb] The linter "nosnakecase" is deprecated (step 2) and deactivated. It should be removed from the list of disabled linters. https://golangci-lint.run/product/roadmap/#linter-deprecation-cycle"
level=warning msg="[lintersdb] The name "goerr113" is deprecated. The linter has been renamed to: err113."
level=warning msg="The linter 'exportloopref' is deprecated (since v1.60.2) due to: Since Go1.22 (loopvar) this linter is no longer relevant. Replaced by copyloopvar."
level=warning msg="The linter 'execinquery' is deprecated (since v1.58.0) due to: The repository of the linter has been archived by the owner. "


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 98a0bad and 81bf628.

📒 Files selected for processing (3)
  • services/rfq/api/model/request.go (1 hunks)
  • services/rfq/api/rest/rfq_test.go (1 hunks)
  • services/rfq/api/rest/ws.go (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • services/rfq/api/model/request.go
  • services/rfq/api/rest/rfq_test.go
  • services/rfq/api/rest/ws.go

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.

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.

@github-actions github-actions bot added go Pull requests that update Go code size/xs labels Nov 12, 2024
Copy link

codecov bot commented Nov 12, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 26.60645%. Comparing base (23d4a7a) to head (81bf628).
Report is 1 commits behind head on feat/relayer-arb-call.

Additional details and impacted files
@@                       Coverage Diff                       @@
##           feat/relayer-arb-call       #3388         +/-   ##
===============================================================
- Coverage               26.62752%   26.60645%   -0.02108%     
===============================================================
  Files                        214         214                 
  Lines                      13625       13617          -8     
  Branches                      82          82                 
===============================================================
- Hits                        3628        3623          -5     
+ Misses                      9713        9711          -2     
+ Partials                     284         283          -1     
Flag Coverage Δ
opbot 0.18337% <ø> (ø)
packages 90.44834% <ø> (ø)
promexporter 6.81642% <ø> (ø)
solidity 98.65320% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link

cloudflare-workers-and-pages bot commented Nov 12, 2024

Deploying sanguine-fe with  Cloudflare Pages  Cloudflare Pages

Latest commit: 81bf628
Status: ✅  Deploy successful!
Preview URL: https://a8b2c8cf.sanguine-fe.pages.dev
Branch Preview URL: https://feat-zap-params.sanguine-fe.pages.dev

View logs

Copy link
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: 3

🧹 Outside diff range and nitpick comments (4)
services/rfq/api/rest/ws.go (2)

238-240: Consider enhancing error handling for zap-related cases

While the error handling improvement is good, given that this PR introduces zap-related changes, consider adding specific error handling or logging for zap parameter validation failures to help with debugging issues related to passive quotes with zap parameters.

 if err != nil {
-    logger.Errorf("error handling send quote: %v", err)
+    logger.Errorf("error handling send quote (zap validation failed: %t): %v", 
+        errors.Is(err, ErrZapValidationFailed), err)
 }

238-240: Consider standardizing error handling patterns

The WebSocket client has inconsistent error handling patterns across different operations. While some handlers return errors in response messages (subscribe/unsubscribe), the handleSendQuote logs and swallows errors. Consider standardizing the error handling approach for better maintainability and debugging.

Consider one of these approaches:

  1. Return error responses consistently across all operations
  2. Document why certain operations handle errors differently
services/rfq/api/rest/rfq_test.go (1)

310-319: Consider enhancing test coverage for zap parameters

The test case effectively verifies the basic rejection of requests with zap parameters. However, consider these improvements:

  1. Add test cases for edge cases:
    • Empty but non-null zap data
    • Invalid zap native amount
    • Maximum allowed values
  2. Add a comment explaining the business logic behind rejecting zap requests
  3. Verify that the request was properly logged for monitoring/debugging

Here's a suggested enhancement:

 	// Submit a user quote request with zap data
+	// Zap requests should be rejected as they require special handling
 	userQuoteReq.Data.ZapData = "abc"
 	userQuoteReq.Data.ZapNative = "100"
 	userQuoteResp, err = userClient.PutRFQRequest(c.GetTestContext(), userQuoteReq)
 	c.Require().NoError(err)
 
 	// Assert the response
 	c.Assert().False(userQuoteResp.Success)
 	c.Assert().Equal("no quotes found", userQuoteResp.Reason)
+
+	// Test edge cases
+	testCases := []struct {
+		name      string
+		zapData   string
+		zapNative string
+	}{
+		{"empty_zap_data", "", "100"},
+		{"invalid_zap_native", "abc", "invalid"},
+		{"max_values", strings.Repeat("a", 1000), "999999999"},
+	}
+
+	for _, tc := range testCases {
+		c.Run(tc.name, func() {
+			userQuoteReq.Data.ZapData = tc.zapData
+			userQuoteReq.Data.ZapNative = tc.zapNative
+			resp, err := userClient.PutRFQRequest(c.GetTestContext(), userQuoteReq)
+			c.Require().NoError(err)
+			c.Assert().False(resp.Success)
+			c.Assert().Equal("no quotes found", resp.Reason)
+		})
+	}
+
+	// Verify request logging
+	// TODO: Add verification that the request was properly logged
services/rfq/api/rest/server.go (1)

543-543: Consider adding logging for Zap quote decisions

Adding debug logging when skipping passive quotes due to Zap parameters would help with troubleshooting.

Apply this diff to add logging:

-  if !isZapQuote(&req) {
+  isZap := isZapQuote(&req)
+  if isZap {
+    logger.Debug("Skipping passive quote for Zap request", "request_id", requestID)
+  }
+  if !isZap {
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 978313d and 98a0bad.

📒 Files selected for processing (4)
  • services/rfq/api/model/request.go (1 hunks)
  • services/rfq/api/rest/rfq_test.go (1 hunks)
  • services/rfq/api/rest/server.go (3 hunks)
  • services/rfq/api/rest/ws.go (1 hunks)
🔇 Additional comments (3)
services/rfq/api/model/request.go (1)

62-64: 🛠️ Refactor suggestion

Document nullable fields and verify API compatibility

The conversion of DestAmount, RelayerAddress, and QuoteID to pointer types is a breaking change that could affect API clients. Please document when these fields might be nil.

Add documentation for the nullable fields:

+	// DestAmount is the target amount for the quote. May be nil for certain quote types.
 	DestAmount       *string `json:"dest_amount"`
+	// RelayerAddress is the address of the relayer. May be nil for user-initiated quotes.
 	RelayerAddress   *string `json:"relayer_address"`
+	// QuoteID is the unique identifier for the quote. May be nil for new quote requests.
 	QuoteID          *string `json:"quote_id"`

Let's verify the impact:

services/rfq/api/rest/server.go (2)

7-7: LGTM: Import addition is appropriate

The addition of the "math/big" package is necessary for handling large numbers in the new isZapQuote function.


536-550: ⚠️ Potential issue

Potential nil pointer dereference in quote handling

The code accesses DestAmount without checking if activeQuote or passiveQuote is nil first. While there is a nil check for the quotes themselves, accessing DestAmount should also be guarded.

Apply this diff to fix the potential nil pointer dereference:

 if isActiveRFQ {
   activeQuote = r.handleActiveRFQ(ctx, &req, requestID)
-  if activeQuote != nil && activeQuote.DestAmount != nil {
+  if activeQuote != nil {
+    if activeQuote.DestAmount != nil {
       span.SetAttributes(attribute.String("active_quote_dest_amount", *activeQuote.DestAmount))
+    }
   }
 }
 if !isZapQuote(&req) {
   passiveQuote, err = r.handlePassiveRFQ(ctx, &req)
   if err != nil {
     logger.Error("Error handling passive RFQ", "error", err)
   }
-  if passiveQuote != nil && passiveQuote.DestAmount != nil {
+  if passiveQuote != nil {
+    if passiveQuote.DestAmount != nil {
       span.SetAttributes(attribute.String("passive_quote_dest_amount", *passiveQuote.DestAmount))
+    }
   }
 }

Likely invalid or redundant comment.

Comment on lines 60 to 61
ZapData string `json:"zap_data"`
ZapNative string `json:"zap_native"`
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add documentation and consider validation for new zap fields

The new ZapData and ZapNative fields lack documentation explaining their purpose and expected format. Additionally, consider adding validation if there are specific format requirements or size constraints.

Add documentation above the fields:

+	// ZapData contains the Zap protocol-specific data for the quote request
 	ZapData          string  `json:"zap_data"`
+	// ZapNative specifies the native token amount for Zap protocol integration
 	ZapNative        string  `json:"zap_native"`
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ZapData string `json:"zap_data"`
ZapNative string `json:"zap_native"`
// ZapData contains the Zap protocol-specific data for the quote request
ZapData string `json:"zap_data"`
// ZapNative specifies the native token amount for Zap protocol integration
ZapNative string `json:"zap_native"`

Comment on lines +238 to +240
if err != nil {
logger.Errorf("error handling send quote: %v", err)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Potential race condition in error logging after connection closure

Errors may be logged after the WebSocket connection has been closed. Consider verifying the connection state before logging errors to prevent misleading log entries.

🔗 Analysis chain

Verify error logging after connection closure

There might be a race condition where errors are logged after the connection is closed. Consider adding a check for connection state before logging errors to avoid misleading logs.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for patterns where errors might be logged after connection closure
rg -A 5 "conn.*Close|close\(.*doneChan\)" 

Length of output: 2740

Comment on lines +582 to +592
func isZapQuote(req *model.PutRFQRequest) bool {
if req.Data.ZapData != "" {
return true
}

zapNative, ok := new(big.Int).SetString(req.Data.ZapNative, 10)
if !ok {
return false
}
return zapNative.Sign() != 0
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve error handling in isZapQuote function

The function has a few potential issues:

  1. It silently ignores invalid ZapNative values
  2. No validation is performed on ZapData
  3. The big.Int comparison could be more explicit

Apply this diff to improve error handling and clarity:

 func isZapQuote(req *model.PutRFQRequest) bool {
+  if req == nil || req.Data == nil {
+    return false
+  }
+
   if req.Data.ZapData != "" {
     return true
   }
 
+  if req.Data.ZapNative == "" {
+    return false
+  }
+
   zapNative, ok := new(big.Int).SetString(req.Data.ZapNative, 10)
   if !ok {
     return false
   }
-  return zapNative.Sign() != 0
+  return zapNative.Cmp(big.NewInt(0)) > 0
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func isZapQuote(req *model.PutRFQRequest) bool {
if req.Data.ZapData != "" {
return true
}
zapNative, ok := new(big.Int).SetString(req.Data.ZapNative, 10)
if !ok {
return false
}
return zapNative.Sign() != 0
}
func isZapQuote(req *model.PutRFQRequest) bool {
if req == nil || req.Data == nil {
return false
}
if req.Data.ZapData != "" {
return true
}
if req.Data.ZapNative == "" {
return false
}
zapNative, ok := new(big.Int).SetString(req.Data.ZapNative, 10)
if !ok {
return false
}
return zapNative.Cmp(big.NewInt(0)) > 0
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
go Pull requests that update Go code needs-go-generate-services/rfq size/s
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant