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

[OTE-755] Wrap wallet total volume roundtable queries in transaction #2309

Merged
merged 26 commits into from
Sep 20, 2024

Conversation

jerryfan01234
Copy link
Contributor

@jerryfan01234 jerryfan01234 commented Sep 20, 2024

Changelist

remove persistent cache update from wallet total volume update query
wrap wallet total volume roundtable queries in transaction
styling changes

Test Plan

[Describe how this PR was tested (if applicable)]

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

  • Bug Fixes

    • Improved error handling and logging for the wallet total volume update task.
  • New Features

    • Enhanced transaction management for wallet updates, ensuring atomic operations.
    • Updated logic for handling transaction IDs within wallet volume updates.
  • Refactor

    • Streamlined test cases for wallet total volume updates, consolidating functionality checks.
    • Clarified parameter structure in the updateInfo function documentation.
    • Updated variable names for clarity in test cases.
  • Tests

    • Optimized test logic for wallet total volume updates, including time simulation for accuracy.

Copy link

linear bot commented Sep 20, 2024

Copy link
Contributor

coderabbitai bot commented Sep 20, 2024

Walkthrough

The changes primarily involve refactoring the wallet and affiliate info logic in the indexer package. Key modifications include the removal of specific test cases, updates to method signatures, and enhancements to transaction handling. The documentation for functions has been clarified, and the logic for updating total volume has been streamlined. Overall, the updates focus on improving clarity, efficiency, and error handling across the codebase.

Changes

File Path Change Summary
indexer/packages/postgres/__tests__/stores/wallet-table.test.ts Removed tests related to persistent cache upserting; refactored wallet retrieval logic; updated variable names for clarity; optimized fill creation using Promise.all.
indexer/packages/postgres/src/stores/affiliate-info-table.ts Updated documentation for updateInfo function to clarify parameter type from an object to a number for txId.
indexer/packages/postgres/src/stores/wallet-table.ts Modified updateTotalVolume function to include an optional txId parameter; removed logic for persistent cache updates; enhanced transaction handling with a new variable for transactions.
indexer/services/roundtable/__tests__/tasks/update-wallet-total-volume.test.ts Enhanced test cases for walletTotalVolumeUpdateTask; updated test logic to simulate time and verify updates; consolidated tests for clarity; optimized fill creation with Promise.all.
indexer/services/roundtable/src/tasks/update-wallet-total-volume.ts Updated default last update time; added transaction management; improved error handling; modified logic for determining time windows for updates; enhanced logging; ensured wallet updates are part of the transaction.

Possibly related PRs

Suggested reviewers

  • affanv14
  • Christopher-Li

Poem

🐇 In the code where wallets dwell,
Changes made, all is well.
Tests refined, logic clear,
Transactions flow without fear.
A hop, a jump, through code we race,
Celebrating progress in our space! 🎉


Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 4d574a2 and 4db9ad7.

Files selected for processing (5)
  • indexer/packages/postgres/tests/stores/wallet-table.test.ts (5 hunks)
  • indexer/packages/postgres/src/stores/affiliate-info-table.ts (1 hunks)
  • indexer/packages/postgres/src/stores/wallet-table.ts (3 hunks)
  • indexer/services/roundtable/tests/tasks/update-wallet-total-volume.test.ts (5 hunks)
  • indexer/services/roundtable/src/tasks/update-wallet-total-volume.ts (2 hunks)
Files skipped from review as they are similar to previous changes (3)
  • indexer/packages/postgres/src/stores/affiliate-info-table.ts
  • indexer/packages/postgres/src/stores/wallet-table.ts
  • indexer/services/roundtable/src/tasks/update-wallet-total-volume.ts
Additional comments not posted (10)
indexer/packages/postgres/__tests__/stores/wallet-table.test.ts (5)

14-15: LGTM!

The imports are valid and used appropriately in the test file.


100-102: LGTM!

The variable renaming improves code clarity.


114-115: LGTM!

The variable renaming improves code clarity.


132-135: LGTM!

Using Promise.all to create orders concurrently is an efficient approach.


146-172: LGTM!

The changes to the fill creation logic, including the use of Promise.all for concurrent execution and the simplification of the subaccount ID usage, are well-implemented and improve the code efficiency and clarity.

indexer/services/roundtable/__tests__/tasks/update-wallet-total-volume.test.ts (5)

Line range hint 38-76: LGTM!

The changes to the test case improve clarity and accuracy:

  • The updated test case name clearly indicates that both totalVolume and persistent cache are being updated multiple times.
  • Creating a block before the task run simulates time passing, allowing for a more realistic test scenario.
  • Verifying the wallet's totalVolume and the persistent cache's totalVolumeUpdateTime after the task run ensures that both entities are updated correctly based on the simulated time.

79-95: LGTM!

The changes to the second task run in the test case are appropriate:

  • Creating a block before the second task run simulates time passing, allowing for a more realistic test scenario when there are no new fills.
  • Verifying that the wallet's totalVolume remains unchanged ensures that the task behaves correctly when there are no new fills.
  • Checking the persistent cache's totalVolumeUpdateTime after the second task run confirms that it is updated based on the simulated time, even in the absence of new fills.

105-120: LGTM!

The changes to the third task run in the test case are appropriate:

  • Creating a new fill and a block before the third task run simulates a realistic scenario where there is a new fill and time has passed since the previous task run.
  • Verifying that the wallet's totalVolume is incremented by the size of the new fill ensures that the task correctly updates the value when there are new fills.
  • Checking the persistent cache's totalVolumeUpdateTime after the third task run confirms that it is updated based on the simulated time when there are new fills.

127-161: LGTM!

The changes to the backfill test case improve efficiency and comprehensiveness:

  • Using Promise.all to create fills and set the persistent cache's totalVolumeUpdateTime concurrently optimizes the test setup.
  • Creating fills spanning a period of 2 weeks in the past and setting the persistent cache's totalVolumeUpdateTime to 3 weeks ago allows for a more thorough test of the backfill functionality.

177-215: LGTM!

The changes to the backfill test case for the first run improve control and efficiency:

  • Simulating a 1-week backfill from a specific reference date (2023-10-26T00:00:00Z) allows for a more controlled and predictable test of the backfill functionality on the first run.
  • Creating fills around the reference date using Promise.all optimizes the test setup.
  • Running the backfill task 7 times simulates a realistic scenario where the task is executed multiple times during roundtable runs.

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 (4)
indexer/packages/postgres/src/stores/affiliate-info-table.ts (1)

110-110: Consider adding a type for the txId parameter.

To improve type safety, consider adding a type for the txId parameter. For example:

type TransactionId = number;

export async function updateInfo(
  windowStartTs: string,
  windowEndTs: string, 
  txId: TransactionId | undefined = undefined,
) : Promise<void> {
  // ...
}
indexer/services/roundtable/src/tasks/update-wallet-total-volume.ts (1)

19-20: Typo in comment: "affilitate" should be "affiliate"

There's a typo in the comment on line 20. The word "affilitate" should be corrected to "affiliate".

Apply this diff to fix the typo:

-  // cache and affilitate info table are in sync.
+  // cache and affiliate info table are in sync.
indexer/packages/postgres/src/stores/wallet-table.ts (1)

Line range hint 133-163: Parameterize the SQL query to prevent SQL injection

Using string interpolation to insert windowStartTs and windowEndTs directly into the SQL query can lead to SQL injection vulnerabilities if these values are not properly sanitized. It's recommended to parameterize the query to enhance security.

Apply this diff to parameterize the query:

 const query = `
   WITH fills_total AS (
     -- Step 1: Calculate total volume for each subaccountId
     SELECT "subaccountId", SUM("price" * "size") AS "totalVolume"
     FROM fills
-    WHERE "createdAt" > '${windowStartTs}' AND "createdAt" <= '${windowEndTs}'
+    WHERE "createdAt" > ? AND "createdAt" <= ?
     GROUP BY "subaccountId"
   ),
   subaccount_volume AS (
     -- Step 2: Merge with subaccounts table to get the address
     SELECT s."address", f."totalVolume"
     FROM fills_total f
     JOIN subaccounts s
     ON f."subaccountId" = s."id"
   ),
   address_volume AS (
     -- Step 3: Group by address and sum the totalVolume
     SELECT "address", SUM("totalVolume") AS "totalVolume"
     FROM subaccount_volume
     GROUP BY "address"
   )
   -- Step 4: Left join the result with the wallets table and update the total volume
   UPDATE wallets
   SET "totalVolume" = COALESCE(wallets."totalVolume", 0) + av."totalVolume"
   FROM address_volume av
   WHERE wallets."address" = av."address";
 `;

- return transaction
-   ? knexPrimary.raw(query).transacting(transaction)
-   : knexPrimary.raw(query);
+ const bindings = [windowStartTs, windowEndTs];
+ return transaction
+   ? knexPrimary.raw(query, bindings).transacting(transaction)
+   : knexPrimary.raw(query, bindings);
indexer/services/roundtable/__tests__/tasks/update-wallet-total-volume.test.ts (1)

178-180: Clarify the number of backfill iterations for better understanding

In the comment, it mentions running the backfill task seven times, but it's not immediately clear why seven iterations are necessary. Consider explaining how this number relates to the date range or calculating it programmatically to enhance clarity.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 18f76cc and 4d574a2.

Files selected for processing (5)
  • indexer/packages/postgres/tests/stores/wallet-table.test.ts (5 hunks)
  • indexer/packages/postgres/src/stores/affiliate-info-table.ts (1 hunks)
  • indexer/packages/postgres/src/stores/wallet-table.ts (3 hunks)
  • indexer/services/roundtable/tests/tasks/update-wallet-total-volume.test.ts (5 hunks)
  • indexer/services/roundtable/src/tasks/update-wallet-total-volume.ts (2 hunks)
Additional comments not posted (6)
indexer/packages/postgres/__tests__/stores/wallet-table.test.ts (4)

14-15: LGTM!

The imports are valid and used appropriately in the test file.


100-102: LGTM!

The variable renaming improves code clarity. The logic to retrieve the wallet from the database is correct.


114-115: LGTM!

The variable renaming improves code clarity. The logic to retrieve the wallet from the database is correct.


Line range hint 132-172: LGTM!

The refactoring of the populateWalletSubaccountFill function improves code efficiency and readability:

  • Using Promise.all for concurrent execution of fill creation is a good optimization.
  • Simplifying the subaccount IDs to use single variables instead of an array enhances code clarity.

The logic and syntax of the function are correct.

indexer/packages/postgres/src/stores/affiliate-info-table.ts (1)

110-110: Verify the function signature change in the codebase.

The change to the updateInfo function signature looks good. It simplifies the function by directly accepting the txId parameter instead of an options object.

However, ensure that all function calls to updateInfo have been updated to match the new signature.

Run the following script to verify the function usage:

Verification successful

Function signature change verified successfully

The updateInfo function signature change has been successfully verified across the codebase. All calls to updateInfo are using the new signature correctly:

  • In indexer/services/roundtable/src/tasks/update-affiliate-info.ts, the function is called with all three parameters, including txId.
  • In the test file indexer/packages/postgres/__tests__/stores/affiliate-info-table.test.ts, multiple calls are made with only two parameters (windowStartTs and windowEndTs), omitting the optional txId parameter, which is valid according to the new signature.

The function definition in indexer/packages/postgres/src/stores/affiliate-info-table.ts matches the expected new signature:

export async function updateInfo(
  windowStartTs: string,
  windowEndTs: string,
  txId: number | undefined = undefined
) : Promise<void>
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify all function calls to `updateInfo` match the new signature.

# Test: Search for the function usage. Expect: Only occurrences of the new signature.
rg --type typescript -A 5 $'updateInfo'

Length of output: 73


Script:

#!/bin/bash
# Description: Verify all function calls to `updateInfo` match the new signature.

# Search for the function usage without specifying file type
echo "Searching for updateInfo function calls:"
rg -A 5 'updateInfo\s*\('

# Use ast-grep to search for function calls to updateInfo
echo "Using ast-grep to search for updateInfo function calls:"
ast-grep --lang typescript --pattern 'updateInfo($_)'

Length of output: 4825

indexer/services/roundtable/__tests__/tasks/update-wallet-total-volume.test.ts (1)

163-163: Simplify DateTime comparison by removing redundant conversions

Since backfillTime is already a DateTime object, you can compare it directly with currentDt without converting to an ISO string and back:

- while (backfillTime !== undefined && DateTime.fromISO(backfillTime.toISO()) < currentDt) {
+ while (backfillTime !== undefined && backfillTime < currentDt) {

This simplifies the code and improves readability.

Likely invalid or redundant comment.

@jerryfan01234 jerryfan01234 force-pushed the affiliates-roundtable-total-volume branch from 4d574a2 to 4db9ad7 Compare September 20, 2024 18:18
...defaultWallet,
totalVolume: '105', // 103 + 2
}));
});

it('Successfully upserts persistent cache', async () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

why delete this test?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The query to update total volume was modified to not update the persistent cache. The roundtable task calls persistent cache upsert within the same transaction as total volume update.

This pattern is what the affiliate info uses.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Persistent cache updating is checked in the roundtable task unit tests.

@jerryfan01234 jerryfan01234 merged commit 82598aa into main Sep 20, 2024
16 checks passed
@jerryfan01234 jerryfan01234 deleted the affiliates-roundtable-total-volume branch September 20, 2024 19:09
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