Skip to content

Conversation

@bmuddha
Copy link
Contributor

@bmuddha bmuddha commented Oct 24, 2025

This PR adds some metrics related to RPC methods processing and execution timings, which can provide useful insights into common usage patterns and areas of improvement.

Summary by CodeRabbit

  • New Features

    • Added runtime metrics for RPC requests, WebSocket subscriptions, transaction processing, failed transactions, and preflight behavior; added lightweight subscription guards.
    • Added human-friendly string helpers for JSON-RPC methods.
  • Refactor

    • Consolidated and relabeled metrics for finer-grained observability; replaced many legacy per-metric helpers with centralized metric vectors/timers.
  • Bug Fixes

    • Lowered severity of certain account/ensure failures from error to warn to reduce noisy logs.
  • Chores

    • Added metrics crate to the workspace and enabled an additional logging feature.

thlorenz and others added 30 commits September 17, 2025 19:08
- needs to be cleaned up to handle all program loaders
- unwrap needs to be removed as well
- covered in newer tests
- not repeatable due to hardcoded accounts
- testing obsolete behavior (non-eager cloning)
@bmuddha bmuddha requested a review from thlorenz October 24, 2025 12:52
@github-actions
Copy link

github-actions bot commented Oct 24, 2025

Manual Deploy Available

You can trigger a manual deploy of this PR branch to testnet:

Deploy to Testnet 🚀

Alternative: Comment /deploy on this PR to trigger deployment directly.

⚠️ Note: Manual deploy requires authorization. Only authorized users can trigger deployments.

Comment updated automatically when the PR is synchronized.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 24, 2025

Walkthrough

Adds a metrics crate to the workspace and instruments aperture and processor code with new label-aware metrics: per-RPC request timers/counters, transaction processing/skip metrics, ensure-accounts timers, WebSocket subscription guards, and a failed-transaction counter; also adds RPC method string helpers and small cleanup in account mutation.

Changes

Cohort / File(s) Summary
Metrics Infrastructure Refactor
magicblock-metrics/src/metrics/mod.rs
Replace many legacy metrics with new label-aware collectors (e.g., ENSURE_ACCOUNTS_TIME: HistogramVec, RPC_REQUEST_HANDLING_TIME: HistogramVec, TRANSACTION_PROCESSING_TIME, RPC_REQUESTS_COUNT: IntCounterVec, RPC_WS_SUBSCRIPTIONS_COUNT: IntGaugeVec, FAILED_TRANSACTIONS_COUNT); remove numerous old helpers and register the new metrics.
Workspace Dependencies
magicblock-aperture/Cargo.toml, magicblock-processor/Cargo.toml
Add magicblock-metrics = { workspace = true } dependency to both crates.
HTTP & WebSocket Dispatch Instrumentation
magicblock-aperture/src/server/http/dispatch.rs, magicblock-aperture/src/server/websocket/dispatch.rs
Increment RPC_REQUESTS_COUNT with method label and start RPC_REQUEST_HANDLING_TIME timer for each incoming request.
Request Processing Instrumentation
magicblock-aperture/src/requests/http/mod.rs, magicblock-aperture/src/requests/http/send_transaction.rs
Add ENSURE_ACCOUNTS_TIME timers (labels: "account", "multi-account", "transaction"), TRANSACTION_PROCESSING_TIME timer, and TRANSACTION_SKIP_PREFLIGHT counter; adjust log levels and add trace/warn logging around failures.
JSON-RPC Method Helpers
magicblock-aperture/src/requests/mod.rs
Add as_str() helpers: JsonRpcHttpMethod::as_str() and JsonRpcWsMethod::as_str() mapping enum variants to camelCase names for metric labeling.
Subscription Tracking
magicblock-aperture/src/state/subscriptions.rs
Add pub(crate) struct SubMetricGuard that increments RPC_WS_SUBSCRIPTIONS_COUNT on creation and decrements on drop; instantiate guards for account/program/logs/slot subscriptions and drop them on cleanup.
Failed Transaction Tracking
magicblock-processor/src/executor/processing.rs
Increment FAILED_TRANSACTIONS_COUNT when a transaction fails to load during execution.
Removed Metric Calls / Small Cleanup
programs/magicblock/src/mutate_accounts/account_mod_data.rs
Remove Neg import and delete active-data-mods metric update; simplify get_data to remove metric side-effects.
Workspace Log Feature Toggle
Cargo.toml
Change workspace log dependency to enable release_max_level_info feature: log = { version = "0.4.20", features = ["release_max_level_info"] }.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Client
    participant HttpDispatcher
    participant RequestHandler
    participant AccountsEnsurer
    participant TxProcessor
    note over HttpDispatcher: Metrics: RPC_REQUESTS_COUNT, RPC_REQUEST_HANDLING_TIME
    Client->>HttpDispatcher: send RPC request (method)
    HttpDispatcher->>RPC: RPC_REQUESTS_COUNT.inc(method)
    HttpDispatcher->>RPC: RPC_REQUEST_HANDLING_TIME.start(method)
    HttpDispatcher->>RequestHandler: dispatch request
    alt send_transaction
        RequestHandler->>TxProcessor: prepare_transaction(...)
        TxProcessor->>RPC: TRANSACTION_PROCESSING_TIME.start()
        alt skip_preflight
            TxProcessor->>RPC: TRANSACTION_SKIP_PREFLIGHT.inc()
        end
        TxProcessor->>AccountsEnsurer: ensure transaction accounts
        AccountsEnsurer->>RPC: ENSURE_ACCOUNTS_TIME.start("transaction")
        AccountsEnsurer-->>TxProcessor: ensured / warn on failure
        TxProcessor-->>RequestHandler: result
    else account read
        RequestHandler->>AccountsEnsurer: read_account_with_ensure(...)
        AccountsEnsurer->>RPC: ENSURE_ACCOUNTS_TIME.start("account"/"multi-account")
        AccountsEnsurer-->>RequestHandler: ensured / warn on failure
    end
    RequestHandler-->>HttpDispatcher: response
    HttpDispatcher->>RPC: RPC_REQUEST_HANDLING_TIME.observe_finish()
Loading
sequenceDiagram
    autonumber
    participant Client
    participant WsDispatcher
    participant SubscriptionManager
    participant RPC
    note over WsDispatcher: SubMetricGuard increments/decrements RPC_WS_SUBSCRIPTIONS_COUNT
    Client->>WsDispatcher: subscribe(account/program/logs/slot)
    WsDispatcher->>SubscriptionManager: create subscription
    SubscriptionManager->>RPC: RPC_WS_SUBSCRIPTIONS_COUNT.inc(label)  -- via SubMetricGuard::new
    SubscriptionManager-->>WsDispatcher: subscription id
    Client->>WsDispatcher: unsubscribe(id)
    WsDispatcher->>SubscriptionManager: remove subscription
    SubscriptionManager->>RPC: RPC_WS_SUBSCRIPTIONS_COUNT.dec(label)  -- via SubMetricGuard drop
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

  • Pay extra attention to: magicblock-metrics/src/metrics/mod.rs (API surface and registrations), instrumentation placement in send_transaction.rs and http/mod.rs (timers/counters and log-level changes), and subscription guard lifecycle in state/subscriptions.rs.

Possibly related PRs

Suggested reviewers

  • GabrielePicco
  • thlorenz
  • Dodecahedr0x

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "Rpc/execution related metrics" directly aligns with the primary objective and changes in the pull request. The changeset consistently adds new metrics for tracking RPC method processing, WebSocket subscriptions, transaction execution, and account operations across multiple files in the magicblock-metrics, magicblock-aperture, and magicblock-processor crates. The title is concise, specific, and clearly communicates the core purpose of the PR to someone scanning the commit history without including unnecessary noise or vague terminology.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bmuddha/feat/rpc-metrics

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 72890fb and 5127e86.

📒 Files selected for processing (5)
  • Cargo.toml (1 hunks)
  • magicblock-aperture/src/requests/http/mod.rs (4 hunks)
  • magicblock-aperture/src/requests/http/send_transaction.rs (3 hunks)
  • magicblock-aperture/src/state/subscriptions.rs (7 hunks)
  • magicblock-metrics/src/metrics/mod.rs (3 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-21T14:00:54.642Z
Learnt from: bmuddha
PR: magicblock-labs/magicblock-validator#578
File: magicblock-aperture/src/requests/websocket/account_subscribe.rs:18-27
Timestamp: 2025-10-21T14:00:54.642Z
Learning: In magicblock-aperture account_subscribe handler (src/requests/websocket/account_subscribe.rs), the RpcAccountInfoConfig fields data_slice, commitment, and min_context_slot are currently ignored—only encoding is applied. This is tracked as technical debt in issue #579: https://github.com/magicblock-labs/magicblock-validator/issues/579

Applied to files:

  • magicblock-aperture/src/state/subscriptions.rs
🧬 Code graph analysis (4)
magicblock-aperture/src/requests/http/mod.rs (1)
magicblock-aperture/src/requests/http/get_multiple_accounts.rs (1)
  • pubkeys (31-39)
magicblock-aperture/src/state/subscriptions.rs (2)
magicblock-aperture/src/server/websocket/dispatch.rs (2)
  • new (49-61)
  • drop (155-161)
magicblock-aperture/src/server/websocket/connection.rs (1)
  • new (66-84)
magicblock-aperture/src/requests/http/send_transaction.rs (1)
magicblock-aperture/src/requests/mod.rs (1)
  • params (22-26)
magicblock-metrics/src/metrics/mod.rs (1)
magicblock-aperture/src/state/subscriptions.rs (2)
  • new (338-351)
  • new (406-409)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: run_make_ci_lint
  • GitHub Check: run_make_ci_test
  • GitHub Check: run_make_ci_format
  • GitHub Check: run_make_ci_test
🔇 Additional comments (9)
Cargo.toml (1)

94-94: LGTM! Good performance optimization.

Adding release_max_level_info to the log dependency ensures that debug and trace logs are compiled out in release builds, reducing binary size and runtime overhead.

magicblock-aperture/src/requests/http/send_transaction.rs (1)

1-56: LGTM! Clean metrics instrumentation.

The transaction processing metrics are well-placed:

  • Timer guards the entire request lifecycle via RAII
  • Skip-preflight counter correctly increments only when config.skip_preflight is true
  • Log levels are appropriate (warn for failures, trace for flow)
magicblock-aperture/src/requests/http/mod.rs (4)

13-13: LGTM! Consistent metrics instrumentation.

The ENSURE_ACCOUNTS_TIME metric is used consistently across all three ensure methods (account, multi-account, transaction) with appropriate labels to distinguish operation types.


105-116: LGTM! Appropriate timing and logging.

The single-account path correctly:

  • Times the ensure operation with label "account"
  • Uses warn! for failures (appropriate for non-critical recoverable errors)

122-143: LGTM! Multi-account instrumentation looks good.

The multi-account path follows the same pattern with label "multi-account" and includes a helpful trace log.


193-221: LGTM! Transaction account instrumentation is consistent.

The transaction-account path uses label "transaction" and maintains consistent error handling with the other ensure methods.

magicblock-aperture/src/state/subscriptions.rs (1)

403-418: SubMetricGuard implementation is clean.

The RAII pattern for metric increment/decrement is well-implemented. The guard correctly increments on creation and decrements on drop.

magicblock-metrics/src/metrics/mod.rs (2)

117-166: LGTM! New RPC metrics are well-structured.

The new metrics provide good visibility into RPC operations:

  • ENSURE_ACCOUNTS_TIME with "kind" label distinguishes account/multi-account/transaction paths
  • TRANSACTION_PROCESSING_TIME tracks end-to-end transaction handling
  • RPC_REQUEST_HANDLING_TIME and RPC_REQUESTS_COUNT with "name" label enable per-method analysis
  • RPC_WS_SUBSCRIPTIONS_COUNT with "name" label tracks active WebSocket subscriptions
  • Histogram bucket ranges are appropriate (10μs to 9s)

226-232: LGTM! New metrics properly registered.

All new metrics are correctly registered with the Prometheus registry.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
magicblock-aperture/src/state/subscriptions.rs (2)

109-121: Avoid metric leaks on shutdown: move guard to SubscriptionHandle (RAII), not async cleanup

Decrementing via drop(metric) inside a spawned cleanup task can be skipped during runtime shutdown, leaving RPC_WS_SUBSCRIPTIONS_COUNT over-reported. Prefer owning the guard on SubscriptionHandle so the gauge decrements synchronously on handle drop; keep the async DB cleanup as-is.

Apply these changes:

@@ pub(crate) async fn subscribe_to_account(...)
-        let metric = SubMetricGuard::new("account");
+        let metric = SubMetricGuard::new("account");
@@
-            if entry.remove_subscriber(conid, &encoder) {
+            if entry.remove_subscriber(conid, &encoder) {
                 let _ = entry.remove();
             }
-            drop(metric)
         };
-        let cleanup = CleanUp(Some(Box::pin(callback)));
-        SubscriptionHandle { id, cleanup }
+        let cleanup = CleanUp(Some(Box::pin(callback)));
+        SubscriptionHandle { id, cleanup, _metric: Some(metric) }

And update the handle definition (see Lines 376-379).


372-379: Store metric in SubscriptionHandle to guarantee gauge decrement on drop

The metric is currently created and incremented at each subscription constructor (lines 109, 151, 219, 248) but only decremented when the async cleanup task runs. If that task fails or doesn't run, the gauge leaks. Add _metric: Option<SubMetricGuard> to the struct and update all 4 constructors (lines 123, 162, 225, 254) to include it—this ensures synchronous decrement when the handle is dropped, even if async cleanup fails.

 pub(crate) struct SubscriptionHandle {
     pub(crate) id: SubscriptionID,
     pub(crate) cleanup: CleanUp,
+    _metric: Option<SubMetricGuard>,
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cb55824 and 4d28188.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (11)
  • magicblock-aperture/Cargo.toml (1 hunks)
  • magicblock-aperture/src/requests/http/mod.rs (4 hunks)
  • magicblock-aperture/src/requests/http/send_transaction.rs (3 hunks)
  • magicblock-aperture/src/requests/mod.rs (1 hunks)
  • magicblock-aperture/src/server/http/dispatch.rs (2 hunks)
  • magicblock-aperture/src/server/websocket/dispatch.rs (2 hunks)
  • magicblock-aperture/src/state/subscriptions.rs (7 hunks)
  • magicblock-metrics/src/metrics/mod.rs (3 hunks)
  • magicblock-processor/Cargo.toml (1 hunks)
  • magicblock-processor/src/executor/processing.rs (2 hunks)
  • programs/magicblock/src/mutate_accounts/account_mod_data.rs (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-21T14:00:54.642Z
Learnt from: bmuddha
PR: magicblock-labs/magicblock-validator#578
File: magicblock-aperture/src/requests/websocket/account_subscribe.rs:18-27
Timestamp: 2025-10-21T14:00:54.642Z
Learning: In magicblock-aperture account_subscribe handler (src/requests/websocket/account_subscribe.rs), the RpcAccountInfoConfig fields data_slice, commitment, and min_context_slot are currently ignored—only encoding is applied. This is tracked as technical debt in issue #579: https://github.com/magicblock-labs/magicblock-validator/issues/579

Applied to files:

  • magicblock-aperture/src/state/subscriptions.rs
🧬 Code graph analysis (3)
magicblock-aperture/src/requests/http/send_transaction.rs (1)
magicblock-aperture/src/requests/mod.rs (1)
  • params (22-26)
magicblock-aperture/src/state/subscriptions.rs (2)
magicblock-aperture/src/server/websocket/dispatch.rs (1)
  • new (50-62)
magicblock-aperture/src/server/websocket/connection.rs (1)
  • new (66-84)
magicblock-metrics/src/metrics/mod.rs (1)
magicblock-aperture/src/state/subscriptions.rs (2)
  • new (338-351)
  • new (406-409)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: run_make_ci_test
  • GitHub Check: run_make_ci_lint
  • GitHub Check: run_make_ci_test
  • GitHub Check: run_make_ci_format
🔇 Additional comments (21)
programs/magicblock/src/mutate_accounts/account_mod_data.rs (1)

74-76: LGTM! Clean refactor aligning with centralized metrics.

The simplification to a single-line expression is idiomatic and preserves the original behavior. The removal of local metrics updates aligns with the broader PR objective of centralizing metrics in the magicblock-metrics crate.

magicblock-aperture/Cargo.toml (1)

36-36: LGTM! Dependency addition supports metrics instrumentation.

The addition of the magicblock-metrics workspace dependency enables the aperture crate to instrument HTTP/WebSocket dispatch and request processing with the new centralized metrics system.

magicblock-processor/src/executor/processing.rs (2)

11-11: LGTM! Import supports transaction failure tracking.

The import of FAILED_TRANSACTIONS_COUNT enables instrumentation of transaction load failures in the executor.


58-58: LGTM! Metric correctly placed in error path.

The increment of FAILED_TRANSACTIONS_COUNT is appropriately positioned after committing the failed transaction and before returning, accurately tracking transactions that fail to load.

magicblock-aperture/src/requests/mod.rs (2)

91-150: LGTM! Comprehensive method-to-string mapping for HTTP methods.

The as_str implementation provides consistent camelCase labels for all HTTP RPC methods, supporting metrics instrumentation. All enum variants are covered with correct mappings.


152-167: LGTM! Comprehensive method-to-string mapping for WebSocket methods.

The as_str implementation provides consistent camelCase labels for all WebSocket RPC methods, supporting metrics instrumentation. All enum variants are covered with correct mappings.

magicblock-processor/Cargo.toml (1)

19-19: LGTM! Dependency addition supports transaction failure metrics.

The addition of the magicblock-metrics workspace dependency enables the processor crate to track failed transactions using FAILED_TRANSACTIONS_COUNT.

magicblock-aperture/src/server/http/dispatch.rs (2)

9-11: LGTM! Imports enable HTTP request metrics.

The imports of RPC_REQUESTS_COUNT and RPC_REQUEST_HANDLING_TIME support per-method request tracking and latency measurement in the HTTP dispatch path.


117-121: LGTM! Well-positioned metrics instrumentation.

The metrics are correctly placed at the start of the process method:

  • Request count incremented immediately with the method label
  • Timer started using RAII pattern (automatically records on drop)
  • Both metrics use the same method label for consistent correlation
magicblock-aperture/src/server/websocket/dispatch.rs (2)

20-21: LGTM! Import enables WebSocket request counting.

The import of RPC_REQUESTS_COUNT supports per-method request tracking in the WebSocket dispatch path.


70-72: LGTM! Consistent WebSocket request metrics.

The counter increment is appropriately placed before request handling, using the method label for consistent tracking across HTTP and WebSocket transports.

magicblock-aperture/src/requests/http/send_transaction.rs (4)

1-4: LGTM! Imports enable transaction metrics and logging.

The imports support:

  • Enhanced error logging via warn!
  • Transaction processing time measurement
  • Preflight skip tracking

21-21: LGTM! Timer correctly positioned for full request duration.

The TRANSACTION_PROCESSING_TIME timer is started at function entry and will automatically record the full processing duration when dropped (RAII pattern).


31-31: LGTM! Enhanced error observability.

The inspect_err pattern adds warning-level logging for transaction preparation failures without affecting the error propagation flow.


46-46: LGTM! Preflight skip tracking.

The metric increment correctly tracks when transactions bypass preflight validation, providing valuable insights into transaction submission patterns.

magicblock-aperture/src/requests/http/mod.rs (2)

105-108: Good: Low-overhead timing instrumentation

Using ENSURE_ACCOUNTS_TIME.start_timer() scoped via _timer is correct; drop records duration reliably.


196-199: Metrics registration verified at startup

Metrics are correctly registered early in the initialization chain. The try_start_metrics_service() function in magicblock-api/src/magic_validator.rs:216 is called during validator startup via MagicValidator::try_from_config(), which ensures metrics::register() executes before the metrics service spawns. This timing guarantees observations are available for export.

magicblock-aperture/src/state/subscriptions.rs (2)

18-18: WS subscriptions metric import

Import looks correct; label cardinality constrained by &'static str usage.


96-124: Note: account_subscribe config fields still ignored (tracking issue #579)

Instrumentation doesn’t affect behavior; the known omission (data_slice, commitment, min_context_slot ignored) remains. Just a reminder; no change requested here.

Based on learnings

magicblock-metrics/src/metrics/mod.rs (2)

114-168: Metrics additions and registration look solid

New Histogram/Vec and Counter/Vec definitions use consistent buckets; all are registered.

Also applies to: 226-233


193-234: Verified: metrics::register() is invoked during startup

The call chain is confirmed: magicblock-validator/src/main.rs:97 calls MagicValidator::try_from_config(), which in turn calls try_start_metrics_service() at magicblock-api/src/magic_validator.rs:216, which immediately invokes metrics::register() at magicblock-metrics/src/service.rs:20. Collectors are properly exported under the mbv registry during validator initialization.

Comment on lines 248 to 252
let metric = SubMetricGuard::new("slot");
let callback = async move {
slot.write().txs.remove(&conid);
drop(metric)
};
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 | 🟠 Major

Same fix for slot subscriptions

Store the guard on the handle; remove drop(metric) in the callback.

-        let metric = SubMetricGuard::new("slot");
+        let metric = SubMetricGuard::new("slot");
@@
-            slot.write().txs.remove(&conid);
-            drop(metric)
+            slot.write().txs.remove(&conid);
         };
-        let cleanup = CleanUp(Some(Box::pin(callback)));
-        SubscriptionHandle { id, cleanup }
+        let cleanup = CleanUp(Some(Box::pin(callback)));
+        SubscriptionHandle { id, cleanup, _metric: Some(metric) }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In magicblock-aperture/src/state/subscriptions.rs around lines 248 to 252, the
SubMetricGuard created for "slot" is dropped inside the async callback which
prematurely ends the metric; instead store the guard on the subscription handle
so its lifetime matches the subscription and remove the explicit drop(metric)
from the callback; modify the subscription handle (or its enclosing struct) to
hold the SubMetricGuard for the slot subscription and move/assign the guard into
that handle when creating the callback, leaving the callback to only perform
slot.write().txs.remove(&conid).

Copy link
Contributor

@thlorenz thlorenz left a comment

Choose a reason for hiding this comment

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

Looks good in general, just some nits we should address/clarify.

Also I feel sorry for @lucacillario since he'll have to update all the dashboards 😓

Copy link
Contributor

@thlorenz thlorenz left a comment

Choose a reason for hiding this comment

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

LGTM, but maybe address some of the coderabbit comments before merging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants