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-456] FNS x OE: stage FinalizeBlock events and emit in Precommit #2253

Merged
merged 5 commits into from
Sep 16, 2024

Conversation

teddyding
Copy link
Contributor

@teddyding teddyding commented Sep 13, 2024

Changelist

Store order fill stream events in a transient store during block processing
Do the following in Precommit, after consensus agrees on a block.

  • Send onchain order fills
  • Send onchain subacount updates
  • Send OrderbookUpdates to synchronize optimistic fills in our local ops queue.

Test Plan

(TODO) FNS integration testing on dev

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

Here are the updated release notes based on the provided changes:

  • New Features

    • Added functionality to stage and retrieve events related to order fills and subaccount updates during the block finalization process.
    • Introduced methods to handle batch streaming of updates after a block is finalized, ensuring synchronization between on-chain state and off-chain operations.
  • Improvements

    • Enhanced the streaming manager component to better manage and respond to events related to block finalization.
    • Streamlined the handling of finalized updates for order fills and subaccounts, improving performance and maintainability.
  • Chores

    • Added new constants and metrics for better monitoring and management of streaming events.

Copy link
Contributor

coderabbitai bot commented Sep 13, 2024

Warning

Rate limit exceeded

@teddyding has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 12 minutes and 26 seconds before requesting another review.

How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

Commits

Files that changed from the base of the PR and between ceba058 and 840bbd7.

Walkthrough

The changes introduce new interfaces and message types to enhance event handling during the FinalizeBlock process in a blockchain system. Key additions include the StagedFinalizeBlockEvent interface and related methods for encoding and decoding events. Modifications to the streaming manager support staging and streaming updates for order fills and subaccount updates. Additionally, constants related to streaming and gRPC metrics are defined to improve monitoring capabilities. Overall, these changes streamline the management of events and updates within the application.

Changes

Files Change Summary
indexer/packages/v4-protos/src/codegen/dydxprotocol/... Added interfaces and methods for StagedFinalizeBlockEvent to enhance structured event handling.
proto/dydxprotocol/clob/streaming.proto Introduced StagedFinalizeBlockEvent message type with a oneof construct for event encapsulation.
protocol/app/app.go Integrated a new streaming manager component into the application initialization process.
protocol/lib/metrics/constants.go, protocol/lib/metrics/metric_keys.go Added constants for streaming and gRPC metrics related to finalize block updates.
protocol/streaming/constants.go Defined constants for managing streaming events, including transient store keys and event counts.
protocol/streaming/full_node_streaming_manager.go Enhanced streaming manager with methods for staging and retrieving finalize block events.
protocol/streaming/noop_streaming_manager.go Added placeholder methods for future streaming functionalities related to block finalization.
protocol/streaming/types/interface.go Updated FullNodeStreamingManager interface with new methods for event staging and streaming.
protocol/x/clob/abci.go Implemented Precommit function for managing streaming updates conditionally based on the streaming manager state.
protocol/x/clob/keeper/grpc_stream_finalize_block.go Added functions for handling updates related to order fills and streaming updates post-finalization.
protocol/x/clob/keeper/process_operations.go, protocol/x/subaccounts/keeper/subaccount.go Simplified update handling by replacing method calls with direct staging of updates.

Sequence Diagram

sequenceDiagram
    participant A as Client
    participant B as FullNodeStreamingManager
    participant C as Keeper
    participant D as OffchainUpdates

    A->>C: Request Finalize Block
    C->>B: StageFinalizeBlockFill
    C->>B: StageFinalizeBlockSubaccountUpdate
    B->>D: StreamBatchUpdatesAfterFinalizeBlock
    D-->>A: Send Updates
Loading

🐰 In the meadow where bunnies play,
New changes hop in, brightening the day!
With events staged and updates in line,
The code now dances, oh so fine!
Stream and sync, a joyful cheer,
For every hop brings progress near! 🥕✨


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 generate interesting stats about this repository and render them as a table.
    -- @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

linear bot commented Sep 13, 2024

Copy link
Contributor

mergify bot commented Sep 13, 2024

⚠️ The sha of the head commit of this PR conflicts with #1726. Mergify cannot evaluate rules on this PR. ⚠️


finalizedFills, finalizedSubaccountUpdates := sm.getStagedEventsFromFinalizeBlock(ctx)

// TODO(CT-1190): Stream below in a single batch.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will do this in a follow-up PR

Copy link
Contributor

Choose a reason for hiding this comment

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

probably good to just obtain the lock and manually send the updates through in a single batch bypassing the cache

@teddyding teddyding marked this pull request as ready for review September 13, 2024 16:03
@teddyding teddyding requested a review from a team as a code owner September 13, 2024 16:03
@@ -198,6 +198,15 @@ message StreamUpdate {
}
}

// StagedFinalizeBlockEvent is an event staged during `FinalizeBlock`.
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we add context to this comment to explain staging more and why it is necessary? + this is not exposed externally, so maybe move it out of query.proto?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will add more documentation in code as opposed to proto file

ctx sdk.Context,
eventBytes []byte,
) {
noGasCtx := ctx.WithGasMeter(ante_types.NewFreeInfiniteGasMeter())
Copy link
Contributor

Choose a reason for hiding this comment

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

for my understanding why do we need to add gas meter to ctx? because we write to state?

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 any read/write to store incur the gas meter. We do the same thing for indexer

) {
// Flush all pending updates, since we want the onchain updates to arrive in a batch.
sm.FlushStreamUpdates()

Copy link
Contributor

@jonfung-dydx jonfung-dydx Sep 13, 2024

Choose a reason for hiding this comment

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

Thinking out loud, we don't need to sm.Lock() this right? CheckTx transactions won't run in parallel when we are finalizing the block so the cache couldn't possibly get new updates when we are calling this function? It could be the case that we flush on the timer but it should be fine if cache is empty since we flush it first

EDIT: i see that the three sm.SendOrderbookUpdates() functions already obtain the lock before adding to the cache, i think it's fine

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 agreed. In the follow-up PR I will obtain the lock around sending a batch

localValidatorOperationsQueue, _ := k.MemClob.GetOperationsToReplay(ctx)
fetchOrdersInvolvedInOpQueue(localValidatorOperationsQueue)
orderIdsFromLocal := fetchOrdersInvolvedInOpQueue(
localValidatorOperationsQueue,
Copy link
Contributor

@jonfung-dydx jonfung-dydx Sep 13, 2024

Choose a reason for hiding this comment

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

Think we need to monitor this to make sure the removal of

		orderIdsFromProposed := fetchOrdersInvolvedInOpQueue(
			operations,
		)

will not break correctness

)

// Returns the order updates needed to update the fill amount for the orders
// from local ops queue, according to the latest onchain state (after FinalizeBlock).
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// from local ops queue, according to the latest onchain state (after FinalizeBlock).
// from local ops queue, according to the latest onchain state (after FinalizeBlock).
// Effectively reverts the optimistic fill amounts removed from the CheckTx to DeliverTx state transition.

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 976ba07 and ceba058.

Files ignored due to path filters (1)
  • protocol/x/clob/types/streaming.pb.go is excluded by !**/*.pb.go
Files selected for processing (15)
  • indexer/packages/v4-protos/src/codegen/dydxprotocol/bundle.ts (2 hunks)
  • indexer/packages/v4-protos/src/codegen/gogoproto/bundle.ts (1 hunks)
  • indexer/packages/v4-protos/src/codegen/google/bundle.ts (1 hunks)
  • proto/dydxprotocol/clob/streaming.proto (1 hunks)
  • protocol/app/app.go (4 hunks)
  • protocol/lib/metrics/constants.go (1 hunks)
  • protocol/lib/metrics/metric_keys.go (1 hunks)
  • protocol/streaming/constants.go (1 hunks)
  • protocol/streaming/full_node_streaming_manager.go (6 hunks)
  • protocol/streaming/noop_streaming_manager.go (1 hunks)
  • protocol/streaming/types/interface.go (1 hunks)
  • protocol/x/clob/abci.go (1 hunks)
  • protocol/x/clob/keeper/grpc_stream_finalize_block.go (1 hunks)
  • protocol/x/clob/keeper/process_operations.go (3 hunks)
  • protocol/x/subaccounts/keeper/subaccount.go (1 hunks)
Files skipped from review due to trivial changes (2)
  • indexer/packages/v4-protos/src/codegen/gogoproto/bundle.ts
  • indexer/packages/v4-protos/src/codegen/google/bundle.ts
Files skipped from review as they are similar to previous changes (7)
  • protocol/app/app.go
  • protocol/lib/metrics/constants.go
  • protocol/lib/metrics/metric_keys.go
  • protocol/streaming/constants.go
  • protocol/streaming/noop_streaming_manager.go
  • protocol/x/clob/abci.go
  • protocol/x/subaccounts/keeper/subaccount.go
Additional context used
buf
proto/dydxprotocol/clob/streaming.proto

4-4: import "dydxprotocol/subaccounts/streaming.proto": file does not exist

(COMPILE)

Additional comments not posted (23)
proto/dydxprotocol/clob/streaming.proto (1)

10-16: LGTM!

The new message type StagedFinalizeBlockEvent is well-defined and serves a clear purpose of representing events staged during the FinalizeBlock process. The use of oneof for the event field allows for flexibility in the type of event that can be contained within the message.

protocol/x/clob/keeper/grpc_stream_finalize_block.go (3)

15-29: LGTM!

The function logic for retrieving updates to sync the local operations queue is correct.

As mentioned in the previous review, please monitor the removal of the following code segment to ensure it does not break correctness:

orderIdsFromProposed := fetchOrdersInvolvedInOpQueue(
  operations,
)

37-42: As mentioned in the previous review, please avoid using the telemetry module.


34-50: LGTM!

The function logic for streaming batch updates after a block is finalized is correct. The documentation has been improved and accurately describes the purpose of the function.

protocol/streaming/types/interface.go (4)

53-56: LGTM!

The StageFinalizeBlockFill method is a valid addition to the FullNodeStreamingManager interface. It follows the naming conventions and has appropriate parameters for staging a fill event related to a finalized block.


57-60: LGTM!

The StageFinalizeBlockSubaccountUpdate method is a valid addition to the FullNodeStreamingManager interface. It follows the naming conventions and has appropriate parameters for staging a subaccount update event related to a finalized block.


61-63: LGTM!

The GetStagedFinalizeBlockEvents method is a valid addition to the FullNodeStreamingManager interface. It follows the naming conventions and has an appropriate return type for retrieving a list of staged events related to finalized blocks.


65-69: LGTM!

The StreamBatchUpdatesAfterFinalizeBlock method is a valid addition to the FullNodeStreamingManager interface. It follows the naming conventions and has appropriate parameters for streaming batch updates after a block is finalized, synchronizing updates with the local operations queue, and utilizing a mapping of perpetual IDs to CLOB pair IDs.

indexer/packages/v4-protos/src/codegen/dydxprotocol/bundle.ts (3)

39-40: LGTM!

The addition of new imports for clob/streaming, clob/tx, and various submodules under daemons/ is properly done. The imports follow the existing naming conventions, are placed in the correct order, and are grouped with related imports.

Also applies to: 41-47


44-123: LGTM!

The renaming of existing imports by incrementing their suffixed numbers is consistently applied across all affected imports. The renaming is necessary to maintain uniqueness due to the addition of new imports. It does not introduce any naming conflicts or inconsistencies.


Line range hint 191-404: LGTM!

The updates to the exports within the dydxprotocol namespace to include the newly added and renamed imports are consistently applied across all affected exports. The updates are necessary to ensure that the newly added and renamed imports are properly exported and accessible. The existing structure and organization of the exports are maintained.

protocol/streaming/full_node_streaming_manager.go (10)

381-387: LGTM!

The function correctly retrieves the count of staged events from the transient store and handles the case when the count doesn't exist.


390-403: LGTM!

The function correctly stages the subaccount update event in the transient store during FinalizeBlock.


410-423: LGTM!

The function correctly stages the fill event in the transient store during FinalizeBlock.


425-436: LGTM!

The function correctly retrieves all staged events from the transient store by iterating over the count and unmarshaling each event.


439-445: LGTM!

The function correctly retrieves all staged events from the transient store using a new context with an infinite gas meter to avoid charging gas.


447-461: LGTM!

The function correctly stages an event in the transient store by incrementing the count, storing the count, and storing the event bytes in a prefix store using the count as the key.


809-809: LGTM!

Flushing all pending updates before streaming the batch updates ensures that the onchain updates arrive in a batch.


838-871: LGTM!

The function correctly retrieves staged events from FinalizeBlock, categorizes them into finalized fills and subaccount updates, and sets appropriate metrics.


Line range hint 873-933: LGTM!

The function correctly initializes new streams with orderbook and subaccount snapshots, handling the case when the subaccount snapshot may not exist due to a race condition. It also handles the snapshot block interval logic correctly.


Line range hint 97-136: LGTM!

The constructor correctly initializes the FullNodeStreamingManagerImpl instance with the provided parameters, including the new streamingManagerTransientStoreKey parameter. The usage of the transient store key is consistent with the newly added functions.

protocol/x/clob/keeper/process_operations.go (2)

Line range hint 533-547: LGTM!

The changes simplify the logic related to gRPC streaming and order book updates by staging the updates using the streaming manager's StageFinalizeBlockFill method. This approach potentially improves performance and maintainability by streamlining the management of updates without relying on the MemClob state.


652-656: LGTM!

The changes simplify the logic related to gRPC streaming and order book updates for liquidation matches by staging the updates using the streaming manager's StageFinalizeBlockFill method. This approach is consistent with the changes made in PersistMatchOrdersToState and potentially improves performance and maintainability by streamlining the management of updates without relying on the MemClob state.

syntax = "proto3";
package dydxprotocol.clob;

import "dydxprotocol/subaccounts/streaming.proto";
Copy link
Contributor

Choose a reason for hiding this comment

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

Fix the missing import file.

The import statement import "dydxprotocol/subaccounts/streaming.proto"; references a file that does not exist, according to the static analysis hints. This could lead to compilation errors.

Please ensure that the file dydxprotocol/subaccounts/streaming.proto exists in the specified location. If you need assistance resolving this issue, I'd be happy to help. Let me know if you'd like me to open a GitHub issue to track this task.

Tools
buf

4-4: import "dydxprotocol/subaccounts/streaming.proto": file does not exist

(COMPILE)

@teddyding teddyding merged commit 025cc85 into main Sep 16, 2024
39 checks passed
@teddyding teddyding deleted the td/fns-oe-refactored branch September 16, 2024 16:41
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