Rebase #741 onto neo/edge with review fixes#839
Open
Lucifer0x17 wants to merge 33 commits into
Open
Conversation
Arweave v2 TXIDs are SHA-256(signature), which differs from the unsigned content hash used by HyperBEAM messages. Add a fallback in is_tx_admissible that checks the commitment-based ID via hb_message:id(CommittedMsg, all, Opts) when the unsigned content hash doesn't match.
…ed routing Introduces dev_router_perf.erl, an Erlang execution device for process@1.0 that replaces dynamic-router.lua for Arweave gateway routing. Fixes gaps in the Lua version: supports match/with route format. Key functionality: - register: adds nodes to routes with http_reference for the feedback loop - duration: updates node performance via exponential weighted average (EMA) - recalculate: recomputes weights using decay-based percentile scoring - Supports both match/with and prefix Registers router-perf@1.0 in hb_opts preloaded_devices. Comments added in the file by: Claude Opus 4.6 <noreply@anthropic.com>
Add `is_admissible_hook_routed_test_` that validates the full perf-router feedback loop: gateway registration, TX fetch through routed stack, async monitor duration posts, and performance score updates via EMA.
This reverts commit dba1bd3.
Lightweight device that gates HTTP monitor invocations via 1-in-N probabilistic sampling. Reads `sample-rate` from the request message and rolls `rand:uniform(Rate) =:= 1`. If absent, all requests pass.
- Gate monitor invocations via monitor-sampler@1.0 when `sample-rate` is set in the http_monitor config
- When `is-wasm-process` is set, strip the reserved `path` key from the monitor body and move it to `monitor-type`.
opts example
---
``` json
"http_monitor": {
"device": "relay@1.0",
"method": "POST",
"peer": "http://localhost:9000",
"path": "call",
"relay-path": "/<process-id>/push",
"commit-request": true,
"sample-rate": 10,
"is-wasm-process": true
}
```
Change find/3 to use hb_util:deep_get instead of maps:get so that slash-separated hook names like <<"http-client/response">> resolve to nested keys in the on config map
Add dev_chance.erl as a composable 1-in-N probabilistic gate using the 4-arity default handler pattern.
- Replace ~60 lines of custom monitor invocation (maybe_invoke_monitor, should_forward, do_invoke_monitor, sanitize_body) with a single `dev_hook:on(<<"http-client/response">>, ...)` call. - Reorder relay-path priority in dev_relay:call so that the explicit relay-path key is checked before the generic path key, fixing a conflict where the handler's dispatch path shadowed the relay URL.
The multirequest-admissible check was in the generic request/5 function which also handles /raw paths that don't emit the user's message as-is. Moved the admissibility + tx-admissible hook logic into get_tx where it belongs.
- Remove duplicate record_duration/2 and dead maybe_invoke_monitor/2 left by a botched merge during the rebase onto neo/edge. - Switch the surviving record_duration/2 to use hb_prometheus:observe/3 with the declared metric name http_client_duration_seconds (was calling prometheus_histogram:observe directly with an undeclared name). - Add <<"action">> => <<"duration">> to the hook body so dev_router_perf can dispatch performance updates from the http-client/response hook.
Restores the admission control gate that the Lua dynamic-router had but the Erlang port dropped. Without this anyone could POST a registration and inject themselves into a route. - Add trusted-peer check: if any signer of the request matches the configured trusted-peer wallet, registration is accepted unconditionally. - Otherwise resolve the configured is-admissible device against the body. If absent, registration is open (matches prior behaviour). - Document trusted-peer and is-admissible at the module level. - Drop the path-fallback dispatch and TODO from compute/3 now that hb_http_client always sets <<"action">> on the hook body.
dev_hook:on/3 can return {failure, Reason} when a handler returns an
unexpected result. Without this clause get_tx crashes with case_clause
on hook misconfiguration. Treat it the same as {error, Reason}.
binary_to_integer/1 throws badarg on a non-integer path. Wrap in try/catch and reject non-positive rates explicitly so callers get a proper error tuple instead of a crash.
Falls back to <<"path">> when <<"action">> is not present on the hook payload
c748996 to
8b5c56d
Compare
jfrain99
approved these changes
Apr 13, 2026
response_to_map/1 only matched {ok, _, _, _}. Transport errors from
hackney/gun crashed with function_clause before record_duration could
fire the hook. Add a catch-all that returns an empty map so the hook
chain still runs (and the adapter rejects the empty response as
not admissible).
…eat/rebased-router-node
| %%% Helper functions | ||
| -export([get_chunk/2, bundle_header/2, bundle_header/3]). | ||
| -include("include/hb.hrl"). | ||
| -include("include/hb_arweave_nodes.hrl"). |
| <<"path">> => <<"is-tx-admissible">>, | ||
| <<"tx">> => TXID | ||
| }, | ||
| case is_tx_admissible(Admissible, Msg, TxOpts) of |
Collaborator
There was a problem hiding this comment.
Why are we using a newly constructed message with a path as a base message?
| }, | ||
| case is_tx_admissible(Admissible, Msg, TxOpts) of | ||
| true -> | ||
| case dev_hook:on( |
Collaborator
There was a problem hiding this comment.
I think you want to ignore the result. It shouldn't affect the user getting their reply, unless I misunderstood?
Also, if we have a function called is_tx_admissible, why is our tx-admissible hook outside of it?
| maybe | ||
| {ok, TXID} ?= hb_maps:find(<<"tx">>, Base, Opts), | ||
| CommIDs = maps:keys(maps:get(<<"commitments">>, Request, #{})), | ||
| true ?= |
Collaborator
There was a problem hiding this comment.
This line is unnecessary
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replaces #741.
Clean rebase of feat/permissionless-id-fetch onto current neo/edge. The original branch had drifted enough that its diff showed 32 files changed when only 8 are actual feature work. This strips out the staleness.
Includes everything from #741 plus
Review fixes on top
No new tests yet. router-perf is not in prod so we land the fixes first and add tests separately.