Skip to content

Wire block-merging re-enable into the admin portal - #513

Open
0w3n-d wants to merge 4 commits into
od/merged_block_sim_step3from
od/merged_block_sim_step4
Open

Wire block-merging re-enable into the admin portal#513
0w3n-d wants to merge 4 commits into
od/merged_block_sim_step3from
od/merged_block_sim_step4

Conversation

@0w3n-d

@0w3n-d 0w3n-d commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator

Issue: #500 (step 4 of 4 -- last step)

Base branch: od/merged_block_sim_step3 (step 3, #508) -- stacked per CONTRIBUTING.md, not yet merged. Diff will shrink as earlier steps merge and this retargets down toward develop.

What this PR does

Wires the relay's /admin/v1/block-merging route (added in #502) into the admin portal, end to end, mirroring the existing kill-switch pattern exactly (this crate had zero bespoke proxy wrapping for it before -- confirmed no generic admin-route proxy exists in crates/admin, so this needed the same bespoke client method + handler + route as every other admin action here):

  • RelayAdminClient gains block_merging_enabled on RelayAdminStatus and a set_block_merging(enabled) method.
  • handlers.rs gains enable_block_merging/disable_block_merging (proxying to the relay) and overview()/OverviewResponse gain block_merging_enabled: Option<bool> (None when the relay admin API is unreachable, same convention as kill_switch_enabled).
  • service.rs gains the /api/v1/actions/block-merging route.
  • Frontend: a "Block merging" toggle in Settings (two buttons + two ConfirmDialogs, mirroring the kill-switch block) and a status tile on the Overview page.

What this PR deliberately does not do

Nothing else changes in the disable/re-enable logic itself (#508 already covers when/why merging gets disabled) -- this is purely portal wiring so an admin doesn't have to hit the relay's raw HTTP API by hand to re-enable it.

Tests

Written first, reviewed, then implemented against. This crate (helix-admin) has no test coverage today -- enable_kill_switch/disable_kill_switch and siblings are all untested. Rather than add a new dependency (e.g. httpmock) to test RelayAdminClient, a small in-process axum server standing in for the relay's admin API (axum is already a dependency) is spun up on an OS-assigned ephemeral port:

  • set_block_merging_toggles_and_status_reflects_it: exercises the client's URL/method construction and status-field parsing end to end against the fake relay.

The handler/route wiring itself is a one-line proxy call, same as its untested siblings, so no new test pattern was introduced there -- consistent with existing precedent in this crate.

Frontend: tsc --noEmit and vite build both pass; this crate has no eslint config to run.

just fmt-check, cargo clippy --all-features --no-deps -- -D warnings, and just test (full workspace) all pass. One unrelated pre-existing flaky test (helix-types::clock::test_duration_into_slot) intermittently fails under parallel test-thread contention but passes in isolation.

Reviewer checklist

  • CI (lint, unit-test) is green
  • Matches the linked issue/step
  • No unexplained scope creep or unrelated files touched

0w3n-d and others added 4 commits August 24, 2026 18:43
Gates BlockMergingTile's dial/reconnect on a new admin-toggled flag,
mirroring the existing killswitch pattern. While disabled, the tile
never dials and force-disconnects any active merge builder connection.
No simulation wiring yet — that's a later step.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… simulator

Merged blocks from the merge builder now get a SimRequest::ValidateMerged
path through SimulatorTile, tagged separately in SimResult so a future
consumer can distinguish it from ordinary submission validation. The
merged block is converted to a synthetic SignedBidSubmission (real
block_hash/parent_hash/gas_limit/gas_used/value/fee_recipient, zeroed
signature and builder/proposer pubkeys) so it reuses the existing
SSZ/JSON simulator dispatch. A new PendingMergeRequests queue, keyed by
base_block_hash rather than builder pubkey, gives merged-block requests
the same load-shedding behavior as ordinary submissions.

Nothing consumes SimResult::ValidateMerged yet -- BlockMergingTile isn't
wired up to send requests or read results. That's the next step.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ble failures

BlockMergingTile now sends every accepted merged block to the simulator
via SimRequest::ValidateMerged, in addition to (not instead of) its
existing immediate forward to the auctioneer -- the serving path is
unchanged. The tile becomes a consumer of from_sim (already MPMC per
spine-derive's defaults, confirmed no queue-declaration change needed)
and filters for its own tagged SimResult::ValidateMerged results,
ignoring the auctioneer's ordinary submission-validation results on the
same queue.

On a builder-attributable failure, block merging is disabled -- which
alone triggers the existing force-disconnect gating from the previous
step, so no separate disconnect call is needed -- and a critical Discord
alert fires with the block hash, merge builder endpoint, and reason.
"Builder-attributable" reuses BlockSimError::is_demotable() (the same
logic used for bid-submission builder demotion) but additionally
excludes internal channel/queue failures (SendError, SimulationDropped,
HydrationMiss), which are relay/simulator-side infra hiccups rather than
anything the merge builder did wrong. Temporary/infra errors and
successes take no action. Nothing except the admin endpoint from the
first step ever re-enables merging.

SlotState gains registered_gas_limit/apply_blacklist/inclusion_list,
captured from the same validator-registration and slot-event data that
already feeds fee_recipient, to build each merged block's simulation
request context.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds a block_merging_enabled toggle to the admin portal, mirroring the
existing kill-switch pattern end to end: RelayAdminClient gains
set_block_merging()/a block_merging_enabled status field, a proxied
/api/v1/actions/block-merging route, and a Settings page toggle with
confirmation dialogs plus an Overview status tile.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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.

1 participant