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

RFQ Relayer: restrict state transitions #2787

Merged
merged 23 commits into from
Jul 2, 2024
Merged

Conversation

dwasse
Copy link
Collaborator

@dwasse dwasse commented Jun 25, 2024

Summary by CodeRabbit

  • New Features

    • Introduced a new 'Keys()' method in map mutex interfaces for retrieving all keys.
    • Added logging for state transitions in quote requests.
  • Bug Fixes

    • Enhanced the UpdateQuoteRequestStatus function to check for valid state transitions and log any invalid transitions.
  • Tests

    • Added new test cases for key retrieval in different types of map mutexes.

Copy link
Contributor

coderabbitai bot commented Jun 25, 2024

Walkthrough

The recent updates involve integrating a logger for the relayer-db package and modifying the UpdateQuoteRequestStatus function to verify valid state transitions within various services related to RFQs (Request for Quotes). Moreover, the core/mapmutex package has been enhanced with a Keys() method for easier key retrieval, including respective tests, across several map-related mutex interfaces.

Changes

File(s) Summary
services/rfq/relayer/reldb/base/quote.go Added logger and valid state transition checks in UpdateQuoteRequestStatus. Introduced isValidStateTransition.
services/rfq/relayer/reldb/db.go Modified UpdateQuoteRequestStatus method signature to include prevStatus.
services/rfq/relayer/service/chainindexer.go Updated UpdateQuoteRequestStatus calls to include additional prevStatus argument.
services/rfq/relayer/service/handlers.go Enhanced UpdateQuoteRequestStatus usages in various handler functions to pass additional status arguments.
services/rfq/relayer/service/relayer.go Adjusted processRequest for improved status updating logic with status reference passing.
services/rfq/relayer/service/statushandler.go Updated deadlineMiddleware to include req.Status in UpdateQuoteRequestStatus calls.
core/mapmutex/mapmutex.go Added Keys() method to untypedMapMutex and implemented in untypedMapMutexImpl for debugging purposes.
core/mapmutex/mapmutex_test.go Introduced tests for key retrieval functionalities in various map mutex types.
core/mapmutex/stringer.go Added Keys() method to StringerMapMutex, StringMapMutex, and IntMapMutex interfaces, and provided implementations.

Poem

A logger’s tale, a journey to refine,
Quote requests now traverse a secure line.
State transitions verified, errors foregone,
Keys unlocked, mutexes carry on.
Debugging’s a breeze, status held tight,
In RFQ’s realm, transitions bright. 🌟🐇


Tip

Early access features: enabled

We are currently testing the following features in early access:

  • OpenAI gpt-4o model for code reviews and chat: OpenAI claims that this model is better at understanding and generating code than the previous models. We seek your feedback over the next few weeks before making it generally available.

Note:

  • You can enable or disable early access features from the CodeRabbit UI or by updating the CodeRabbit configuration file.
  • Please join our Discord Community to provide feedback and report issues.
  • OSS projects are currently opted into early access features by default.

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>.
    • 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 generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @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 as 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.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration 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.

@github-actions github-actions bot added go Pull requests that update Go code size/s labels Jun 25, 2024
Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

PR Summary

  • Added state transition validation to UpdateQuoteRequestStatus in quote.go
  • Introduced prevStatus parameter to UpdateQuoteRequestStatus in db.go
  • Updated UpdateQuoteRequestStatus calls in chainindexer.go with new parameter
  • Ensured proper state management in handlers.go by including previous status
  • Modified UpdateQuoteRequestStatus in relayer.go and statushandler.go to include current status

6 file(s) reviewed, no comment(s)

Copy link

codecov bot commented Jun 25, 2024

Codecov Report

Attention: Patch coverage is 40.00000% with 45 lines in your changes missing coverage. Please review.

Project coverage is 25.64578%. Comparing base (0d573f2) to head (b140cb2).

Files Patch % Lines
services/rfq/relayer/reldb/base/quote.go 0.00000% 15 Missing ⚠️
services/rfq/relayer/service/handlers.go 0.00000% 13 Missing ⚠️
services/rfq/relayer/service/statushandler.go 0.00000% 8 Missing ⚠️
services/rfq/relayer/service/chainindexer.go 0.00000% 7 Missing ⚠️
services/rfq/relayer/service/relayer.go 0.00000% 2 Missing ⚠️
Additional details and impacted files
@@                 Coverage Diff                 @@
##              master       #2787         +/-   ##
===================================================
+ Coverage   25.57487%   25.64578%   +0.07090%     
===================================================
  Files            766         766                 
  Lines          54925       54972         +47     
  Branches          80          80                 
===================================================
+ Hits           14047       14098         +51     
+ Misses         39428       39427          -1     
+ Partials        1450        1447          -3     
Flag Coverage Δ
cctp-relayer 31.93780% <ø> (ø)
core 59.29936% <100.00000%> (+0.68200%) ⬆️
ethergo 48.27025% <ø> (+0.01356%) ⬆️
explorer 4.97877% <ø> (ø)
git-changes-action 23.69615% <ø> (ø)
omnirpc 33.08129% <ø> (ø)
opbot 0.21082% <ø> (ø)
promexporter 8.50242% <ø> (ø)
rfq 27.07075% <0.00000%> (-0.05088%) ⬇️
screener-api 29.79798% <ø> (+0.50505%) ⬆️
scribe 18.17597% <ø> (+0.06437%) ⬆️
tools 30.55118% <ø> (ø)

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 Jun 25, 2024

Deploying sanguine-fe with  Cloudflare Pages  Cloudflare Pages

Latest commit: b140cb2
Status: ✅  Deploy successful!
Preview URL: https://1e17f5b9.sanguine-fe.pages.dev
Branch Preview URL: https://feat-restrict-state-tx.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

Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 0de75b0 and fe03dfe.

Files selected for processing (6)
  • services/rfq/relayer/reldb/base/quote.go (3 hunks)
  • services/rfq/relayer/reldb/db.go (1 hunks)
  • services/rfq/relayer/service/chainindexer.go (4 hunks)
  • services/rfq/relayer/service/handlers.go (12 hunks)
  • services/rfq/relayer/service/relayer.go (1 hunks)
  • services/rfq/relayer/service/statushandler.go (1 hunks)
Additional context used
GitHub Check: Build (1.22.x, ubuntu-latest)
services/rfq/relayer/service/handlers.go

[failure] 378-378:
undefined: request

Additional comments not posted (5)
services/rfq/relayer/reldb/base/quote.go (1)

17-18: Introduced global logger for relayer-db

Adding a logger is a good practice for tracking application behavior and errors, which is crucial for debugging and monitoring.

services/rfq/relayer/service/chainindexer.go (1)

88-88: Ensure consistency in error handling for UpdateQuoteRequestStatus calls

All calls to UpdateQuoteRequestStatus in this file pass nil for prevStatus. This could lead to unintended behavior if the prevStatus is required for accurate validation. Verify that this is the intended usage or consider passing the actual previous status where necessary.

Also applies to: 102-102, 116-116, 209-209

services/rfq/relayer/reldb/db.go (1)

27-27: Updated function signature to include prevStatus

The function UpdateQuoteRequestStatus now requires a prevStatus parameter. This change aligns with the need for more robust state transition checks as indicated in the summary. Ensure all calls to this function are updated accordingly.

services/rfq/relayer/service/statushandler.go (1)

141-141: Handling of deadline exceeded status

The middleware correctly updates the status to DeadlineExceeded when the current time surpasses the deadline. This is a critical update for maintaining the integrity of the quote request lifecycle. Ensure that the prevStatus is correctly utilized in the status update logic.

services/rfq/relayer/service/relayer.go (1)

394-394: Proper handling of expired deadlines in processRequest

The method checks if the quote request has expired and updates its status accordingly. This is crucial for preventing actions on outdated requests. However, ensure that prevStatus is appropriately used to prevent incorrect state transitions.

