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

[IND-499]: Add AggregateTradingRewardsProcessedCache with roundtable task #927

Merged
merged 7 commits into from
Jan 5, 2024

Conversation

Christopher-Li
Copy link
Contributor

Changelist

  • Add AggregateTradingRewardsProcessedCache cache
  • Set and pull from AggregateTradingRewardsProcessedCache in AggregateTradingRewardsTask
  • Generate interval in AggregateTradingRewardsTask

Test Plan

Extensive unit tests

Author/Reviewer Checklist

  • If this PR has changes that result in a different app state given the same prior state and transaction list, manually add the state-breaking label.
  • If the PR has breaking postgres changes to the indexer add the indexer-postgres-breaking label.
  • If this PR isn't state-breaking but has changes that modify behavior in PrepareProposal or ProcessProposal, manually add the label proposal-breaking.
  • If this PR is one of many that implement a specific feature, manually label them all feature:[feature-name].
  • If you wish to for mergify-bot to automatically create a PR to backport your change to a release branch, manually add the label backport/[branch-name].
  • Manually add any of the following labels: refactor, chore, bug.

Copy link

linear bot commented Jan 4, 2024

Copy link
Contributor

coderabbitai bot commented Jan 4, 2024

Walkthrough

The codebase has undergone a set of updates to enhance its date handling and trading reward aggregation features. A new constant for representing a day in milliseconds was added, and utility functions for date rounding were introduced. The Postgres module now includes improved functionality for managing trading reward data, with new methods for retrieval and deletion based on specific criteria. Redis caching capabilities were expanded to handle aggregate trading rewards. Furthermore, the Roundtable service received configuration options for different aggregation intervals and updated task logic for trading reward aggregation.

Changes

File Path Change Summary
indexer/packages/base/src/constants.ts, indexer/packages/base/src/date-helpers.ts, indexer/packages/base/src/index.ts Added a constant for one day in milliseconds and exported new date helper functions.
indexer/packages/postgres/__tests__/helpers/mock-generators.ts, indexer/packages/postgres/__tests__/stores/wallet-table.test.ts Imported WalletTable and modified the default wallet data in tests.
indexer/packages/postgres/__tests__/stores/trading-reward-aggregation-table.test.ts, indexer/packages/postgres/src/stores/trading-reward-aggregation-table.ts, indexer/packages/postgres/src/models/trading-reward-aggregation-model.ts, indexer/packages/postgres/src/types/query-types.ts Enhanced trading reward aggregation with new functions, tests, and updated logic for the endedAt property from inclusive to exclusive.
indexer/packages/redis/__tests__/caches/aggregate-trading-rewards-processed-cache.test.ts, indexer/packages/redis/src/caches/aggregate-trading-rewards-processed-cache.ts, indexer/packages/redis/src/index.ts Implemented and tested new Redis cache functionalities for trading rewards processing times.
indexer/services/roundtable/__tests__/tasks/aggregate-trading-rewards.test.ts, indexer/services/roundtable/src/config.ts, indexer/services/roundtable/src/index.ts, indexer/services/roundtable/src/lib/constants.ts, indexer/services/roundtable/src/tasks/aggregate-trading-rewards.ts Added new tests, configurations, and constants for aggregate trading rewards, and refactored the task logic for different aggregation periods.

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's AI:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit-tests for this file.
  • 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 tests 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 from git and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit tests.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid.
    • @coderabbitai read the files in the src/scheduler package and generate README in the markdown format.

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 a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @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.
  • The JSON schema for the configuration file is available here.
  • 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/coderabbit-overrides.v2.json

CodeRabbit Discord Community

Join our Discord Community to get help, request features, and share feedback.

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.

Review Status

Actionable comments generated: 1

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between d2ec340 and b53dfd0.
Files selected for processing (15)
  • indexer/packages/base/src/constants.ts (1 hunks)
  • indexer/packages/base/src/date-helpers.ts (1 hunks)
  • indexer/packages/base/src/index.ts (1 hunks)
  • indexer/packages/postgres/tests/helpers/mock-generators.ts (3 hunks)
  • indexer/packages/postgres/tests/stores/trading-reward-aggregation-table.test.ts (3 hunks)
  • indexer/packages/postgres/src/stores/trading-reward-aggregation-table.ts (3 hunks)
  • indexer/packages/postgres/src/types/query-types.ts (2 hunks)
  • indexer/packages/redis/tests/caches/aggregate-trading-rewards-processed-cache.test.ts (1 hunks)
  • indexer/packages/redis/src/caches/aggregate-trading-rewards-processed-cache.ts (1 hunks)
  • indexer/packages/redis/src/index.ts (1 hunks)
  • indexer/services/roundtable/tests/tasks/aggregate-trading-rewards.test.ts (2 hunks)
  • indexer/services/roundtable/src/config.ts (2 hunks)
  • indexer/services/roundtable/src/index.ts (2 hunks)
  • indexer/services/roundtable/src/lib/constants.ts (2 hunks)
  • indexer/services/roundtable/src/tasks/aggregate-trading-rewards.ts (1 hunks)
Files skipped from review due to trivial changes (1)
  • indexer/packages/base/src/index.ts
Additional comments: 34
indexer/services/roundtable/src/lib/constants.ts (2)
  • 2-2: The import of DateTimeOptions from 'luxon' is correct and follows standard import conventions in TypeScript.

  • 14-14: The declaration of UTC_OPTIONS is correct and follows TypeScript's conventions for declaring constants. It's also good practice to define such constants for date-time options to ensure consistency across the application.

indexer/packages/base/src/date-helpers.ts (2)
  • 5-10: The floorDate function correctly calculates the floor of the given date to the nearest interval specified by timeInMilliseconds. The logic uses Math.floor which is the appropriate choice for this operation.

  • 17-22: The ceilingDate function correctly calculates the ceiling of the given date to the nearest interval specified by timeInMilliseconds. The logic uses Math.ceil which is the appropriate choice for this operation.

indexer/packages/redis/src/caches/aggregate-trading-rewards-processed-cache.ts (3)
  • 8-10: The getKey function correctly constructs the Redis key using the AGGREGATE_TRADING_REWARDS_PROCESSED_CACHE_KEY prefix and the given period. This ensures that keys are unique per period.

  • 12-16: The getProcessedTime function correctly retrieves the processed time from Redis. It uses the getAsync helper, which is expected to be a promisified version of Redis's get command.

  • 19-24: The setProcessedTime function correctly sets the processed time in Redis. The use of await ensures that the operation completes before the function resolves, which is important for ensuring data consistency.

indexer/packages/base/src/constants.ts (1)
  • 15-15: The addition of ONE_DAY_IN_MILLISECONDS is correct and follows the established pattern of defining time-related constants in milliseconds. This constant will be useful for any operations that need to represent a day in terms of milliseconds.
indexer/packages/redis/src/index.ts (1)
  • 3-3: The export of AggregateTradingRewardsProcessedCache is correct and follows the established pattern of exporting modules in TypeScript. This will make the cache available for import in other parts of the application.
indexer/packages/redis/__tests__/caches/aggregate-trading-rewards-processed-cache.test.ts (1)
  • 9-37: The test case 'successfully sets and gets aggregate trading rewards processed' is well-structured. It checks for the absence of a value before setting it and then confirms that the value can be retrieved correctly. This is a good practice for testing cache operations.
indexer/packages/postgres/__tests__/helpers/mock-generators.ts (2)
  • 8-8: The import of WalletTable is correct and follows the established pattern of importing modules in TypeScript. This will allow the use of WalletTable for creating mock wallet data in tests.

  • 67-67: The addition of defaultWallet to the seedData function is correct. It ensures that the wallet data is available for tests that depend on it, which is important for setting up a consistent test environment.

indexer/services/roundtable/src/index.ts (1)
  • 126-147: The conditional checks for LOOPS_ENABLED_AGGREGATE_TRADING_REWARDS_DAILY, LOOPS_ENABLED_AGGREGATE_TRADING_REWARDS_WEEKLY, and LOOPS_ENABLED_AGGREGATE_TRADING_REWARDS_MONTHLY are correct. They follow the established pattern for starting loops based on configuration flags. The use of TradingRewardAggregationPeriod enum values as arguments to aggregateTradingRewardsTasks is also correct, ensuring that the tasks are started with the appropriate period.
indexer/packages/postgres/src/stores/trading-reward-aggregation-table.ts (2)
  • 95-108: The getLatestAggregatedTradeReward function is correctly implemented to retrieve the latest aggregated trade reward for a given period. The use of orderBy with Ordering.DESC and first() ensures that the most recent record is returned.

  • 156-177: The deleteAll function is correctly implemented to delete aggregated trade rewards based on the period and starting height. The use of a conditional query builder pattern allows for flexible query construction based on the provided parameters.

indexer/services/roundtable/src/config.ts (2)
  • 45-47: The addition of configuration options for enabling aggregate trading rewards on different intervals (daily, weekly, monthly) is correct. The default values are set to true, which is a reasonable default for feature flags.

  • 80-87: The loop interval configurations for the aggregate trading rewards have been correctly added and follow the established pattern for loop timing configurations. The default values are consistent with other loop intervals in the system.

indexer/packages/postgres/__tests__/stores/trading-reward-aggregation-table.test.ts (3)
  • 1-11: The addition of new imports for TradingRewardAggregationPeriod, createdDateTime, and BlockTable indicates that the test cases will be using these entities. Ensure that the new test cases are using these imports correctly and that they are necessary for the test logic.

  • 63-94: The test case for finding the latest monthly TradingRewardAggregation seems to correctly create blocks and trading reward aggregations before attempting to retrieve the latest one. It's important to ensure that the TradingRewardAggregationTable.getLatestAggregatedTradeReward method is designed to return the correct record based on the period parameter.

  • 139-177: The test case for deleting trading reward aggregations after a certain height correctly sets up the necessary data and then uses the deleteAll method with the startedAtHeightOrAfter parameter. It's crucial to verify that the deleteAll method is implemented to handle this parameter correctly and that the test asserts the expected state of the database after the deletion.

indexer/packages/postgres/src/types/query-types.ts (2)
  • 75-79: The addition of STARTED_AT_HEIGHT_OR_AFTER to the QueryableField enum is consistent with the changes in the test file that uses this field. Ensure that this new field is supported in the query logic where TradingRewardAggregationQueryConfig is used.

  • 280-285: The TradingRewardAggregationQueryConfig interface has been updated to include the new STARTED_AT_HEIGHT_OR_AFTER field. This change should be cross-checked with the implementation of the query logic to ensure that it correctly interprets and uses this new field.

indexer/services/roundtable/__tests__/tasks/aggregate-trading-rewards.test.ts (12)
  • 2-15: The new imports and constants are introduced to support the new caching mechanism and interval generation. Ensure that these imports are used within the file and that the constants are correctly implemented in the tests.

  • 39-57: The constants for date and time calculations are correctly using the luxon library to ensure UTC time is used. This is important for consistency in time-based calculations across different time zones.

  • 59-79: The test case for getTradingRewardDataToProcessInterval correctly checks for undefined return when no blocks are in the database. The use of logger.info to log this condition is also appropriate.

  • 81-102: The test case for getTradingRewardDataToProcessInterval when the cache is empty and no aggregations are present correctly asserts the interval based on the first block time. This ensures that the interval calculation logic is working as expected.

  • 104-134: The test case for deleting incomplete aggregations when the cache is empty is important to ensure that the system can recover from an inconsistent state. The assertions for the interval and the remaining aggregations are correctly checking the expected outcomes.

  • 138-163: The test case for handling multiple incomplete aggregations when the cache is empty is similar to the previous one but with more data. It's good to see that the test is comprehensive and covers different scenarios.

  • 166-196: The test case for handling intervals when the cache is populated but not enough blocks have been processed is crucial for ensuring that the system correctly identifies the next interval to process. The assertions are well-placed to check the expected behavior.

  • 199-229: The test case for handling intervals when the cache is populated and there are unprocessed blocks beyond a certain time threshold is another important scenario. The test ensures that the system can correctly calculate the next interval to process.

  • 233-262: The test case for handling intervals when there is a significant amount of unprocessed blocks is testing the system's ability to handle larger intervals. This is a good stress test for the interval calculation logic.

  • 266-298: The test case for handling intervals when the cache is populated close to the end of the day is testing edge cases around day boundaries. This is important for ensuring that the system behaves correctly around these critical times.

  • 302-312: The test case for runTask when there are no blocks in the database is ensuring that the task exits gracefully. The use of logger.info to log this condition is appropriate and should aid in debugging if needed.

  • 316-321: The helper function createBlockWithTime is a good addition to the test suite, allowing for the creation of blocks with specific times for testing interval calculations. Ensure that this function is used correctly in the test cases.

Comment on lines 1 to 235
TradingRewardAggregationFromDatabase | undefined = await
TradingRewardAggregationTable.getLatestAggregatedTradeReward(this.period);

if (latestAggregation !== undefined && latestAggregation.endedAt === null) {
await TradingRewardAggregationTable.deleteAll({
period: this.period,
startedAtHeightOrAfter: latestAggregation.startedAtHeight,
});
logger.info({
at: 'aggregate-trading-rewards#deleteIncompleteAggregatedTradingReward',
message: `Deleted the last ${this.period} aggregated trading rewards`,
height: latestAggregation.startedAtHeight,
time: latestAggregation.startedAt,
});
}
}

/**
* The start time of the next interval to process. This will be the start time of the
* first block in the database, or the start time of the next month after the latest
* monthly aggregation.
*/
private async getNextIntervalStart(): Promise<DateTime> {
const latestAggregation:
TradingRewardAggregationFromDatabase | undefined = await
TradingRewardAggregationTable.getLatestAggregatedTradeReward(this.period);
// Since we've deleted the incomplete aggregations, we can assume that the latestAggregation
// is complete.
if (latestAggregation !== undefined) {
return DateTime.fromISO(latestAggregation.endedAt!, UTC_OPTIONS);
}

// Since we were able to find the latest block, we assume we can find the first block
const firstBlock: BlockFromDatabase[] = await BlockTable.findAll({
blockHeight: ['1'],
limit: 1,
}, []);
return DateTime.fromISO(firstBlock[0].time, UTC_OPTIONS);
}

/**
* Generate the interval that will be processed. The end time of the interval is calculated from
* a start time and the latest block. This will be the earliest of the following:
* 1. The next day
* 2. An hour after start time
* 3. The start of the minute of the latest block
* @param startTime - startTime of the interval
* @param latestBlock
* @returns
*/
private generateInterval(
startTime: DateTime,
latestBlock: BlockFromDatabase,
): Interval {
const latestBlockTime: Date = DateTime.fromISO(latestBlock.time, UTC_OPTIONS).toJSDate();

// The most recent start of a minute. i.e 12:02:33 will be rounded to 12:02:00
const normalizedLatestBlockTime: Date = floorDate(
latestBlockTime,
ONE_MINUTE_IN_MILLISECONDS,
);

const nextDay: Date = startTime.plus({ days: 1 }).toJSDate();
const normalizedNextDay: Date = floorDate(nextDay, ONE_DAY_IN_MILLISECONDS);

const startDate: Date = startTime.toJSDate();
const oneHourAfterStart: Date = DateTime.fromJSDate(startDate).plus({ hour: 1 }).toJSDate();
const endTime: Date = new Date(Math.min(
normalizedLatestBlockTime.getTime(),
normalizedNextDay.getTime(),
oneHourAfterStart.getTime(),
));
const endDateTime: DateTime = DateTime.fromJSDate(endTime).toUTC();
return Interval.fromDateTimes(startTime, endDateTime);
}

private async getTradingRewardDataToProcess(
_interval: Interval,
): Promise<TradingRewardFromDatabase[]> {
// TODO: Implement
return Promise.resolve([]);
}

private sortTradingRewardData(
_tradingRewardData: TradingRewardFromDatabase[],
): SortedTradingRewardData {
// TODO: Implement
return {};
}

async function updateTradingRewardsAggregation(
_sortedTradingRewardData: SortedTradingRewardData,
): Promise<void> {
// TODO: Implement
private async updateTradingRewardsAggregation(
_sortedTradingRewardData: SortedTradingRewardData,
): Promise<void> {
// TODO: Implement
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The new AggregateTradingReward class and generateTaskFromPeriod function have been added to the aggregate-trading-rewards.ts file. It's important to ensure that the class methods are correctly implemented and that the generateTaskFromPeriod function correctly instantiates and uses the AggregateTradingReward class. Additionally, the TODO comments within the class methods indicate that the implementation is not yet complete, which should be addressed before merging.

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.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between b53dfd0 and 3fabcd3.
Files selected for processing (1)
  • indexer/packages/postgres/tests/stores/wallet-table.test.ts (3 hunks)
Additional comments: 6
indexer/packages/postgres/__tests__/stores/wallet-table.test.ts (6)
  • 3-3: Renaming defaultWallet to defaultWallet2 may indicate the use of multiple wallet constants for testing. Verify that defaultWallet2 is correctly defined and used consistently throughout the test cases.

  • 20-20: Ensure that the create method is intended to be called with defaultWallet2 and that this change is consistent with the test's purpose.

  • 24-35: The upsert method is called twice with defaultWallet2. Confirm that the test logic correctly reflects the intention of upserting the same wallet data multiple times and that the assertions are valid.

Verification successful

To verify the structure of defaultWallet2 and the behavior of the upsert method, I will generate a script to extract the definition of defaultWallet2 and the upsert method from the wallet-table.test.ts file.


I will generate a new script to extract the full definition of the upsert method and to find the definition of defaultWallet2 in the wallet-table.test.ts file.


The upsert function in wallet-table.ts takes a walletToUpsert object of type WalletCreateObject and an options object with an optional txId. It returns a promise that resolves to a WalletFromDatabase object. The function performs an upsert operation and returns the first wallet from the result, which is expected to be the only wallet due to the nature of upsert operations.

The defaultWallet2 variable is imported from ../helpers/constants and used in various test cases within wallet-table.test.ts, including calls to create and upsert methods on WalletTable, and it is expected to match the structure required by the upsert method.

Given this information, the test logic appears to be intentionally upserting the same wallet data multiple times to confirm that the upsert operation behaves correctly when inserting a new wallet and when updating an existing wallet. The assertions using expect.objectContaining(defaultWallet2) are checking that the wallet returned from the database matches the data that was upserted.

Based on the provided context and the new information from the scripts, the review comment questioning the intention of upserting the same wallet data multiple times and the validity of the assertions seems to be addressed. The test is designed to verify the idempotency of the upsert operation, which is a common practice in testing database operations.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Verify that the upsert method is compatible with defaultWallet2 structure and is intended to be called multiple times.
ast-grep --lang typescript --pattern $'WalletTable.upsert($_)'

Length of output: 293



Script:

#!/bin/bash
# Extract the definition of defaultWallet2 and the upsert method from the wallet-table.test.ts file.
rg "let defaultWallet2 =" ./indexer/packages/postgres/__tests__/stores/wallet-table.test.ts
rg "upsert" ./indexer/packages/postgres/src/stores/wallet-table.ts

Length of output: 233



Script:

#!/bin/bash
# Extract the full definition of the upsert method from the wallet-table.ts file.
rg -A 10 "export async function upsert" ./indexer/packages/postgres/src/stores/wallet-table.ts

# Attempt to find the definition of defaultWallet2 in the wallet-table.test.ts file.
rg "defaultWallet2" ./indexer/packages/postgres/__tests__/stores/wallet-table.test.ts

Length of output: 1129

* 40-43: The creation of a wallet with a hardcoded 'fake_address' should be reviewed to ensure it aligns with the test's objectives and that the address is not used elsewhere in a conflicting manner.
  • 54-57: The assertion checks if the wallet object contains properties of defaultWallet2. Confirm that the test is correctly asserting the expected properties and that defaultWallet2 is the intended object for comparison.

  • 61-67: The create and findById methods are used in conjunction with defaultWallet2. Verify that the findById method is expected to retrieve the wallet created with defaultWallet2 and that the assertion is correct.

Verification successful

The search results indicate that both defaultWallet2 and defaultAddress are imported from ../helpers/constants in the wallet-table.test.ts file. The defaultWallet2 object is used in the create, upsert, and expect calls, and defaultAddress is used as an argument to the findById method. Given that they are imported from the same file, it is reasonable to infer that defaultAddress is related to defaultWallet2, likely representing the address of the wallet.

Since defaultWallet2 is used to create and upsert a wallet, and defaultAddress is used to find a wallet, the test expects that the wallet found by findById using defaultAddress will contain the data from defaultWallet2. The assertion expect(wallet).toEqual(expect.objectContaining(defaultWallet2)) is checking that the wallet returned by findById matches the expected fields of defaultWallet2.

Based on this information, it can be concluded that the findById method is expected to retrieve the wallet created with defaultWallet2, and the assertion is correctly checking this.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Verify that findById is expected to work with the wallet created with defaultWallet2 and that the assertion is correct.
ast-grep --lang typescript --pattern $'WalletTable.findById($_)'

Length of output: 2707



Script:

#!/bin/bash
# Verify the relationship between defaultWallet2, defaultAddress, and the findById method.
# Also, check the assertion for correctness.
rg 'let defaultWallet2 =' ./indexer/packages/postgres/__tests__/stores/wallet-table.test.ts
rg 'const defaultAddress =' ./indexer/packages/postgres/__tests__/stores/wallet-table.test.ts

Length of output: 189



Script:

#!/bin/bash
# Broaden the search for defaultWallet2 and defaultAddress without assuming specific variable declaration keywords.
# Also, search for any import statements that might include these variables.
rg 'defaultWallet2' ./indexer/packages/postgres/__tests__/stores/wallet-table.test.ts
rg 'defaultAddress' ./indexer/packages/postgres/__tests__/stores/wallet-table.test.ts

Length of output: 885

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.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 3fabcd3 and 45f5b23.
Files selected for processing (1)
  • indexer/packages/postgres/tests/stores/trading-reward-aggregation-table.test.ts (4 hunks)
Files skipped from review as they are similar to previous changes (1)
  • indexer/packages/postgres/tests/stores/trading-reward-aggregation-table.test.ts

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.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 45f5b23 and 0643579.
Files selected for processing (1)
  • indexer/packages/postgres/tests/stores/wallet-table.test.ts (3 hunks)
Files skipped from review as they are similar to previous changes (1)
  • indexer/packages/postgres/tests/stores/wallet-table.test.ts

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.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 0643579 and f294652.
Files selected for processing (3)
  • indexer/packages/postgres/src/stores/wallet-table.ts (3 hunks)
  • indexer/packages/postgres/src/types/wallet-types.ts (1 hunks)
  • indexer/services/ender/tests/handlers/trading-rewards-handler.test.ts (1 hunks)
Additional comments: 4
indexer/packages/postgres/src/types/wallet-types.ts (1)
  • 8-11: The addition of WalletUpdateObject aligns with the existing structure and naming conventions of the wallet types.
indexer/packages/postgres/src/stores/wallet-table.ts (2)
  • 16-16: The import of WalletUpdateObject is correctly added for use in the new update function.

  • 74-87: Verify the return type of the patch method to ensure that the cast to a single WalletFromDatabase object is correct.

Verification successful

The previous script contained an error due to the incorrect usage of the --exec flag with rg. Let's correct the script to search for the patch method within TypeScript files and examine the output to verify the return type of the patch method.


It seems there was an issue with the file type specification in the rg command. Ripgrep may not recognize "typescript" as a file type directly. Instead, we can search for files with the .ts extension. Let's adjust the script accordingly to search for the patch method in .ts files.


The output from the script shows several instances of the patch method being used in the context of the Objection.js ORM within the indexer/packages/postgres/src/stores/ directory. In each case, the method is chained with .returning('*'), which suggests that the expected behavior is to return the updated row(s) from the database.

Given this pattern, it's reasonable to infer that the patch method followed by .returning('*') is intended to return the updated object, and the cast to a single WalletFromDatabase object in the wallet-table.ts file is likely correct. However, without explicit documentation or type definitions confirming this behavior, we cannot be entirely certain.

Based on the observed usage pattern in the codebase, the review comment regarding the return type of the patch method and the cast to a single object seems to be consistent with the other usages in the codebase.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Verify the return type of the patch method in the Objection.js model
rg --type typescript --files-with-matches 'patch' --exec cat {} +

Length of output: 476



Script:

#!/bin/bash
# Search for the usage of the patch method in TypeScript files to infer the return type
rg --type typescript 'patch' 

Length of output: 63



Script:

#!/bin/bash
# Search for the usage of the patch method in .ts files to infer the return type
rg 'patch' --glob '*.ts'

Length of output: 2972

indexer/services/ender/__tests__/handlers/trading-rewards-handler.test.ts (1)
  • 197-200: The test case has been correctly updated to use the update method from WalletTable.

@@ -1,6 +1,6 @@
import { WalletFromDatabase } from '../../src/types';
import { clearData, migrate, teardown } from '../../src/helpers/db-helpers';
import { defaultAddress, defaultWallet } from '../helpers/constants';
import { defaultWallet2 } from '../helpers/constants';
Copy link
Contributor

Choose a reason for hiding this comment

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

is this necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since defaultWallet is created by default now, and half of the functions in wallet-table are testing behavior before and after the wallet is created, it was easiest to just use defaultWallet2 instead of trying to customize the logic

@@ -194,7 +194,7 @@ describe('tradingRewardHandler', () => {
txHash: defaultTxHash,
});

await WalletTable.create({
await WalletTable.update({
Copy link
Contributor

Choose a reason for hiding this comment

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

is this necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, because the default walletAddress already exists, in seed, so we are changing this operation from create to update

@@ -75,8 +77,14 @@ export const configSchema = {
LOOPS_INTERVAL_MS_REMOVE_OLD_ORDER_UPDATES: parseInteger({
default: THIRTY_SECONDS_IN_MILLISECONDS,
}),
LOOPS_INTERVAL_MS_AGGREGATE_TRADING_REWARDS: parseInteger({
default: ONE_MINUTE_IN_MILLISECONDS,
LOOPS_INTERVAL_MS_AGGREGATE_TRADING_REWARDS_DAILY: parseInteger({
Copy link
Contributor

Choose a reason for hiding this comment

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

do we need separate configs for each period? is there a case where they'll be individually turned on/off?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

combine these together

redisClient,
);
if (processedTime === null) {
await this.deleteIncompleteAggregatedTradingReward();
Copy link
Contributor

Choose a reason for hiding this comment

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

It's a little confusing that this getTradingRewardDataToProcessInterval function has the side effect of deleting trading reward aggregation. Up to you whether you want to refactor this part out.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

moved it out, good call out

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.

Review Status

Actionable comments generated: 2

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between f294652 and 56608e9.
Files selected for processing (7)
  • indexer/packages/postgres/src/models/trading-reward-aggregation-model.ts (1 hunks)
  • indexer/packages/redis/tests/caches/aggregate-trading-rewards-processed-cache.test.ts (1 hunks)
  • indexer/packages/redis/src/caches/aggregate-trading-rewards-processed-cache.ts (1 hunks)
  • indexer/services/roundtable/tests/tasks/aggregate-trading-rewards.test.ts (2 hunks)
  • indexer/services/roundtable/src/config.ts (3 hunks)
  • indexer/services/roundtable/src/index.ts (2 hunks)
  • indexer/services/roundtable/src/tasks/aggregate-trading-rewards.ts (1 hunks)
Additional comments: 8
indexer/packages/redis/__tests__/caches/aggregate-trading-rewards-processed-cache.test.ts (1)
  • 1-38: The test case for setting and getting processed times in Redis is well-structured and covers the expected functionality.
indexer/packages/postgres/src/models/trading-reward-aggregation-model.ts (1)
  • 54-54: The update to the comment for the endedAt property in the jsonSchema correctly reflects the change in period end time logic from inclusive to exclusive.
indexer/services/roundtable/src/index.ts (1)
  • 126-147: The conditional blocks for starting the aggregate trading rewards loops are correctly structured and use the appropriate parameters for daily, weekly, and monthly aggregation periods.
indexer/services/roundtable/src/config.ts (3)
  • 45-47: The new configuration options for enabling aggregate trading rewards on different bases are correctly added and set to true by default.

  • 81-81: The modification of the loop interval value for aggregate trading rewards to THIRTY_SECONDS_IN_MILLISECONDS is correctly implemented.

  • 138-138: The addition of AGGREGATE_TRADING_REWARDS_MAX_INTERVAL_SIZE_MS with a default value of ONE_HOUR_IN_MILLISECONDS is correctly implemented.

indexer/services/roundtable/src/tasks/aggregate-trading-rewards.ts (1)
  • 33-39: The generateTaskFromPeriod function is correctly structured to return a task function based on the provided period.
indexer/services/roundtable/__tests__/tasks/aggregate-trading-rewards.test.ts (1)
  • 40-341: The test cases for the AggregateTradingReward class methods are comprehensive and cover various scenarios, including cache states and block data presence.

Comment on lines +1 to +30
import { IsoString, TradingRewardAggregationPeriod } from '@dydxprotocol-indexer/postgres';
import { RedisClient } from 'redis';

import { getAsync } from '../helpers/redis';

/**
* Cache key for the aggregate trading rewards processed cache. Given a
* TradingRewardAggregationPeriod, this cache stores the timestamp of the
* trading rewards that have been processed up to and excluding that timestamp.
*/
export const AGGREGATE_TRADING_REWARDS_PROCESSED_CACHE_KEY: string = 'v4/aggregate_trading_rewards_processed/';

function getKey(period: TradingRewardAggregationPeriod): string {
return `${AGGREGATE_TRADING_REWARDS_PROCESSED_CACHE_KEY}${period}`;
}

export async function getProcessedTime(
period: TradingRewardAggregationPeriod,
client: RedisClient,
): Promise<IsoString | null> {
return getAsync(getKey(period), client);
}

export async function setProcessedTime(
period: TradingRewardAggregationPeriod,
timestamp: IsoString,
client: RedisClient,
): Promise<void> {
await client.set(getKey(period), timestamp);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Please add a file-level comment explaining how the AggregateTradingRewardsProcessedCache is utilized within the system for clarity.

Comment on lines +42 to +70
export class AggregateTradingReward {
period: TradingRewardAggregationPeriod;

// TODO(IND-499): Setup AggregateTradingRewardsProcessedCache for start time and add end time
return {
start: DateTime.fromISO(latestBlock.time),
end: DateTime.fromISO(latestBlock.time),
};
}
constructor(period: TradingRewardAggregationPeriod) {
this.period = period;
}

async function getTradingRewardDataToProcess(
_interval: Interval,
): Promise<TradingRewardFromDatabase[]> {
// TODO: Implement
return Promise.resolve([]);
}
async runTask(): Promise<void> {
await this.maybeDeleteIncompleteAggregatedTradingReward();
const interval: Interval = await this.getTradingRewardDataToProcessInterval();
logger.info({
at: 'aggregate-trading-rewards#runTask',
message: 'Generated interval to aggregate trading rewards',
start: interval.start.toISO(),
end: interval.end.toISO(),
});

function sortTradingRewardData(
_tradingRewardData: TradingRewardFromDatabase[],
): SortedTradingRewardData {
// TODO: Implement
return {};
}
const tradingRewardData:
TradingRewardFromDatabase[] = await this.getTradingRewardDataToProcess(interval);
const sortedTradingRewardData: SortedTradingRewardData = this.sortTradingRewardData(
tradingRewardData,
);
await this.updateTradingRewardsAggregation(sortedTradingRewardData);
await AggregateTradingRewardsProcessedCache.setProcessedTime(
this.period,
interval.end.toISO(),
redisClient,
);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The AggregateTradingReward class is well-structured with a clear constructor and method for running the task. Ensure that the TODOs for implementing the data processing logic are addressed.

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.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between b93fc56 and 522a238.
Files selected for processing (19)
  • indexer/packages/base/src/date-helpers.ts (1 hunks)
  • indexer/packages/base/src/index.ts (1 hunks)
  • indexer/packages/postgres/tests/helpers/mock-generators.ts (3 hunks)
  • indexer/packages/postgres/tests/stores/trading-reward-aggregation-table.test.ts (4 hunks)
  • indexer/packages/postgres/tests/stores/wallet-table.test.ts (3 hunks)
  • indexer/packages/postgres/src/models/trading-reward-aggregation-model.ts (1 hunks)
  • indexer/packages/postgres/src/stores/trading-reward-aggregation-table.ts (3 hunks)
  • indexer/packages/postgres/src/stores/wallet-table.ts (3 hunks)
  • indexer/packages/postgres/src/types/query-types.ts (2 hunks)
  • indexer/packages/postgres/src/types/wallet-types.ts (1 hunks)
  • indexer/packages/redis/tests/caches/aggregate-trading-rewards-processed-cache.test.ts (1 hunks)
  • indexer/packages/redis/src/caches/aggregate-trading-rewards-processed-cache.ts (1 hunks)
  • indexer/packages/redis/src/index.ts (1 hunks)
  • indexer/services/ender/tests/handlers/trading-rewards-handler.test.ts (1 hunks)
  • indexer/services/roundtable/tests/tasks/aggregate-trading-rewards.test.ts (2 hunks)
  • indexer/services/roundtable/src/config.ts (3 hunks)
  • indexer/services/roundtable/src/index.ts (2 hunks)
  • indexer/services/roundtable/src/lib/constants.ts (2 hunks)
  • indexer/services/roundtable/src/tasks/aggregate-trading-rewards.ts (1 hunks)
Files skipped from review as they are similar to previous changes (7)
  • indexer/packages/postgres/src/models/trading-reward-aggregation-model.ts
  • indexer/packages/redis/tests/caches/aggregate-trading-rewards-processed-cache.test.ts
  • indexer/packages/redis/src/caches/aggregate-trading-rewards-processed-cache.ts
  • indexer/services/roundtable/tests/tasks/aggregate-trading-rewards.test.ts
  • indexer/services/roundtable/src/config.ts
  • indexer/services/roundtable/src/index.ts
  • indexer/services/roundtable/src/tasks/aggregate-trading-rewards.ts
Additional comments: 22
indexer/packages/postgres/src/types/wallet-types.ts (1)
  • 8-11: The addition of the WalletUpdateObject interface is consistent with the PR's objectives to enhance the trading rewards system, specifically by allowing updates to wallets with trading rewards.
indexer/services/roundtable/src/lib/constants.ts (2)
  • 2-2: The import of DateTimeOptions from 'luxon' is appropriate for handling date and time operations, which is likely relevant to the new caching and task scheduling features.

  • 14-14: The declaration of UTC_OPTIONS with { zone: 'utc' } is a good practice for ensuring consistent time zone handling across the application.

indexer/packages/base/src/index.ts (1)
  • 15-15: Exporting the date-helpers module aligns with the PR's objectives to introduce date-related utility functions, which are likely used in the new caching mechanism and task enhancements.
indexer/packages/base/src/date-helpers.ts (2)
  • 5-10: The floorDate function correctly implements the flooring of a date to the nearest interval defined by timeInMilliseconds, which is useful for rounding dates in the context of reward processing.

  • 17-22: Similarly, the ceilingDate function correctly implements the ceiling of a date to the nearest interval, complementing the floorDate function and providing necessary functionality for date rounding.

indexer/packages/redis/src/index.ts (1)
  • 3-3: The export of AggregateTradingRewardsProcessedCache is in line with the PR's objectives to introduce a new caching mechanism for aggregate trading rewards.
indexer/packages/postgres/__tests__/stores/wallet-table.test.ts (4)
  • 20-20: The test case for creating a wallet is updated to use defaultWallet2 instead of defaultWallet, which is consistent with the explanation provided in the previous comments.

  • 24-33: The test case for upserting a wallet multiple times and validating the wallet's state after each upsert operation is correctly updated to use defaultWallet2.

  • 52-55: The test case for finding all wallets and asserting their properties is correctly updated to use defaultWallet2 and the new fake_address.

  • 59-65: The test case for finding a specific wallet by address is correctly updated to use defaultWallet2.

indexer/packages/postgres/__tests__/helpers/mock-generators.ts (2)
  • 8-8: The addition of WalletTable to the import statements is necessary for creating a defaultWallet in the seedData function, which is consistent with the changes in the test files.

  • 67-67: The creation of a defaultWallet in the seedData function is necessary for setting up the test environment, which now includes wallet-related operations.

indexer/packages/postgres/src/stores/wallet-table.ts (2)
  • 1-1: The addition of PartialModelObject to the import statement is necessary for the new update function, which allows partial updates to wallet records.

  • 74-86: The new update function is correctly implemented to handle wallet updates, using the WalletUpdateObject and PartialModelObject to perform a patch operation.

indexer/packages/postgres/src/stores/trading-reward-aggregation-table.ts (2)
  • 95-109: The addition of the getLatestAggregatedTradeReward function is consistent with the PR's objectives to retrieve the latest aggregated trade reward, which is likely used in the new task enhancements.

  • 156-177: The new deleteAll function is correctly implemented to delete aggregated trade rewards based on specified criteria, which is necessary for maintaining the integrity of the reward aggregation system.

indexer/packages/postgres/__tests__/stores/trading-reward-aggregation-table.test.ts (2)
  • 61-91: The test case for finding the latest monthly TradingRewardAggregation is correctly implemented, ensuring that the most recent aggregation is retrieved as expected.

  • 137-174: The test case for deleting trading reward aggregations after a certain height is correctly implemented, ensuring that the deleteAll function works as intended.

indexer/services/ender/__tests__/handlers/trading-rewards-handler.test.ts (1)
  • 197-200: The test logic is altered to update an existing entry in the WalletTable instead of creating a new one, which is consistent with the changes in the wallet handling logic.
indexer/packages/postgres/src/types/query-types.ts (2)
  • 78-78: The addition of STARTED_AT_HEIGHT_OR_AFTER to the QueryableField enum is necessary for querying trading reward aggregations based on a new criterion.

  • 283-283: The update to the TradingRewardAggregationQueryConfig interface to include the STARTED_AT_HEIGHT_OR_AFTER field is consistent with the new querying capabilities introduced in the PR.

@Christopher-Li Christopher-Li merged commit e47b841 into main Jan 5, 2024
11 checks passed
@Christopher-Li Christopher-Li deleted the cl_cache branch January 5, 2024 21:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging this pull request may close these issues.

2 participants