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

(OraklNode) Refresh fetcher when global aggregate and local aggregate price differ by more than 30% #2242

Closed
wants to merge 8 commits into from

Conversation

nick-bisonai
Copy link
Collaborator

@nick-bisonai nick-bisonai commented Aug 27, 2024

Description

It'll auto restart fetcher if difference over 30% between local aggregate and global aggregate is detected
The problem with this approach is, that it will restart fetchers from properly working nodes too.

better approach might be comparing with given local aggregate values from other nodes. yet there aren't enough nodes atm to check if current node's value is majority or not

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

Checklist before requesting a review

  • I have performed a self-review of my code.
  • If it is a core feature, I have added thorough tests.

Deployment

  • Should publish npm package
  • Should publish Docker image

Copy link
Contributor

coderabbitai bot commented Aug 27, 2024

Warning

Rate limit exceeded

@nick-bisonai has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 1 minutes and 34 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

Files that changed from the base of the PR and between c66f079 and 1a5d6b3.

Walkthrough

Walkthrough

The changes encompass significant modifications to the Aggregator and related components, enhancing their functionality and thread safety. Key updates include the introduction of a message bus parameter in various functions, improvements in thread safety during message handling, and the implementation of a cooldown mechanism for refresh operations. Additionally, new error variables and adjustments to test cases reflect the broader integration of these features across the codebase.

Changes

Files Change Summary
node/pkg/aggregator/aggregator.go, .../aggregator_test.go, .../app.go, .../globalaggregatebulkwriter_test.go, .../types.go Added a message bus parameter to NewAggregator and modified related methods and tests to enhance communication and functionality. Updated aggregator struct fields.
node/pkg/error/sentinel.go Introduced new error variables for better error handling in the Aggregator and Fetcher services.
node/pkg/fetcher/app.go, .../app_test.go, .../localaggregatebulkwriter_test.go, .../main_test.go, .../types.go, .../utils_test.go Added a cooldown mechanism for refresh operations, including a new LastRefreshTime field and a RefreshCooldownInterval constant. Modified tests to validate new logic.

Sequence Diagram(s)

sequenceDiagram
    participant App
    participant MessageBus
    participant Aggregator
    participant Fetcher

    App->>MessageBus: Publish Refresh Request
    MessageBus->>Aggregator: Handle Refresh
    Aggregator->>Aggregator: Check LastRefreshTime
    Aggregator-->>MessageBus: Refresh on Cooldown (if applicable)
    Aggregator-->>MessageBus: Process Refresh (if allowed)
    MessageBus->>Fetcher: Trigger Fetch
Loading

🐰 Hopping through code with glee,
New features added, can't you see?
Message bus and cooldowns in place,
Our aggregators now set the pace!
With tests updated, all's in tune,
Let's celebrate, beneath the moon! 🌙✨


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

@nick-bisonai nick-bisonai changed the title Refresh fetcher when global aggregate and local aggregate price differ by 30% Refresh fetcher when global aggregate and local aggregate price differ by more than 30% Aug 27, 2024
Base automatically changed from feat/restart-fetcher to master August 28, 2024 02:12
@nick-bisonai nick-bisonai force-pushed the feat/fetcher-refresh-logic branch from c9ab262 to 2f121d9 Compare August 28, 2024 02:17
@nick-bisonai nick-bisonai marked this pull request as ready for review August 28, 2024 03:45
@nick-bisonai nick-bisonai requested a review from a team as a code owner August 28, 2024 03:45
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 UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between deae0ca and 88670ff.

Files selected for processing (12)
  • node/pkg/aggregator/aggregator.go (6 hunks)
  • node/pkg/aggregator/aggregator_test.go (4 hunks)
  • node/pkg/aggregator/app.go (1 hunks)
  • node/pkg/aggregator/globalaggregatebulkwriter_test.go (1 hunks)
  • node/pkg/aggregator/types.go (2 hunks)
  • node/pkg/error/sentinel.go (2 hunks)
  • node/pkg/fetcher/app.go (3 hunks)
  • node/pkg/fetcher/app_test.go (2 hunks)
  • node/pkg/fetcher/localaggregatebulkwriter_test.go (1 hunks)
  • node/pkg/fetcher/main_test.go (1 hunks)
  • node/pkg/fetcher/types.go (2 hunks)
  • node/pkg/fetcher/utils_test.go (1 hunks)
Additional comments not posted (27)
node/pkg/fetcher/localaggregatebulkwriter_test.go (4)

24-24: LGTM!

Running the application in a goroutine is a good approach to allow concurrent execution.

The code changes are approved.


26-26: LGTM!

The sleep period ensures that the bulk writer has enough time to process data before assertions are made.

The code changes are approved.


28-31: LGTM!

The database query and error handling are correctly implemented.

The code changes are approved.


32-32: LGTM!

The assertion ensures that data is being produced and stored correctly in the database.

The code changes are approved.

node/pkg/fetcher/utils_test.go (1)

120-120: LGTM!

The initialization step ensures that the application state is correctly configured before any assertions or further actions are taken.

The code changes are approved.

node/pkg/aggregator/globalaggregatebulkwriter_test.go (1)

89-89: LGTM!

The additional parameter likely represents a messaging bus or similar component, enhancing the functionality of the NewAggregator function.

The code changes are approved.

node/pkg/fetcher/types.go (2)

28-28: LGTM!

The RefreshCooldownInterval constant is correctly defined.

The code change is approved.


95-95: LGTM! But verify the initialization and usage of LastRefreshTime.

The LastRefreshTime field is correctly defined. Ensure that this field is properly initialized and updated in the codebase.

The code change is approved.

Run the following script to verify the initialization and usage of LastRefreshTime:

Verification successful

The LastRefreshTime field is properly initialized and used.

The field is initialized with time.Time{}, checked for zero value, and updated with time.Now(). This indicates correct usage in managing time-based logic.

  • Initialization: node/pkg/fetcher/app.go
  • Usage: node/pkg/fetcher/app.go
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the initialization and usage of `LastRefreshTime`.

# Test: Search for the initialization and usage of `LastRefreshTime`. Expect: Proper initialization and updates.
rg --type go 'LastRefreshTime'

Length of output: 327

node/pkg/aggregator/aggregator_test.go (5)

33-33: LGTM!

The NewAggregator function call is correctly updated to include nil for the Bus parameter.

The code change is approved.


26-26: LGTM! But verify the initialization of Bus in the test setup.

The NewAggregator function call is correctly updated to include testItems.app.Bus. Ensure that the Bus parameter is properly initialized in the test setup.

The code change is approved.

Run the following script to verify the initialization of Bus in the test setup:

Verification successful

Verification Successful: Bus Initialization in Test Setup

The Bus parameter is properly initialized in the test setup, ensuring its correct usage in the NewAggregator function call. No issues found with the initialization.

  • Initialization observed in node/pkg/fetcher/main_test.go and node/pkg/aggregator/main_test.go.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the initialization of `Bus` in the test setup.

# Test: Search for the initialization of `Bus` in the test setup. Expect: Proper initialization.
rg --type go 'Bus' -A 5

Length of output: 22908


49-49: LGTM! But verify the initialization of Bus in the test setup.

The NewAggregator function call is correctly updated to include testItems.app.Bus. Ensure that the Bus parameter is properly initialized in the test setup.

The code change is approved.

Run the following script to verify the initialization of Bus in the test setup:

Verification successful

Verification Successful: Bus Initialization in Test Setup Confirmed

The Bus parameter is properly initialized in the test setup for the NewAggregator function call. The initialization is consistent across the test files, ensuring correct setup for the tests.

  • node/pkg/aggregator/aggregator_test.go: Bus is passed as testItems.app.Bus.
  • node/pkg/aggregator/main_test.go: Bus initialized as testItems.messageBus = mb.
  • node/pkg/admin/tests/main_test.go: Similar initialization pattern observed.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the initialization of `Bus` in the test setup.

# Test: Search for the initialization of `Bus` in the test setup. Expect: Proper initialization.
rg --type go 'Bus' -A 5

