Skip to content

feat: Validator grid and UP/CE networking infrastructure#925

Open
yu2C wants to merge 2 commits intomainfrom
feat/networking-validator-grid-upce
Open

feat: Validator grid and UP/CE networking infrastructure#925
yu2C wants to merge 2 commits intomainfrom
feat/networking-validator-grid-upce

Conversation

@yu2C
Copy link
Copy Markdown
Contributor

@yu2C yu2C commented Mar 27, 2026

Summary

This PR adds validator grid topology and neighbor computation aligned with JAMNP, and strengthens QUIC connection handling / stream dispatch and CE handler wire consistency. It also includes small API, naming, and index-safety cleanups so follow-up work (UP 0, automatic dialing, epoch transitions) can land cleanly.

Motivation

  • JAMNP ties connectivity and UP 0 peers to grid neighbors and previous / current / next epoch validator sets; the codebase lacked a reusable grid / manager layer.
  • EventBus used inconsistent keys for Subscribe vs Publish, so handlers never ran.
  • ConnectionManager was not concurrency-safe (r/w on a map without a mutex).
  • CE handling mixed 1-byte stream kind with an extra 4-byte length wrapper in one path, which could desynchronize reads inside handlers.
  • Peer needed an accept loop, TLS-backed Ed25519 peer identity, 1-byte stream kind dispatch, and Broadcast that writes the kind byte before the payload.
  • PeerSet needed multi-index lookups (key / address / validator index) and must reject malformed Ed25519 key lengths to avoid corrupt indices.
  • GridMapper field names were updated to Previous / Current / Next for clearer alignment with the spec.

Scope (by file)

P0 / foundational fixes

File Change
internal/networking/quic/event_bus.go handlers as map[EventType][]Handler; Publish(ctx, eventType, event)
internal/networking/quic/connection.go Mutex on ConnectionManager; Add / Remove / All

Validator grid and dial addresses

File Change
internal/networking/validator/grid.go GridMapper (Previous / Current / Next), ComputeWidth, same-epoch neighbors, same-index across epochs, FindIndex
internal/networking/validator/manager.go ValidatorManager, PreferredInitiator, metadata → IPv6 + little-endian port

Peer / stream dispatch

File Change
internal/networking/quic/peer_set.go Multi-index map; Add returns error; Ed25519 key length must be 32 bytes when a key is present
internal/networking/quic/peer.go Start / accept loop; validate TLS cert and extract peer key; RegisterHandler; Broadcast writes stream kind; integrates PeerSet
internal/networking/quic/handler.go HandleStreamByKind; HandleStream keeps backward-compatible 1-byte read then dispatch

CE dispatch

File Change
internal/networking/handler/ce/ce_handler.go Removed incorrect outer 4-byte framing; HandleStream(blockchain, protoID, stream)

Tests

File Change
internal/networking/quic/peer_test.go Ed25519Key, Connect signature, broadcast wire includes kind byte
internal/networking/handler/ce/ce128_test.go, ce129_test.go Updated Connect calls

Validation

go test ./internal/networking/quic ./internal/networking/validator ./internal/networking/handler/ce

Expected: quic and handler/ce pass; validator currently has no test files.

Out of scope (follow-ups)

  • Full UP 0 block announcement state machine (handshake loop, announcement loop, duplicate UP stream resolution).
  • Epoch-transition connectivity delay rules from JAMNP.
  • Preferred-initiator 5s fallback and dialing all prev/current/next validators automatically.
  • Restoring explicit PeerRole / builder ALPN on Connect if product wiring needs it (small follow-up PR).
  • Replacing log in networking with the shared logger package for consistent levels and configuration.

@yu2C yu2C requested a review from Terryhung March 27, 2026 14:41
@yu2C yu2C self-assigned this Mar 27, 2026
@yu2C yu2C added the feat new feature for the user, not a new feature for build script label Mar 27, 2026
return result
}

func (g *GridMapper) IsNeighborInEpoch(a, b int) bool {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should IsNeighbor(key) consider peers whose key exists only in Previous/Next (same validator index), since JAMNP-S counts same-index-across-epochs as grid neighbours, or is Current-only lookup?

}
}

func (p *Peer) Broadcast(kind string, message interface{}) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should Broadcast follow JAMNP-S message framing (4-byte LE length after the stream kind byte)?

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

Labels

feat new feature for the user, not a new feature for build script

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants