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

Filter out to single tick per interval. #2403

Merged
merged 5 commits into from
Oct 1, 2024

Conversation

vincentwschau
Copy link
Contributor

@vincentwschau vincentwschau commented Sep 30, 2024

Changelist

It's possible for a vault to be instantiated in the middle of the day/hour, and start having PnL ticks in the middle of the day/hour. This breaks the aggregation logic for PnL ticks as it introduces an extra PnL tick in the middle of the day / hour for the megavault.
This change adds a filtering function that only takes the aggregated PnL ticks with block times closest to the start of the day / hour.

Test Plan

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.

Summary by CodeRabbit

  • New Features

    • Introduced a new configuration parameter for vault profit and loss history, allowing for more granular control.
    • Enhanced functionality for fetching historical profit and loss data with improved resolution handling and filtering logic.
  • Bug Fixes

    • Updated test cases to ensure accurate handling of historical profit and loss data for vault subaccounts, accommodating multiple vaults and undefined values.

@vincentwschau vincentwschau requested a review from a team as a code owner September 30, 2024 16:39
Copy link
Contributor

coderabbitai bot commented Sep 30, 2024

Walkthrough

The changes implement enhancements to the vault controller's API, focusing on the handling of historical profit and loss (PnL) data for vault subaccounts. Key modifications include the introduction of a new configuration parameter for PnL history, updates to test cases to accommodate changes in block heights, and the implementation of new functions to standardize resolution handling and filter PnL ticks based on specified intervals.

Changes

Files Change Summary
indexer/services/comlink/src/controllers/api/v4/vault-controller.ts Modified methods to standardize resolution handling for historical PnL data, introduced new filtering logic for PnL ticks, and updated function signatures to enforce non-optional resolution parameters.
indexer/services/comlink/__tests__/controllers/api/v4/vault-controller.test.ts Updated test cases for API endpoints handling historical PnL data, adjusted block heights, and modified expected response structures to allow for undefined values.
indexer/services/comlink/src/config.ts Added a new configuration parameter VAULT_PNL_HISTORY_HOURS to allow for more granular control over PnL data history, defaulting to 72 hours.

Possibly related PRs

Suggested labels

backport/indexer/v7.x

Suggested reviewers

  • tqin7

🐰 In the vaults where profits bloom,
A new hour's tale begins to loom.
With tests refined and logic clear,
Our PnL data brings good cheer!
So hop along, let changes flow,
For brighter days, we surely sow! 🌼


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

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Outside diff range and nitpick comments (1)
indexer/services/comlink/src/config.ts (1)

64-64: LGTM! Consider adding a comment for clarity.

The addition of VAULT_PNL_HISTORY_HOURS is a good enhancement that aligns with the PR objectives. It provides more granular control over the PnL history, complementing the existing VAULT_PNL_HISTORY_DAYS parameter.

Consider adding a brief comment explaining the purpose and relationship between VAULT_PNL_HISTORY_HOURS and VAULT_PNL_HISTORY_DAYS. This would improve code readability and maintainability. For example:

  VAULT_PNL_HISTORY_DAYS: parseInteger({ default: 90 }),
+ // VAULT_PNL_HISTORY_HOURS provides finer granularity for recent PnL history
  VAULT_PNL_HISTORY_HOURS: parseInteger({ default: 72 }),
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 19fd34d and b8b71d4.

📒 Files selected for processing (3)
  • indexer/services/comlink/tests/controllers/api/v4/vault-controller.test.ts (5 hunks)
  • indexer/services/comlink/src/config.ts (1 hunks)
  • indexer/services/comlink/src/controllers/api/v4/vault-controller.ts (7 hunks)
🧰 Additional context used
🪛 Biome
indexer/services/comlink/src/controllers/api/v4/vault-controller.ts

[error] 466-466: Forbidden extra non-null assertion.

Safe fix: Remove extra non-null assertion.

(lint/suspicious/noExtraNonNullAssertion)

🔇 Additional comments (5)
indexer/services/comlink/src/config.ts (1)

64-64: Verify the usage of the new configuration parameter.

The addition of VAULT_PNL_HISTORY_HOURS is well-integrated into the existing configuration structure. It maintains consistency with other parameters and doesn't disrupt the overall configuration processing.

To ensure proper implementation, please verify that this new configuration parameter is correctly utilized in the relevant parts of the codebase. Run the following script to check its usage:

This will help ensure that the new parameter is being used appropriately throughout the project.

✅ Verification successful

VAULT_PNL_HISTORY_HOURS usage verified

The VAULT_PNL_HISTORY_HOURS parameter is correctly utilized in config.ts and vault-controller.ts. The integration maintains consistency with existing configuration parameters and functions as intended without disrupting the overall configuration processing.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of VAULT_PNL_HISTORY_HOURS in the codebase

# Search for usage of VAULT_PNL_HISTORY_HOURS
echo "Searching for VAULT_PNL_HISTORY_HOURS usage:"
rg --type typescript --type javascript "VAULT_PNL_HISTORY_HOURS"

# Search for potential places where it should be used alongside VAULT_PNL_HISTORY_DAYS
echo "\nSearching for potential usage alongside VAULT_PNL_HISTORY_DAYS:"
rg --type typescript --type javascript "VAULT_PNL_HISTORY_DAYS"

Length of output: 438


Script:

#!/bin/bash
# Description: Verify the usage of VAULT_PNL_HISTORY_HOURS in the codebase

# Search for usage of VAULT_PNL_HISTORY_HOURS
echo "Searching for VAULT_PNL_HISTORY_HOURS usage:"
rg --type=ts --type=js "VAULT_PNL_HISTORY_HOURS"

# Search for potential places where it should be used alongside VAULT_PNL_HISTORY_DAYS
echo "\nSearching for potential usage alongside VAULT_PNL_HISTORY_DAYS:"
rg --type=ts --type=js "VAULT_PNL_HISTORY_DAYS"

Length of output: 832

indexer/services/comlink/__tests__/controllers/api/v4/vault-controller.test.ts (3)

162-170: Validate handling of undefined values in test cases

In the parameterized test cases starting at line 162, the arrays contain undefined values. Ensure that the test logic correctly handles undefined entries to prevent unexpected behaviors during execution.

Please verify that the mapping functions and any iterations properly account for undefined values.


535-537: Consistency in timestamp and block height assignment

In the creation of PnlTicksTable entries, the blockTime, createdAt, and blockHeight are set using almostTwoDaysAgo and almostTwoDayBlockHeight. Verify that these timestamps and block heights align correctly with the intended test scenarios.

Ensure that almostTwoDaysAgo and almostTwoDayBlockHeight accurately represent the desired time difference and are used consistently across the related test data.


27-29: Ensure consistent block height values

The block heights for currentBlockHeight, twoHourBlockHeight, and almostTwoDayBlockHeight are set to string values '9', '7', and '5' respectively. Ensure that these values correctly represent the intended block heights and that any dependent logic or calculations align with these updated values.

Run the following script to cross-verify block height usages:

indexer/services/comlink/src/controllers/api/v4/vault-controller.ts (1)

33-33: Appropriate import of 'DateTime' from 'luxon'

Importing DateTime from 'luxon' is necessary for date and time manipulations in the new function filterOutIntervalTicks.

Comment on lines 520 to 526
function getResolution(resolution?: PnlTickInterval) {
if (resolution === undefined) {
return PnlTickInterval.day;
}

return resolution;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Simplify the getResolution function using default parameters

You can refactor the getResolution function to use default parameters, which makes the code cleaner and removes the need to check for undefined.

Apply this diff to refactor the function:

-function getResolution(resolution?: PnlTickInterval) {
-  if (resolution === undefined) {
-    return PnlTickInterval.day;
-  }
-
-  return resolution;
+function getResolution(resolution: PnlTickInterval = PnlTickInterval.day): PnlTickInterval {
+  return resolution;
}
📝 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
function getResolution(resolution?: PnlTickInterval) {
if (resolution === undefined) {
return PnlTickInterval.day;
}
return resolution;
}
function getResolution(resolution: PnlTickInterval = PnlTickInterval.day): PnlTickInterval {
return resolution;
}

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

🧹 Outside diff range and nitpick comments (5)
indexer/services/comlink/src/controllers/api/v4/vault-controller.ts (5)

89-89: LGTM: Improved resolution handling and tick filtering

The changes in the getMegavaultHistoricalPnl method effectively implement the new resolution handling and tick filtering:

  1. Using getResolution(resolution) ensures consistent resolution handling.
  2. The new filterOutIntervalTicks function addresses the PR objective of filtering out single ticks per interval.

These modifications should resolve the issue of extra PnL ticks disrupting the aggregation process.

Consider extracting the getResolution(resolution) call to a variable at the beginning of the method to avoid repeated function calls:

 async getMegavaultHistoricalPnl(
   @Query() resolution?: PnlTickInterval,
 ): Promise<MegavaultHistoricalPnlResponse> {
+  const resolvedResolution = getResolution(resolution);
   // ... existing code ...
   const [
     vaultPnlTicks,
     // ... other destructured variables ...
   ] : [
     // ... type annotations ...
   ] = await Promise.all([
-    getVaultSubaccountPnlTicks(vaultSubaccountIdsWithMainSubaccount, getResolution(resolution)),
+    getVaultSubaccountPnlTicks(vaultSubaccountIdsWithMainSubaccount, resolvedResolution),
     // ... other Promise.all elements ...
   ]);

   // ... existing code ...

   const pnlTicksWithCurrentTick: PnlTicksFromDatabase[] = getPnlTicksWithCurrentTick(
     currentEquity,
-    filterOutIntervalTicks(aggregatedPnlTicks, getResolution(resolution)),
+    filterOutIntervalTicks(aggregatedPnlTicks, resolvedResolution),
     latestBlock,
   );

   // ... rest of the method ...
 }

This change would slightly improve readability and reduce redundant function calls.

Also applies to: 106-106


132-132: LGTM: Consistent resolution handling

The change in the getVaultsHistoricalPnl method aligns with the modifications made in getMegavaultHistoricalPnl, ensuring consistent resolution handling across different methods.

Similar to the suggestion for getMegavaultHistoricalPnl, consider extracting the getResolution(resolution) call to a variable at the beginning of the method:

 async getVaultsHistoricalPnl(
   @Query() resolution?: PnlTickInterval,
 ): Promise<VaultsHistoricalPnlResponse> {
+  const resolvedResolution = getResolution(resolution);
   const vaultSubaccounts: VaultMapping = await getVaultMapping();
   const [
     vaultPnlTicks,
     vaultPositions,
     latestBlock,
   ] : [
     PnlTicksFromDatabase[],
     Map<string, VaultPosition>,
     BlockFromDatabase,
   ] = await Promise.all([
-    getVaultSubaccountPnlTicks(_.keys(vaultSubaccounts), getResolution(resolution)),
+    getVaultSubaccountPnlTicks(_.keys(vaultSubaccounts), resolvedResolution),
     getVaultPositions(vaultSubaccounts),
     BlockTable.getLatest(),
   ]);

   // ... rest of the method ...
 }

This change would improve consistency with the getMegavaultHistoricalPnl method and reduce redundant function calls.


298-313: LGTM: Improved resolution handling in getVaultSubaccountPnlTicks

The changes in the getVaultSubaccountPnlTicks function effectively implement resolution-based PnL history retrieval:

  1. The resolution parameter is now required, ensuring that a valid resolution is always provided.
  2. The windowSeconds calculation adapts based on the resolution (daily or hourly), using appropriate configuration values.
  3. The PnlTicksTable.getPnlTicksAtIntervals call now uses the correct parameters for resolution-based querying.

These modifications align well with the PR objectives and should provide more flexible and accurate PnL history retrieval.

Consider using a switch statement or object mapping for windowSeconds calculation to improve readability and extensibility:

const SECONDS_PER_DAY = 24 * 60 * 60;
const SECONDS_PER_HOUR = 60 * 60;

const windowSecondsMap = {
  [PnlTickInterval.day]: config.VAULT_PNL_HISTORY_DAYS * SECONDS_PER_DAY,
  [PnlTickInterval.hour]: config.VAULT_PNL_HISTORY_HOURS * SECONDS_PER_HOUR,
};

const windowSeconds = windowSecondsMap[resolution];
if (windowSeconds === undefined) {
  throw new Error(`Unsupported resolution: ${resolution}`);
}

This approach would make it easier to add new resolutions in the future and provides a clear error if an unsupported resolution is passed.


466-466: LGTM with a minor suggestion: Use of _.maxBy for latest PnL tick

The change to use _.maxBy(pnlTicks, 'blockTime') is a good improvement, ensuring that the most recent PnL tick is used as a base for the current tick. This aligns well with the PR objectives and should provide more accurate current tick information.

Remove the unnecessary non-null assertion operator (!) as suggested by the static analysis tool. The pnlTicks array is guaranteed to be non-empty due to the preceding check, so _.maxBy will always return a value.

Apply this diff to fix the issue:

-    ...(_.maxBy(pnlTicks, 'blockTime')!),
+    ...(_.maxBy(pnlTicks, 'blockTime')),

This change will improve code safety and comply with the static analysis recommendation.

🧰 Tools
🪛 Biome

[error] 466-466: Forbidden extra non-null assertion.

Safe fix: Remove extra non-null assertion.

(lint/suspicious/noExtraNonNullAssertion)


475-518: LGTM: Well-implemented filterOutIntervalTicks function

The new filterOutIntervalTicks function effectively implements the core logic for filtering PnL ticks to one per interval, addressing the main objective of the PR. Key points:

  1. Proper use of Luxon's DateTime for date/time operations.
  2. Correct handling of both day and hour intervals.
  3. Logical approach to finding the closest tick to the start of each interval.

This implementation should resolve the issue of extra PnL ticks disrupting the aggregation process.

Consider adding some comments to explain the logic, especially for the comparison in the if statement on line 512. This will improve readability and maintainability. For example:

// If this block's time is closer to the start of the interval than the currently stored block,
// update the block and tick for this interval
if (blockTime.diff(startOfInterval) < startOfDayBlockTime.diff(startOfInterval)) {
  blocksPerInterval.set(startOfInterval.toISO(), block);
  ticksPerInterval.set(startOfInterval.toISO(), pnlTick);
}

Additionally, consider extracting the interval start calculation to a separate function for better readability:

function getIntervalStart(dateTime: DateTime, resolution: PnlTickInterval): DateTime {
  return dateTime.toUTC().startOf(resolution);
}

// Usage in the function:
const startOfInterval: DateTime = getIntervalStart(blockTime, resolution);

These changes would make the function easier to understand and maintain.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between b8b71d4 and 9a77f2a.

📒 Files selected for processing (1)
  • indexer/services/comlink/src/controllers/api/v4/vault-controller.ts (7 hunks)
🧰 Additional context used
🪛 Biome
indexer/services/comlink/src/controllers/api/v4/vault-controller.ts

[error] 466-466: Forbidden extra non-null assertion.

Safe fix: Remove extra non-null assertion.

(lint/suspicious/noExtraNonNullAssertion)

🔇 Additional comments (3)
indexer/services/comlink/src/controllers/api/v4/vault-controller.ts (3)

33-33: LGTM: Appropriate import for date/time handling

The import of DateTime from the Luxon library is a good choice for handling date and time operations in the new filtering function.


520-522: LGTM: Useful getResolution helper function

The new getResolution function is a simple yet effective helper that ensures a valid resolution is always returned, defaulting to PnlTickInterval.day when no resolution is provided. This function contributes to standardizing resolution handling across the controller, which aligns well with the PR objectives.


Line range hint 1-523: Overall assessment: Well-implemented changes addressing PR objectives

The changes in this file effectively address the main objectives of the PR:

  1. Filtering out single ticks per interval to prevent disruption in the aggregation process.
  2. Handling different resolutions (daily and hourly) for PnL history.
  3. Standardizing resolution handling across the controller.

The new filterOutIntervalTicks function, along with the modifications to existing methods, should resolve the issue of extra PnL ticks. The code is generally well-structured and follows good practices.

Minor suggestions for improvement have been made, mainly focusing on:

  • Extracting repeated function calls to variables.
  • Improving readability with comments and helper functions.
  • Removing an unnecessary non-null assertion.

These suggestions, if implemented, would further enhance the code quality and maintainability.

@tqin7
Copy link
Contributor

tqin7 commented Sep 30, 2024

how are pnl ticks handled with generic subaccounts (what happens if a subaccount gets transferred to for the first time in the middle of a day/hour)?

@tqin7 tqin7 closed this Sep 30, 2024
@tqin7 tqin7 reopened this Sep 30, 2024
pnlTickInterval = PnlTickInterval.day;

let windowSeconds: number;
if (resolution === PnlTickInterval.day) {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: maybe define a function that converts from resolution to seconds? thinking about the possibility of adding more resolution values in the future

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This doesn't work with the underlying SQL query.

/**
* Takes in a map of block heights to PnlTicks and filters out the closest pnl tick per interval.
* @param pnlTicksByBlock
* @returns
Copy link
Contributor

Choose a reason for hiding this comment

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

mega nit: missing return value? not sure whether the convention is to have something here

blockToBlockTime.set(block, blockTime);

const startOfInterval: DateTime = blockTime.toUTC().startOf(resolution);
const startOfIntervalBlock: number | undefined = blocksPerInterval.get(startOfInterval.toISO());
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: not sure how much work this call is. if notable, define startOfInterval.toISO() as a const so we don't call it many times?

@vincentwschau
Copy link
Contributor Author

how are pnl ticks handled with generic subaccounts (what happens if a subaccount gets transferred to for the first time in the middle of a day/hour)?

A pnl tick only gets created at each hour.

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

🧹 Outside diff range and nitpick comments (3)
indexer/services/comlink/src/controllers/api/v4/vault-controller.ts (3)

298-313: LGTM: Updated getVaultSubaccountPnlTicks function

The changes to getVaultSubaccountPnlTicks function improve the handling of resolution for PnL ticks. Making resolution a required parameter ensures consistent behavior.

Consider extracting the windowSeconds calculation into a separate function for better readability and maintainability:

function getWindowSeconds(resolution: PnlTickInterval): number {
  return resolution === PnlTickInterval.day
    ? config.VAULT_PNL_HISTORY_DAYS * 24 * 60 * 60
    : config.VAULT_PNL_HISTORY_HOURS * 60 * 60;
}

Then use it in the function:

const windowSeconds = getWindowSeconds(resolution);

466-466: Approve change and remove unnecessary non-null assertion

The use of _.maxBy(pnlTicks, 'blockTime') is a good improvement, ensuring that the most recent PnL tick is used as the base for the current tick. This is more robust than the previous approach of using the last element of the array.

However, the non-null assertion operator (!) is unnecessary here. Since pnlTicks is guaranteed to be non-empty (checked at the beginning of the function), _.maxBy will always return a value. You can safely remove the assertion:

- ...(_.maxBy(pnlTicks, 'blockTime')!),
+ ...(_.maxBy(pnlTicks, 'blockTime')),
🧰 Tools
🪛 Biome

[error] 466-466: Forbidden extra non-null assertion.

Safe fix: Remove extra non-null assertion.

(lint/suspicious/noExtraNonNullAssertion)


475-519: LGTM: New filterOutIntervalTicks function

The filterOutIntervalTicks function is well-implemented and aligns with the PR objectives. It effectively filters out additional PnL ticks, keeping only the closest tick per interval.

Suggestions for minor improvements:

  1. Add a return type annotation to the function for better type safety:
function filterOutIntervalTicks(
  pnlTicksByBlock: Map<number, PnlTicksFromDatabase>,
  resolution: PnlTickInterval,
): PnlTicksFromDatabase[] {
  // ... function body ...
}
  1. Consider using a more descriptive variable name instead of startOfDayBlockTime when working with non-day resolutions:
const closestIntervalBlockTime: DateTime | undefined = blockToBlockTime.get(startOfIntervalBlock);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 9a77f2a and 2255dca.

📒 Files selected for processing (1)
  • indexer/services/comlink/src/controllers/api/v4/vault-controller.ts (7 hunks)
🧰 Additional context used
🪛 Biome
indexer/services/comlink/src/controllers/api/v4/vault-controller.ts

[error] 466-466: Forbidden extra non-null assertion.

Safe fix: Remove extra non-null assertion.

(lint/suspicious/noExtraNonNullAssertion)

🔇 Additional comments (3)
indexer/services/comlink/src/controllers/api/v4/vault-controller.ts (3)

33-33: LGTM: Import of DateTime from luxon

The addition of the DateTime import from 'luxon' is appropriate for the new functionality introduced in this file, particularly for the filterOutIntervalTicks function.


Line range hint 89-106: LGTM: Updated getMegavaultHistoricalPnl method

The changes to the getMegavaultHistoricalPnl method are well-implemented and consistent with the PR objectives. The use of getResolution ensures proper handling of the resolution parameter, and the introduction of filterOutIntervalTicks addresses the issue of having multiple PnL ticks per interval.

These modifications effectively solve the problem described in the PR summary, where additional PnL ticks were being generated when a vault was instantiated mid-interval.


132-132: LGTM: Updated getVaultsHistoricalPnl method

The change to the getVaultsHistoricalPnl method, incorporating the getResolution function, is appropriate and consistent with the modifications made to getMegavaultHistoricalPnl. This ensures that the resolution is properly handled for individual vaults, maintaining consistency across the API.

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

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 2255dca and 1831319.

📒 Files selected for processing (1)
  • indexer/services/comlink/src/controllers/api/v4/vault-controller.ts (7 hunks)
🧰 Additional context used
🪛 Biome
indexer/services/comlink/src/controllers/api/v4/vault-controller.ts

[error] 466-466: Forbidden extra non-null assertion.

Safe fix: Remove extra non-null assertion.

(lint/suspicious/noExtraNonNullAssertion)

🔇 Additional comments (5)
indexer/services/comlink/src/controllers/api/v4/vault-controller.ts (5)

89-89: LGTM: Improved handling of resolution and PNL tick filtering

The changes to getMegavaultHistoricalPnl function now incorporate the new getResolution and filterOutIntervalTicks functions. This implementation aligns well with the PR objectives of filtering out single ticks per interval, improving the accuracy of historical PNL data.

Also applies to: 106-106


132-132: LGTM: Consistent resolution handling

The getVaultsHistoricalPnl function now uses the getResolution function, ensuring consistent resolution handling across different methods in the controller. This change improves the overall coherence of the code.


298-313: LGTM: Improved resolution handling in PNL tick retrieval

The getVaultSubaccountPnlTicks function has been updated to handle different resolutions (day or hour) and calculate the appropriate window size. This change supports the new filtering functionality and aligns well with the PR objectives. The use of configuration values (config.VAULT_PNL_HISTORY_DAYS and config.VAULT_PNL_HISTORY_HOURS) for determining the window size is a good practice for maintainability.


475-520: LGTM: Well-implemented interval filtering logic

The new filterOutIntervalTicks function effectively implements the core logic for filtering PNL ticks to ensure only one tick per interval is retained. The use of Luxon for date/time operations and the algorithm to find the closest tick to the start of each interval are well-implemented. This function directly addresses the PR objectives and should resolve the issue of extra PNL ticks being generated.


466-466: ⚠️ Potential issue

Remove unnecessary non-null assertion operator

The non-null assertion operator ! in _.maxBy(pnlTicks, 'blockTime')! is unnecessary since pnlTicks is guaranteed to be non-empty (validated by the preceding check). Removing it will improve code safety and comply with the static analysis recommendation.

Apply this diff to fix the issue:

-    ...(_.maxBy(pnlTicks, 'blockTime')!),
+    ...(_.maxBy(pnlTicks, 'blockTime')),

Likely invalid or redundant comment.

🧰 Tools
🪛 Biome

[error] 466-466: Forbidden extra non-null assertion.

Safe fix: Remove extra non-null assertion.

(lint/suspicious/noExtraNonNullAssertion)

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

🧹 Outside diff range and nitpick comments (3)
indexer/services/comlink/src/controllers/api/v4/vault-controller.ts (3)

89-89: LGTM: Improved resolution handling and tick filtering

The changes in the getMegavaultHistoricalPnl method enhance the handling of PnL data:

  1. Using getResolution ensures a consistent approach to resolution handling.
  2. The introduction of filterOutIntervalTicks aligns with the PR objective of filtering out single ticks per interval.

These modifications should effectively address the issue of extra PnL ticks being generated when a vault is instantiated mid-interval.

Consider extracting the getResolution(resolution) call into a variable at the beginning of the method to avoid calling it twice.

Also applies to: 106-106


298-298: LGTM: Improved handling of resolution and time windows

The changes in the getVaultSubaccountPnlTicks function enhance its functionality and flexibility:

  1. Making resolution a required parameter improves type safety.
  2. The new logic for windowSeconds allows for different time windows based on the resolution.
  3. Using resolution in the getPnlTicksAtIntervals call ensures correct interval usage.

These modifications align well with the PR objectives and provide more precise control over PnL data retrieval.

Consider using a switch statement or an object lookup for determining windowSeconds to make it easier to add new resolution types in the future:

const windowSecondsMap = {
  [PnlTickInterval.day]: config.VAULT_PNL_HISTORY_DAYS * 24 * 60 * 60,
  [PnlTickInterval.hour]: config.VAULT_PNL_HISTORY_HOURS * 60 * 60,
};
const windowSeconds = windowSecondsMap[resolution];

Also applies to: 304-308, 312-313


481-520: LGTM: Well-implemented interval tick filtering

The new filterOutIntervalTicks function effectively addresses the PR objective of filtering out single ticks per interval. Key points:

  1. Efficient use of maps to track blocks and ticks per interval.
  2. Proper handling of edge cases, such as when no block is set for the start of an interval.
  3. Correct use of the DateTime class for date and time operations.

This implementation should successfully resolve the issue of extra PnL ticks being generated when a vault is instantiated mid-interval.

Consider adding a comment explaining the logic for choosing the closest block to the start of the interval (lines 514-517). This will make the code more maintainable for future developers.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 1831319 and 2ddbfe7.

📒 Files selected for processing (1)
  • indexer/services/comlink/src/controllers/api/v4/vault-controller.ts (7 hunks)
🧰 Additional context used
🪛 Biome
indexer/services/comlink/src/controllers/api/v4/vault-controller.ts

[error] 466-466: Forbidden extra non-null assertion.

Safe fix: Remove extra non-null assertion.

(lint/suspicious/noExtraNonNullAssertion)

🔇 Additional comments (4)
indexer/services/comlink/src/controllers/api/v4/vault-controller.ts (4)

33-33: LGTM: New import for DateTime

The addition of the DateTime import from the 'luxon' library is appropriate for the new date and time operations introduced in this file.


132-132: LGTM: Consistent resolution handling

The use of getResolution in the getVaultsHistoricalPnl method ensures consistent handling of the resolution parameter across different methods in the controller. This change aligns well with the modifications made in the getMegavaultHistoricalPnl method.


522-524: LGTM: Concise resolution handling

The new getResolution function is a simple yet effective way to handle the resolution parameter:

  1. It provides a default resolution of PnlTickInterval.day.
  2. The implementation is concise and easy to understand.
  3. It ensures consistent handling of the resolution parameter throughout the file.

This function contributes to the overall improvement in PnL data handling in the controller.


Line range hint 1-525: Overall assessment: Well-implemented PnL tick filtering

The changes in this file effectively address the PR objectives:

  1. Introduction of filterOutIntervalTicks function resolves the issue of extra PnL ticks.
  2. Consistent handling of resolution parameter across different methods.
  3. Improved flexibility in determining time windows for PnL data retrieval.

The code is well-structured and maintainable. Minor suggestions have been made for further improvements, but overall, these changes should significantly enhance the accuracy of PnL data for vaults.

@vincentwschau vincentwschau merged commit ce94992 into main Oct 1, 2024
16 checks passed
@vincentwschau vincentwschau deleted the vincentc/single-tick-per-interval branch October 1, 2024 16:23
mergify bot pushed a commit that referenced this pull request Oct 1, 2024
@vincentwschau
Copy link
Contributor Author

@Mergifyio backport release/indexer/v7.x

Copy link
Contributor

mergify bot commented Oct 1, 2024

backport release/indexer/v7.x

✅ Backports have been created

vincentwschau added a commit that referenced this pull request Oct 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

2 participants