Problem
execute_bls_verification in router/src/executor/bls/executor.rs resolves operator addresses sequentially:
for (contributor, g1_pubkey) in participating.iter().zip(participating_g1.iter()) {
let address = self.ensure_g1_hash_map_entry(contributor, g1_pubkey).await?;
operators.push(address);
}
On the first round (or when a new operator joins), each cache miss fires a pubkeyHashToOperator RPC call and awaits the result before starting the next. At a threshold of 5, this is up to 5 × ~150 ms ≈ 750 ms of serial RPC latency before getNonSignerStakesAndSignature is even called.
After the first round all entries are cached and the loop is instant — this is purely a first-round / operator-onboarding problem.
Proposed solution
Split the loop into two phases:
- Collect all cache hits synchronously (no async, no allocations).
- For cache misses, fire all
pubkeyHashToOperator calls in parallel via futures::future::join_all, then write results back to g1_hash_map and build the operators vec.
On steady-state (all operators cached) the behavior is unchanged and no future overhead is added.
Code location
router/src/executor/bls/executor.rs — ensure_g1_hash_map_entry loop inside execute_bls_verification
Impact / Effort / Risk
- Impact: High (up to ~750 ms eliminated on first round / operator set change; zero impact on warm steady-state)
- Effort: Low (< 1 day)
- Risk: Low
Related: gas-killer/roadmap#4
Problem
execute_bls_verificationinrouter/src/executor/bls/executor.rsresolves operator addresses sequentially:On the first round (or when a new operator joins), each cache miss fires a
pubkeyHashToOperatorRPC call and awaits the result before starting the next. At a threshold of 5, this is up to 5 × ~150 ms ≈ 750 ms of serial RPC latency beforegetNonSignerStakesAndSignatureis even called.After the first round all entries are cached and the loop is instant — this is purely a first-round / operator-onboarding problem.
Proposed solution
Split the loop into two phases:
pubkeyHashToOperatorcalls in parallel viafutures::future::join_all, then write results back tog1_hash_mapand build theoperatorsvec.On steady-state (all operators cached) the behavior is unchanged and no future overhead is added.
Code location
router/src/executor/bls/executor.rs—ensure_g1_hash_map_entryloop insideexecute_bls_verificationImpact / Effort / Risk
Related: gas-killer/roadmap#4