Length of output: 22908


73-73: LGTM! But verify the initialization of Bus in the test setup.

The NewAggregator function call is correctly updated to include testItems.app.Bus. Ensure that the Bus parameter is properly initialized in the test setup.

The code change is approved.

Run the following script to verify the initialization of Bus in the test setup:

Verification successful

Bus Initialization Verified in Test Setup

The Bus parameter is properly initialized in the test setup for the NewAggregator function call. The messageBus is correctly assigned and used within the test structure. No further action is required.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the initialization of `Bus` in the test setup.

# Test: Search for the initialization of `Bus` in the test setup. Expect: Proper initialization.
rg --type go 'Bus' -A 5

Length of output: 22908


101-101: LGTM! But verify the initialization of Bus in the test setup.

The NewAggregator function call is correctly updated to include testItems.app.Bus. Ensure that the Bus parameter is properly initialized in the test setup.

The code change is approved.

Run the following script to verify the initialization of Bus in the test setup:

Verification successful

Bus Initialization Verified in Test Setup

The Bus parameter is properly initialized in the test setup, as confirmed by its presence and assignment in the test files. The NewAggregator function call correctly includes testItems.app.Bus. No further action is required.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the initialization of `Bus` in the test setup.

# Test: Search for the initialization of `Bus` in the test setup. Expect: Proper initialization.
rg --type go 'Bus' -A 5

Length of output: 22908

node/pkg/aggregator/types.go (2)

189-194: LGTM! But verify the initialization and usage of roundLocalAggregate.

The fields roundTriggers, roundPrices, roundPriceFixes, and roundProofs have been replaced with roundLocalAggregate. Ensure that the new field is properly initialized and used in the codebase.

The code change is approved.

Run the following script to verify the initialization and usage of roundLocalAggregate:

Verification successful

Initialization and Usage of roundLocalAggregate Verified

The roundLocalAggregate field is properly initialized and used in the codebase. It is initialized as an empty map and is used to store, access, and delete round aggregates based on round IDs.

  • Initialization: roundLocalAggregate is initialized as an empty map in aggregator.go.
  • Usage: It is updated, accessed, and deleted appropriately in aggregator.go.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the initialization and usage of `roundLocalAggregate`.

# Test: Search for the initialization and usage of `roundLocalAggregate`. Expect: Proper initialization and updates.
rg --type go 'roundLocalAggregate'

Length of output: 482


203-204: LGTM! But verify the initialization and usage of bus.

The bus field is correctly defined. Ensure that this field is properly initialized and used in the codebase.

The code change is approved.

Run the following script to verify the initialization and usage of bus:

Verification successful

Initialization and Usage of bus Verified

The bus field in the Aggregator struct is properly initialized and actively used in the codebase. The initialization occurs in the New function, and the field is utilized in various message handling functions, confirming its intended functionality.

  • Initialization: node/pkg/aggregator/app.go in the New function.
  • Usage: Various message handling functions in node/pkg/aggregator/app.go and node/pkg/aggregator/aggregator.go.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the initialization and usage of `bus`.

# Test: Search for the initialization and usage of `bus`. Expect: Proper initialization and updates.
rg --type go 'bus'

Length of output: 16646

node/pkg/fetcher/app_test.go (2)

118-169: LGTM!

The test function TestAppRefresh is correctly implemented and verifies the refresh mechanism of the application.

The code changes are approved.


171-241: LGTM!

The test function TestAppRefreshCooldown is correctly implemented and verifies the cooldown mechanism of the refresh operation.

The code changes are approved.

node/pkg/fetcher/main_test.go (1)

265-267: LGTM!

The refactoring of the cleanup function to call testItems.app.stopAll(ctx) instead of testItems.app.stopAllFetchers(ctx) is appropriate and consolidates functionality under a more general method.

The code changes are approved.

node/pkg/aggregator/app.go (1)

130-132: LGTM!

The modification to include a.Bus in the NewAggregator call enhances the functionality of the aggregator initialization process by allowing interaction with a message bus.

The code changes are approved.

node/pkg/fetcher/app.go (2)

28-28: LGTM!

The LastRefreshTime field is correctly added and initialized.

The code changes are approved.


97-101: LGTM!

The cooldown mechanism is correctly implemented to prevent frequent refresh operations.

The code changes are approved.

node/pkg/aggregator/aggregator.go (4)

7-10: LGTM!

The new imports are necessary for the added functionality.

The code changes are approved.


20-28: LGTM!

The NewAggregator function signature and the Aggregator struct are correctly updated to include the message bus parameter and field.

The code changes are approved.

Also applies to: 65-66


117-118: LGTM!

The refined locking mechanism ensures thread safety.

The code changes are approved.


296-322: LGTM!

The new logic enhances the robustness of the aggregator by ensuring it can respond to inconsistencies in aggregate values effectively.

The code changes are approved.

node/pkg/error/sentinel.go (2)

95-95: LGTM!

The new error variable provides a specific error message for scenarios where there is a mismatch between global and local prices.

The code changes are approved.


160-160: LGTM!

The new error variable improves the robustness of the Fetcher service's error reporting by handling cases where a data refresh attempt fails due to a cooldown period not being completed.

The code changes are approved.

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

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 88670ff and c66f079.

Files selected for processing (1)
  • node/pkg/aggregator/aggregator.go (6 hunks)
Additional comments not posted (2)
node/pkg/aggregator/aggregator.go (2)

117-118: LGTM!

The changes enhance thread safety by holding the lock for the entire method execution.

The code changes are approved.


Line range hint 319-334: LGTM!

The function is correctly implemented.

The code changes are approved.

node/pkg/aggregator/aggregator.go Show resolved Hide resolved
node/pkg/aggregator/aggregator.go Outdated Show resolved Hide resolved
@@ -102,16 +114,14 @@ func (n *Aggregator) HandleTriggerMessage(ctx context.Context, msg raft.Message)
return err
}
defer n.leaveOnlyLast10Entries(triggerMessage.RoundID)

n.mu.Lock()
defer n.mu.Unlock()
Copy link
Contributor

Choose a reason for hiding this comment

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

there are two locks in this function both of which are released when function returns. I wonder if it'd be same result having a single lock 🤔

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

the scope which n.mu.Lock() and n.roundTriggers.mu.Lock() are having are different so it probably shouldn't have the same result 😅

to be more precise, it might be better to have separate mutex for roundLocalAggregate value

Copy link
Contributor

Choose a reason for hiding this comment

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

i thought n.mu.Lock() can do the job of n.roundTriggers.mu.Lock() but seems like it's worth keeping both since it introduces more clarity to the logic?

@nick-bisonai
Copy link
Collaborator Author

I'll keep this open for a while, I'm not sure if this approach is a good idea yet

@@ -142,6 +152,7 @@ func (n *Aggregator) HandleTriggerMessage(ctx context.Context, msg raft.Message)
// if not enough messages collected from HandleSyncReplyMessage, it will hang in certain round
value = -1
} else {
n.roundLocalAggregate[triggerMessage.RoundID] = localAggregate.Value
value = localAggregate.Value
Copy link
Contributor

Choose a reason for hiding this comment

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

n.roundLocalAggregate[triggerMessage.RoundID] = value

@Intizar-T
Copy link
Contributor

I'll keep this open for a while, I'm not sure if this approach is a good idea yet

Agreed. This is quite a bit of automation, might easily spiral out of control.

@nick-bisonai nick-bisonai changed the title Refresh fetcher when global aggregate and local aggregate price differ by more than 30% (OraklNode) Refresh fetcher when global aggregate and local aggregate price differ by more than 30% Aug 28, 2024
@nick-bisonai nick-bisonai self-assigned this Aug 28, 2024
@nick-bisonai
Copy link
Collaborator Author

will close this pr since this kind of situation are rarely happening, and even if it occurs, always temporary

@nick-bisonai nick-bisonai deleted the feat/fetcher-refresh-logic branch November 13, 2024 15:12
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.

(OraklNode) Reconnect websocket if price difference between local aggregate and global aggregate occurs
2 participants