Comment on lines 140 to 145
func isValidStateTransition(prevStatus, status reldb.QuoteRequestStatus) bool {
if status == reldb.DeadlineExceeded || status == reldb.WillNotProcess {
return true
}
return status > prevStatus
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Validation logic in isValidStateTransition seems limited

The function checks if the new status is greater than the previous status or matches specific statuses. This might be too restrictive or not adequately capture valid transitions, depending on business rules. If more complex rules are needed, consider expanding this logic or using a state machine library.

Comment on lines 96 to 108
func (s Store) UpdateQuoteRequestStatus(ctx context.Context, id [32]byte, status reldb.QuoteRequestStatus, prevStatus *reldb.QuoteRequestStatus) error {
if prevStatus == nil {
req, err := s.GetQuoteRequestByID(ctx, id)
if err != nil {
return fmt.Errorf("could not get quote: %w", err)
}
prevStatus = &req.Status
}
if !isValidStateTransition(*prevStatus, status) {
logger.Warnf("invalid state transition from %s to %s [txid=%s]", *prevStatus, status, hexutil.Encode(id[:]))
return nil
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Review the logic for state transition validation and error handling

The method UpdateQuoteRequestStatus now includes logic to handle state transitions validation. While the use of prevStatus to fetch the current status if not provided is logical, the function returns nil when an invalid state transition is detected, which might silently ignore errors. Consider returning an error instead to make the failure explicit.

- return nil
+ return fmt.Errorf("invalid state transition from %s to %s [txid=%s]", *prevStatus, status, hexutil.Encode(id[:]))
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 (s Store) UpdateQuoteRequestStatus(ctx context.Context, id [32]byte, status reldb.QuoteRequestStatus, prevStatus *reldb.QuoteRequestStatus) error {
if prevStatus == nil {
req, err := s.GetQuoteRequestByID(ctx, id)
if err != nil {
return fmt.Errorf("could not get quote: %w", err)
}
prevStatus = &req.Status
}
if !isValidStateTransition(*prevStatus, status) {
logger.Warnf("invalid state transition from %s to %s [txid=%s]", *prevStatus, status, hexutil.Encode(id[:]))
return nil
}
func (s Store) UpdateQuoteRequestStatus(ctx context.Context, id [32]byte, status reldb.QuoteRequestStatus, prevStatus *reldb.QuoteRequestStatus) error {
if prevStatus == nil {
req, err := s.GetQuoteRequestByID(ctx, id)
if err != nil {
return fmt.Errorf("could not get quote: %w", err)
}
prevStatus = &req.Status
}
if !isValidStateTransition(*prevStatus, status) {
logger.Warnf("invalid state transition from %s to %s [txid=%s]", *prevStatus, status, hexutil.Encode(id[:]))
return fmt.Errorf("invalid state transition from %s to %s [txid=%s]", *prevStatus, status, hexutil.Encode(id[:]))
}

prevStatus = &req.Status
}
if !isValidStateTransition(*prevStatus, status) {
logger.Warnf("invalid state transition from %s to %s [txid=%s]", *prevStatus, status, hexutil.Encode(id[:]))
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Chose not to return error here since we presumably don't want to panic on this, and checking errors.Is() on the result introduces a bit of code bloat

Copy link
Contributor

Choose a reason for hiding this comment

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

Completely understand the hesitation to do this, but in this case I'll be renaming the method to UpdateQuoteRequestStatusIFValid or somethign.

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

PR Summary

(updates since last review)

  • Enhanced logging for quote request status updates
  • Added validation for state transitions during quote request status updates
  • Updated functions to include previous status parameter for quote request status updates
  • Introduced Prometheus metrics setup in RFQ API server
  • Added new indirect dependency on github.com/cornelk/hashmap

29 file(s) reviewed, no comment(s)

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

PR Summary

(updates since last review)

  • Enhanced logging for quote request status updates
  • Added validation for state transitions during quote request status updates
  • Improved handling of quote request statuses by passing previous status information
  • Updated functions to include an additional parameter for previous status in quote request status updates

No file(s) reviewed, no comment(s)

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

PR Summary

(updates since last review)

  • Enhanced logging for quote request status updates
  • Added validation for state transitions during quote request status updates
  • Introduced Keys() method to untypedMapMutex interface for debugging
  • Replaced relayMtx with handlerMtx for state transition handling
  • Updated functions to include previous status information for quote requests

7 file(s) reviewed, 1 comment(s)

@@ -11,6 +11,7 @@ import (
"github.com/ethereum/go-ethereum/common"
. "github.com/stretchr/testify/assert"
"github.com/synapsecns/sanguine/core/mapmutex"
"gotest.tools/assert"
Copy link

Choose a reason for hiding this comment

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

🪶 style: Redundant import of gotest.tools/assert. Consider using only one assertion library for consistency.

Copy link
Contributor

Choose a reason for hiding this comment

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

@dwasse also a good take

Copy link
Contributor

Choose a reason for hiding this comment

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

fixed in e867a9b

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

Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

Commits

Files that changed from the base of the PR and between fe03dfe and cf1acb4.

Files selected for processing (7)
  • core/mapmutex/mapmutex.go (3 hunks)
  • core/mapmutex/mapmutex_test.go (2 hunks)
  • core/mapmutex/stringer.go (5 hunks)
  • services/rfq/relayer/service/chainindexer.go (2 hunks)
  • services/rfq/relayer/service/handlers.go (13 hunks)
  • services/rfq/relayer/service/relayer.go (3 hunks)
  • services/rfq/relayer/service/statushandler.go (5 hunks)
Files skipped from review as they are similar to previous changes (3)
  • services/rfq/relayer/service/chainindexer.go
  • services/rfq/relayer/service/relayer.go
  • services/rfq/relayer/service/statushandler.go
Additional context used
GitHub Check: Lint (core)
core/mapmutex/stringer.go

[failure] 32-32:
type assertion must be checked (forcetypeassert)


[failure] 77-77:
type assertion must be checked (forcetypeassert)


[failure] 107-107:
type assertion must be checked (forcetypeassert)

GitHub Check: Build (1.22.x, ubuntu-latest)
services/rfq/relayer/service/handlers.go

[failure] 378-378:
undefined: request

Additional comments not posted (6)
core/mapmutex/stringer.go (3)

11-11: New method added to StringerMapMutex interface.

The addition of the Keys() method is consistent with the changes in other mutex interfaces to provide a way to retrieve all keys. This is useful for debugging and monitoring.


48-48: New method added to StringMapMutex interface.

The Keys() method has been consistently added across different mutex interfaces, enhancing the utility and consistency of the API.


86-86: New method added to IntMapMutex interface.

Adding the Keys() method allows for consistent functionality across all mutex types, facilitating easier management and debugging.

core/mapmutex/mapmutex.go (1)

17-17: New method added to untypedMapMutex interface.

The addition of the Keys() method is a useful enhancement for debugging and monitoring purposes, allowing access to current keys in the mutex map.

core/mapmutex/mapmutex_test.go (1)

56-76: New test cases for Keys() method across different mutex implementations.

These tests are well-structured and provide coverage for the new functionality. They check both the content and the size of the keys list, which is crucial for verifying the correct behavior of the Keys() method.

services/rfq/relayer/service/handlers.go (1)

145-145: Review of Updated UpdateQuoteRequestStatus Calls

All the updates to UpdateQuoteRequestStatus function calls across various functions seem to correctly pass the new prevStatus parameter where needed. This aligns with the PR's objective to enhance state transition validations by passing the previous status into the update function.

However, there are a couple of issues and improvements to note:

  1. Error Handling and Logging: Ensure that all errors are handled appropriately and logged. This is crucial for debugging and maintaining the system, especially in a blockchain context where transactions are irreversible.

  2. Static Analysis Issue:

    • Line 378: The variable request is undefined in the context of handleProofProvided. This is likely a copy-paste error or an oversight. This needs a fix to use the correct variable from the function's scope.
    - err = r.db.UpdateQuoteRequestStatus(ctx, req.TransactionId, reldb.ProvePosted, &request.Status)
    + err = r.db.UpdateQuoteRequestStatus(ctx, req.TransactionId, reldb.ProvePosted, &req.Status)
  3. Consistency Check:

    • General: For functions where prevStatus is set to nil, consider whether this is intentional or if it should be fetching the current status from the database or another source. This could potentially lead to incorrect state transitions if not handled correctly.
  4. Performance Consideration:

    • General: When updating statuses in a blockchain context, consider the implications of transaction costs and delays. Efficient handling of these updates can prevent unnecessary costs and improve the responsiveness of the system.
  5. Security Checks:

    • General: Ensure that all status updates are authorized and validated to prevent unauthorized state changes, which could be critical in a financial or blockchain system.

Overall, the changes align well with the objectives of the PR, but the highlighted issues and considerations should be addressed to ensure robustness and security.

Also applies to: 170-170, 182-182, 209-209, 273-273, 303-303, 335-335, 364-364, 378-378, 411-411, 446-446, 463-463

Comment on lines 73 to 80
// Keys returns the keys of the map.
func (s stringMutexImpl) Keys() []string {
keys := []string{}
for _, key := range s.mapMux.Keys() {
keys = append(keys, key.(string))
}
return keys
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Implementation of Keys() in stringMutexImpl needs safe type assertion.

Similar to the stringerLockerImpl, this implementation also needs to handle type assertions safely to prevent potential runtime panics.

-		keys = append(keys, key.(string))
+		strKey, ok := key.(string)
+		if !ok {
+		    return nil, fmt.Errorf("type assertion to string failed")
+		}
+		keys = append(keys, strKey)
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
// Keys returns the keys of the map.
func (s stringMutexImpl) Keys() []string {
keys := []string{}
for _, key := range s.mapMux.Keys() {
keys = append(keys, key.(string))
}
return keys
}
// Keys returns the keys of the map.
func (s stringMutexImpl) Keys() ([]string, error) {
keys := []string{}
for _, key := range s.mapMux.Keys() {
strKey, ok := key.(string)
if !ok {
return nil, fmt.Errorf("type assertion to string failed")
}
keys = append(keys, strKey)
}
return keys, nil
}
Tools
GitHub Check: Lint (core)

[failure] 77-77:
type assertion must be checked (forcetypeassert)

Comment on lines 28 to 35
// Keys returns the keys of the map.
func (s stringerLockerImpl) Keys() []string {
keys := []string{}
for _, key := range s.mapMux.Keys() {
keys = append(keys, key.(string))
}
return keys
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Implementation of Keys() in stringerLockerImpl needs safe type assertion.

The method uses a type assertion that could panic if the underlying type is not a string. This should be handled more safely.

-		keys = append(keys, key.(string))
+		strKey, ok := key.(string)
+		if !ok {
+		    return nil, fmt.Errorf("type assertion to string failed")
+		}
+		keys = append(keys, strKey)

Committable suggestion was skipped due to low confidence.

Tools
GitHub Check: Lint (core)

[failure] 32-32:
type assertion must be checked (forcetypeassert)

Comment on lines 103 to 110
// Keys returns the keys of the map.
func (i intMapMux) Keys() []int {
keys := []int{}
for _, key := range i.mapMux.Keys() {
keys = append(keys, key.(int))
}
return keys
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Implementation of Keys() in intMapMux needs safe type assertion.

This method also requires safe handling of type assertions to ensure robustness and prevent runtime errors.

-		keys = append(keys, key.(int))
+		intKey, ok := key.(int)
+		if !ok {
+		    return nil, fmt.Errorf("type assertion to int failed")
+		}
+	 keys = append(keys, intKey)

Committable suggestion was skipped due to low confidence.

Tools
GitHub Check: Lint (core)

[failure] 107-107:
type assertion must be checked (forcetypeassert)

Comment on lines 87 to 97
// Keys returns all keys in the map.
func (m *untypedMapMutexImpl) Keys() []interface{} {
// note that we don't lock here in case the map is already locked.
// the idea is that this function can be used for debugging-
// there may be read inconsistencies.
keys := make([]interface{}, 0, len(m.ma))
for k := range m.ma {
keys = append(keys, k)
}
return keys
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Implementation of Keys() in untypedMapMutexImpl lacks synchronization.

The implementation does not lock the mutex map when accessing it, which can lead to race conditions and inconsistent reads. This should be addressed to ensure thread safety.

+	m.ml.Lock()
+	defer m.ml.Unlock()
	keys := make([]interface{}, 0, len(m.ma))
	for k := range m.ma {
		keys = append(keys, k)
	}
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
// Keys returns all keys in the map.
func (m *untypedMapMutexImpl) Keys() []interface{} {
// note that we don't lock here in case the map is already locked.
// the idea is that this function can be used for debugging-
// there may be read inconsistencies.
keys := make([]interface{}, 0, len(m.ma))
for k := range m.ma {
keys = append(keys, k)
}
return keys
}
// Keys returns all keys in the map.
func (m *untypedMapMutexImpl) Keys() []interface{} {
// note that we don't lock here in case the map is already locked.
// the idea is that this function can be used for debugging-
// there may be read inconsistencies.
m.ml.Lock()
defer m.ml.Unlock()
keys := make([]interface{}, 0, len(m.ma))
for k := range m.ma {
keys = append(keys, k)
}
return keys
}

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

PR Summary

(updates since last review)

  • Enhanced state validation for quote requests by including previous status in UpdateQuoteRequestStatus calls
  • Modified UpdateQuoteRequestStatus call for ProvePosted to exclude previous status
  • Introduced logging in the relayer-db package for better tracking and debugging
  • Added methods to retrieve all keys from map mutexes for enhanced debugging
  • Added test cases for key retrieval functionality in various map mutex types

1 file(s) reviewed, no comment(s)

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

Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

Commits

Files that changed from the base of the PR and between cf1acb4 and 8c8b7c0.

Files selected for processing (1)
  • services/rfq/relayer/service/handlers.go (13 hunks)
Files skipped from review as they are similar to previous changes (1)
  • services/rfq/relayer/service/handlers.go

@@ -82,6 +84,18 @@ func (m *untypedMapMutexImpl) TryLock(key interface{}) (Unlocker, bool) {
return nil, false
}

// Keys returns all keys in the map.
func (m *untypedMapMutexImpl) Keys() []interface{} {
// note that we don't lock here in case the map is already locked.
Copy link
Contributor

Choose a reason for hiding this comment

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

@dwasse yeah this is just wrong imo.

This is definitely going to nil pointer- if it was only used for tests ifne but this method is unsafe b/c if could lead to iterating over a non-existent slice element

The lock here isn't global anyway and won't block anything else for long at all. The whole point of mapmutex is the Locks are not global even - the lock here is internal only

"sync"

"github.com/LK4d4/trylock"
Copy link
Contributor

@trajan0x trajan0x Jun 28, 2024

Choose a reason for hiding this comment

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

Think we should remove this dep actually?

See: LK4D4/trylock#3 seems like this functionality is built into sync.Mutex since 1.18

(Random aside: we're not using a canonical url for this either. canonical import url is github.com/LK4D4
image

and we use github.com/LK4d4 (notice the casing difference:

image

I was curious about this since this seemed like a bug in x/pkgsite, but apparentely this is intended behavior when packages existed pre-go.mod:

See golang/go#45409

Apparently, this was a huge issue with logrus when they renamed the package from sirupsen/logrus to Sirupsen/logrus (see sirupsen/logrus#384 followed by sirupsen/logrus#570)

Copy link
Contributor

Choose a reason for hiding this comment

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

okay, i've decided we should address this in a different pr (only bc this requires make tidy)

tracking in #2814

Copy link
Contributor

Choose a reason for hiding this comment

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

fixed in 0d573f2

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

Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 8c8b7c0 and 6928b16.

Files selected for processing (1)
  • core/mapmutex/mapmutex.go (3 hunks)
Files skipped from review as they are similar to previous changes (1)
  • core/mapmutex/mapmutex.go

@trajan0x trajan0x mentioned this pull request Jun 28, 2024
prevStatus = &req.Status
}
if !isValidStateTransition(*prevStatus, status) {
logger.Warnf("invalid state transition from %s to %s [txid=%s]", *prevStatus, status, hexutil.Encode(id[:]))
Copy link
Contributor

Choose a reason for hiding this comment

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

Completely understand the hesitation to do this, but in this case I'll be renaming the method to UpdateQuoteRequestStatusIFValid or somethign.

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

PR Summary

(updates since last review)

  • Updated .codeclimate.yml to exclude generated files from analysis
  • Added otelginmetrics directory to .golangci.yml skip list
  • Conditional Signoz client initialization in contrib/opbot/botmd/botmd.go
  • Introduced requiresSignoz method in contrib/opbot/botmd/commands.go
  • Added tracing and metrics middleware in contrib/opbot/botmd/middleware.go

178 file(s) reviewed, no comment(s)
Edit PR Review Bot Settings

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

PR Summary

(updates since last review)

  • Introduced Keys() method to core/mapmutex/mapmutex.go for key retrieval.
  • Added test cases for Keys() method in core/mapmutex/mapmutex_test.go.
  • Enhanced logging and validation for quote request status transitions in services/rfq/relayer/reldb/base/quote.go.
  • Updated UpdateQuoteRequestStatus calls in services/rfq/relayer/service/handlers.go to include additional status arguments.
  • Removed span parameter from handleNotEnoughInventory in services/rfq/relayer/service/handlers.go.

5 file(s) reviewed, no comment(s)
Edit PR Review Bot Settings

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

PR Summary

(updates since last review)

  • Enhanced validation for quote request status transitions in services/rfq/relayer/reldb/base/quote.go
  • Updated UpdateQuoteRequestStatus method to include additional status arguments in services/rfq/relayer/reldb/base/quote.go
  • Removed logging for invalid state transitions in services/rfq/relayer/reldb/base/quote.go

1 file(s) reviewed, no comment(s)
Edit PR Review Bot Settings

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

Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 6928b16 and 49bcf17.

Files selected for processing (4)
  • core/mapmutex/mapmutex_test.go (1 hunks)
  • core/mapmutex/stringer.go (5 hunks)
  • services/rfq/relayer/reldb/base/quote.go (3 hunks)
  • services/rfq/relayer/service/handlers.go (13 hunks)
Files skipped from review as they are similar to previous changes (2)
  • core/mapmutex/mapmutex_test.go
  • core/mapmutex/stringer.go
Additional context used
GitHub Check: codecov/patch
services/rfq/relayer/reldb/base/quote.go

[warning] 96-102: services/rfq/relayer/reldb/base/quote.go#L96-L102
Added lines #L96 - L102 were not covered by tests


[warning] 104-106: services/rfq/relayer/reldb/base/quote.go#L104-L106
Added lines #L104 - L106 were not covered by tests


[warning] 139-143: services/rfq/relayer/reldb/base/quote.go#L139-L143
Added lines #L139 - L143 were not covered by tests

services/rfq/relayer/service/handlers.go

[warning] 40-40: services/rfq/relayer/service/handlers.go#L40
Added line #L40 was not covered by tests


[warning] 145-145: services/rfq/relayer/service/handlers.go#L145
Added line #L145 was not covered by tests


[warning] 170-170: services/rfq/relayer/service/handlers.go#L170
Added line #L170 was not covered by tests


[warning] 182-182: services/rfq/relayer/service/handlers.go#L182
Added line #L182 was not covered by tests


[warning] 209-209: services/rfq/relayer/service/handlers.go#L209
Added line #L209 was not covered by tests


[warning] 273-273: services/rfq/relayer/service/handlers.go#L273
Added line #L273 was not covered by tests


[warning] 303-303: services/rfq/relayer/service/handlers.go#L303
Added line #L303 was not covered by tests


[warning] 335-335: services/rfq/relayer/service/handlers.go#L335
Added line #L335 was not covered by tests


[warning] 364-364: services/rfq/relayer/service/handlers.go#L364
Added line #L364 was not covered by tests


[warning] 378-378: services/rfq/relayer/service/handlers.go#L378
Added line #L378 was not covered by tests


[warning] 411-411: services/rfq/relayer/service/handlers.go#L411
Added line #L411 was not covered by tests


[warning] 446-446: services/rfq/relayer/service/handlers.go#L446
Added line #L446 was not covered by tests


[warning] 463-463: services/rfq/relayer/service/handlers.go#L463
Added line #L463 was not covered by tests

GitHub Check: Lint (services/rfq)
services/rfq/relayer/reldb/base/quote.go

[failure] 17-17:
logger is unused (deadcode)

Comment on lines +96 to +106
func (s Store) UpdateQuoteRequestStatus(ctx context.Context, id [32]byte, status reldb.QuoteRequestStatus, prevStatus *reldb.QuoteRequestStatus) error {
if prevStatus == nil {
req, err := s.GetQuoteRequestByID(ctx, id)
if err != nil {
return fmt.Errorf("could not get quote: %w", err)
}
prevStatus = &req.Status
}
if !isValidStateTransition(*prevStatus, status) {
return nil
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Validation logic in isValidStateTransition seems limited

The function checks if the new status is greater than the previous status or matches specific statuses. This might be too restrictive or not adequately capture valid transitions, depending on business rules. If more complex rules are needed, consider expanding this logic or using a state machine library.

Tools
GitHub Check: codecov/patch

[warning] 96-102: services/rfq/relayer/reldb/base/quote.go#L96-L102
Added lines #L96 - L102 were not covered by tests


[warning] 104-106: services/rfq/relayer/reldb/base/quote.go#L104-L106
Added lines #L104 - L106 were not covered by tests

Comment on lines +96 to +102
func (s Store) UpdateQuoteRequestStatus(ctx context.Context, id [32]byte, status reldb.QuoteRequestStatus, prevStatus *reldb.QuoteRequestStatus) error {
if prevStatus == nil {
req, err := s.GetQuoteRequestByID(ctx, id)
if err != nil {
return fmt.Errorf("could not get quote: %w", err)
}
prevStatus = &req.Status
Copy link
Contributor

Choose a reason for hiding this comment

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

Missing test coverage

The added lines for the UpdateQuoteRequestStatus function and the isValidStateTransition function are not covered by tests.

Do you want me to generate the unit testing code or open a GitHub issue to track this task?

Also applies to: 104-106, 139-143

Tools
GitHub Check: codecov/patch

[warning] 96-102: services/rfq/relayer/reldb/base/quote.go#L96-L102
Added lines #L96 - L102 were not covered by tests

Comment on lines +139 to +143
func isValidStateTransition(prevStatus, status reldb.QuoteRequestStatus) bool {
if status == reldb.DeadlineExceeded || status == reldb.WillNotProcess {
return true
}
return status >= prevStatus
Copy link
Contributor

Choose a reason for hiding this comment

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

Limited validation logic in isValidStateTransition

The function only checks if the new status is greater than the previous status or matches specific statuses. This might be too restrictive or not adequately capture valid transitions, depending on business rules. Consider expanding this logic or using a state machine library.

Tools
GitHub Check: codecov/patch

[warning] 139-143: services/rfq/relayer/reldb/base/quote.go#L139-L143
Added lines #L139 - L143 were not covered by tests


Missing test coverage

The isValidStateTransition function is not covered by tests.

Do you want me to generate the unit testing code or open a GitHub issue to track this task?

Tools
GitHub Check: codecov/patch

[warning] 139-143: services/rfq/relayer/reldb/base/quote.go#L139-L143
Added lines #L139 - L143 were not covered by tests

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/synapsecns/sanguine/services/rfq/relayer/reldb"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)

var logger = log.Logger("relayer-db")
Copy link
Contributor

Choose a reason for hiding this comment

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

Unused logger

The logger variable is declared but not used in the file.

Consider using the logger to log relevant information or remove the unused variable.

Tools
GitHub Check: Lint (services/rfq)

[failure] 17-17:
logger is unused (deadcode)

Comment on lines +104 to +106
if !isValidStateTransition(*prevStatus, status) {
return nil
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Review the logic for state transition validation and error handling

The method UpdateQuoteRequestStatus now includes logic to handle state transitions validation. While the use of prevStatus to fetch the current status if not provided is logical, the function returns nil when an invalid state transition is detected, which might silently ignore errors. Consider returning an error instead to make the failure explicit.

- return nil
+ return fmt.Errorf("invalid state transition from %s to %s [txid=%s]", *prevStatus, status, hexutil.Encode(id[:]))
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
if !isValidStateTransition(*prevStatus, status) {
return nil
}
if !isValidStateTransition(*prevStatus, status) {
return fmt.Errorf("invalid state transition from %s to %s [txid=%s]", *prevStatus, status, hexutil.Encode(id[:]))
}
Tools
GitHub Check: codecov/patch

[warning] 104-106: services/rfq/relayer/reldb/base/quote.go#L104-L106
Added lines #L104 - L106 were not covered by tests

@@ -361,7 +361,7 @@
return fmt.Errorf("could not submit transaction: %w", err)
}

err = q.db.UpdateQuoteRequestStatus(ctx, request.TransactionID, reldb.ProvePosting)
err = q.db.UpdateQuoteRequestStatus(ctx, request.TransactionID, reldb.ProvePosting, &request.Status)
Copy link
Contributor

Choose a reason for hiding this comment

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

Missing test coverage

The status update logic in handleRelayCompleted is not covered by tests.

Do you want me to generate the unit testing code or open a GitHub issue to track this task?

Tools
GitHub Check: codecov/patch

[warning] 364-364: services/rfq/relayer/service/handlers.go#L364
Added line #L364 was not covered by tests

@@ -375,7 +375,7 @@
func (r *Relayer) handleProofProvided(ctx context.Context, req *fastbridge.FastBridgeBridgeProofProvided) (err error) {
// TODO: this can still get re-orged
// ALso: we should make sure the previous status is ProvePosting
err = r.db.UpdateQuoteRequestStatus(ctx, req.TransactionId, reldb.ProvePosted)
err = r.db.UpdateQuoteRequestStatus(ctx, req.TransactionId, reldb.ProvePosted, nil)
Copy link
Contributor

Choose a reason for hiding this comment

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

Missing test coverage

The status update logic in handleProofProvided is not covered by tests.

Do you want me to generate the unit testing code or open a GitHub issue to track this task?

Tools
GitHub Check: codecov/patch

[warning] 378-378: services/rfq/relayer/service/handlers.go#L378
Added line #L378 was not covered by tests

@@ -408,7 +408,7 @@
}

if bs == fastbridge.RelayerClaimed.Int() {
err = q.db.UpdateQuoteRequestStatus(ctx, request.TransactionID, reldb.ClaimCompleted)
err = q.db.UpdateQuoteRequestStatus(ctx, request.TransactionID, reldb.ClaimCompleted, &request.Status)
Copy link
Contributor

Choose a reason for hiding this comment

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

Missing test coverage

The status update logic in handleProofPosted is not covered by tests.

Do you want me to generate the unit testing code or open a GitHub issue to track this task?

Tools
GitHub Check: codecov/patch

[warning] 411-411: services/rfq/relayer/service/handlers.go#L411
Added line #L411 was not covered by tests

@@ -443,7 +443,7 @@
return fmt.Errorf("could not submit transaction: %w", err)
}

err = q.db.UpdateQuoteRequestStatus(ctx, request.TransactionID, reldb.ClaimPending)
err = q.db.UpdateQuoteRequestStatus(ctx, request.TransactionID, reldb.ClaimPending, &request.Status)
Copy link
Contributor

Choose a reason for hiding this comment

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

Missing test coverage

The status update logic in handleProofPosted is not covered by tests.

Do you want me to generate the unit testing code or open a GitHub issue to track this task?

Tools
GitHub Check: codecov/patch

[warning] 446-446: services/rfq/relayer/service/handlers.go#L446
Added line #L446 was not covered by tests

@@ -460,7 +460,7 @@
}
// if committableBalance > destAmount
if committableBalance.Cmp(request.Transaction.DestAmount) > 0 {
err = q.db.UpdateQuoteRequestStatus(ctx, request.TransactionID, reldb.CommittedPending)
err = q.db.UpdateQuoteRequestStatus(ctx, request.TransactionID, reldb.CommittedPending, &request.Status)
Copy link
Contributor

Choose a reason for hiding this comment

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

Missing test coverage

The status update logic in handleNotEnoughInventory is not covered by tests.

Do you want me to generate the unit testing code or open a GitHub issue to track this task?

Tools
GitHub Check: codecov/patch

[warning] 463-463: services/rfq/relayer/service/handlers.go#L463
Added line #L463 was not covered by tests

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

Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 49bcf17 and f0bc3cb.

Files selected for processing (1)
  • services/rfq/relayer/reldb/base/quote.go (2 hunks)
Files skipped from review as they are similar to previous changes (1)
  • services/rfq/relayer/reldb/base/quote.go

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

PR Summary

(updates since last review)

  • Removed anon.to URL redirection and added slacker.WithUnfurlLinks(false) in contrib/opbot/botmd/commands.go
  • Updated contrib/opbot/go.mod to use a forked slacker package
  • Added Blacklist field to Config struct in contrib/screener-api/config/config.go
  • Renamed blacklistCache to blacklist in contrib/screener-api/screener/screener.go
  • Enhanced signal handling and context management in core/commandline/shell.go

25 file(s) reviewed, no comment(s)
Edit PR Review Bot Settings

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

Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

Commits

Files that changed from the base of the PR and between f0bc3cb and b140cb2.

Files selected for processing (1)
  • core/mapmutex/mapmutex.go (2 hunks)
Files skipped from review as they are similar to previous changes (1)
  • core/mapmutex/mapmutex.go

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

PR Summary

(updates since last review)

  • Removed github.com/LK4d4/trylock dependency from multiple go.mod files
  • Replaced trylock.Mutex with sync.Mutex in /core/mapmutex/mapmutex.go
  • Added Keys method to untypedMapMutex interface in /core/mapmutex/mapmutex.go
  • Enhanced quote request status updates with validation and logging
  • Added test cases for key retrieval functionality in map mutex types

12 file(s) reviewed, no comment(s)
Edit PR Review Bot Settings

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 size/s
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants