feat: sender-affinity load balancing and direct observer forwarding - #125
Conversation
d2d1908 to
cdfc97c
Compare
Security Scan - CodeSeverity: HIGH, CRITICAL No vulnerabilities found View scan results |
- add the SenderAffinityLoadBalancing hardfork, Never on real networks and Block(0) on local, layered above TransactionLoadBalancing - key the committee-slot digest on the recovered sender under the fork, so one validator owns a sender's whole nonce chain instead of consecutive ranges scattering across pools and parking nonce-gapped - add CommitteeSlots with a ring-walk covers() predicate so a down owner's senders fail over to the next live slot, agreed across nodes by the sorted committee order - the gossip handler builds per-slot liveness from connected peers (own slot always live) and dispatches batches through covers() - the fork gate reads the local canonical tip, so validators can briefly disagree across the fork block; worst case is a duplicate include that fails nonce-too-low at execution, never a consensus fork - on local the fork's version byte (0x0f) outranks HybridRewards from block 0; real networks are unaffected since the fork stays Never
- add a per-epoch observer forwarder that submits pending transactions by request-response to the validator owning each sender's slot, falling back to gossip before the fork - append WorkerRequest::SubmitTxns last and WorkerResponse::SubmitTxns after Error so every existing variant keeps its bcs index across a rolling upgrade; the ack carries the hashes the owner rejected as nonce-too-low - share one node-scoped in-flight tracker between the pool and its role via init_txn_pool_with_in_flight, bringing the dormant forwarding marks alive - an observer is no longer batch-producing: it forwards instead of running a batch builder that disburses - gate re-sends behind the catch-up watermark while first sends of new transactions still flow, and ring-walk to the next live validator on failover, marking accepted hashes and suppressing acked-stale ones - change WorkerGossip::Txn, publish_txn, and submit_batch_if_mine to Vec<Bytes> (bcs-identical to Vec<Vec<u8>>) so a payload is encoded once for both the direct and gossip paths - move fxhash_slot_digest and legacy_slot_digest to the types crate so the forwarder and validator compute the identical owner slot - bound inbound submit fan-out with a semaphore, shedding via the existing Error variant so the sender retries the next validator
- assert save_mark_backup persists a forwarding snapshot and load_mark_backup reloads it on a fresh pool, coming live once forwarding re-arms - assert a sealing snapshot writes no file, guarding the contract that restoring sealing marks would wedge the builder
- the mode-write skip treated ANY node currently in Observer mode as sticky: a staked validator that merely booted into Observer (catching up) could then never be promoted back to the committee; stickiness now keys on the operator's --observer flag (is_observer_sticky), the contract the skip was meant to honor - an empty committee-slot table (a gap mid-transition) reached the dispatch modulo, and division by zero aborts the node - a gossip message must never be able to do that; submit_batch_if_mine now drops the message instead Hardening: both paths need a mid-transition committee fault to demonstrate red, so this lands without failing-first tests.
cdfc97c to
2661bdd
Compare
|
Claude finished @bronxyz's task in 3m 13s —— View job PR Review: feat: sender-affinity load balancing and direct observer forwarding
OverviewThis review covers all 4 commits on the branch. The latest two commits ( Issues Remaining From Prior ReviewBug —
|
- `ok_or_eyre` takes a `Display` value, so the braces were emitted literally - addresses the PR #125 (feature/txpool-in-flight-tracker-forwarding-affinity) review: `ok_or_eyre` literal at both `node_inner.rs` sites
- the `Vec<Bytes>` identity with `Vec<Vec<u8>>` was asserted only in a comment; the pin encodes both and cross-decodes the old bytes into the new variant - addresses the PR #125 (feature/txpool-in-flight-tracker-forwarding-affinity) review: the `Vec<Bytes>` wire identity was comment-only
Summary
SenderAffinityLoadBalancinghardfork (0x0f;Neveron real networks, block 0 on local). Under the fork the committee-slot digest keys on the recovered sender, so one validator owns a sender's whole nonce chain instead of consecutive ranges scattering across pools and parking nonce-gapped.CommitteeSlotsadds a ring-walkcovers()predicate so a down owner's senders fail over to the next live slot, agreed across nodes by the sorted committee order.--observerflag rather than on the node's current mode, so a staked validator that booted into Observer to catch up can be promoted again; an empty slot table mid-transition drops the message instead of reaching the modulo (division by zero aborts the node).Stack 6/9 of the txpool in-flight tracker and observer-forwarder series.
Surface areas touched
eth_*,rayls_*, faucet)rayls-contracts/)etc/, scripts, Docker, compose).github/workflows/,Makefile)doc/, in-crate READMEs, root docs)Breaking / compatibility
WorkerRequest::SubmitTxnsis appended last andWorkerResponse::SubmitTxnsafterError, so every existing variant keeps its bcs index; an un-upgraded peer answers the new request withErrorand the sender retries the next validator.WorkerGossip::Txnmoves toVec<Bytes>, which bcs-encodes identically toVec<Vec<u8>>.SenderAffinityLoadBalancingisNeveron every real network until an activation block is scheduled. The fork gate reads the local canonical tip, so validators can briefly disagree across the fork block; the worst case is a duplicate include that fails nonce-too-low at execution, never a consensus fork.Test plan
Errorstays variant index 3 onWorkerResponseand round-trips as itself;SubmitTxnslands at index 4 (response) and 3 (request).save_mark_backup/load_mark_backupround trip for forwarding marks, and the pin that a sealing snapshot writes no file.is_caught_up_gates_on_local_lag,should_send_flows_first_sends_but_gates_resends,validate_stale_keeps_only_hashes_this_node_sent.make checkon the stack tip; CI on this branch.