Skip to content

Commonware + BLS#1143

Draft
JakeHartnell wants to merge 268 commits intomainfrom
bls-commonware
Draft

Commonware + BLS#1143
JakeHartnell wants to merge 268 commits intomainfrom
bls-commonware

Conversation

@JakeHartnell
Copy link
Copy Markdown
Contributor

WIP: but seems to work well with multiple nodes.

@JakeHartnell
Copy link
Copy Markdown
Contributor Author

Might remove all these planning files, but will leave them for now.

JakeHartnell and others added 29 commits April 7, 2026 17:27
…tworking

- Add spawn_commonware_runtime() on dedicated OS thread to avoid Tokio nesting
- Implement run_lookup_network() with Oracle peer authorization (SEC-01)
- Add parse_peer_address() and parse_authorized_peers() helpers
- Rate limiting active via Config::local() defaults (SEC-02)
- Bridge loop handles GetStatus commands from WAVS main runtime
- P2pHandle::new wires up commonware backend for Local config
- Add commonware-utils, commonware-codec, rand_core dependencies

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- test_lookup_mode_two_nodes_connect: two nodes connect via lookup mode (NET-02, NET-03)
- test_unauthorized_peer_rejected: Oracle excludes unauthorized peers (SEC-01)
- Both tests verify commonware runtime starts on dedicated OS thread without panic
- Tests use isolated ports (TEST_PORT_BASE=19000) to avoid conflicts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ng plan

- SUMMARY.md: documents runtime scaffold, lookup networking, Oracle authorization
- STATE.md: advance to plan 2/3, update decisions and blockers
- ROADMAP.md: mark 01-02 as complete
- REQUIREMENTS.md: mark NET-02, NET-03, SEC-01, SEC-02, SEC-03 as complete

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add BlockPeer variant to P2pCommand enum and block_peer() method to P2pHandle
- Implement run_discovery_network() with bootstrapper-based peer discovery (NET-01)
- Wire P2pConfig::Remote to run_discovery_network in spawn_commonware_runtime
- Handle BlockPeer in both lookup and discovery bridge loops via Oracle.block() (SEC-03)
- Add parse_bootstrapper() helper for "pubkey@host:port" bootstrapper address format
- Discovery mode uses Set<PublicKey> for Oracle authorization (vs Map for lookup)
- Automatic reconnection via discovery::Network dial_frequency (NET-04)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…to-reconnect

- test_discovery_mode_two_nodes: Two nodes find each other via bootstrapper (NET-01)
- test_block_peer: block_peer() API wired end-to-end P2pHandle -> P2pCommand -> Oracle.block() (SEC-03)
- test_auto_reconnect: Node survives bootstrapper unavailability and retries (NET-04)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- SUMMARY.md documenting discovery mode, BlockPeer, auto-reconnect
- STATE.md updated: Phase 1 complete, 3/3 plans done, 25% progress
- REQUIREMENTS.md: NET-01 and NET-04 marked complete
- Phase 1 fully complete with all 13 tests passing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two plans in 2 waves for broadcast, service routing, catch-up, and
P2pHandle API preservation. Plan 01 (wave 1) defines P2pMessage,
ServiceRouter, and RetryQueue types. Plan 02 (wave 2) integrates the
broadcast Engine into bridge loops and adds integration tests.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tryQueue

- 12 failing test stubs define behavior contract (Wave 0 Nyquist compliance)
- Added commonware-broadcast = "2026.3.0" dependency to wavs Cargo.toml
- P2pMessage tests: from_submission, codec roundtrip, digest determinism, to_submission
- ServiceRouter tests: empty rejects, subscribe/accept, unsubscribe, subscribed_topics
- RetryQueue tests: empty, push/drain FIFO, overflow drops oldest, drain empty

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…r, and RetryQueue

- P2pMessage struct with service_id_bytes ([u8; 32]) and payload (Vec<u8>)
- P2pMessage::from_submission/to_submission for ServiceId+Submission conversion
- Digestible impl produces deterministic SHA-256 digest for Engine dedup (BCAST-02)
- Codec traits (Write+EncodeSize+Read) for binary encode/decode over broadcast
- ServiceRouter with subscribe/unsubscribe and should_accept filtering (BCAST-05)
- RetryQueue with bounded 64-item FIFO queue and oldest-drop eviction (BCAST-04)
- All 12 unit tests passing (P2pMessage + ServiceRouter + RetryQueue)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Created 02-01-SUMMARY.md with execution results
- Updated STATE.md: Phase 2 position, decisions, metrics
- Updated ROADMAP.md: Plan 02-01 checked off, Phase 2 in progress
- Updated REQUIREMENTS.md: BCAST-02, BCAST-03, BCAST-04, BCAST-05 complete

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… architecture

- Register two channels per network mode: channel 0 (Engine) and channel 1 (direct forwarding)
- Create broadcast Engine with deque_size=128 (CATCH-02) in both lookup and discovery modes
- Spawn inbound bridge tasks bridging commonware Receiver to tokio mpsc for select! compatibility
- Add seen_digests HashSet for application-level message deduplication (BCAST-02)
- Add service_router.should_accept() filtering on inbound messages (BCAST-05)
- Forward decoded P2pMessages to Aggregator as AggregatorCommand::Receive
- Pass aggregator_tx through P2pHandle::new -> spawn_commonware_runtime -> bridge loops
- Document CATCH-01 push-based recovery behavior in Engine setup comments

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… and subscribe logic

- Publish handler: broadcast via Engine (CATCH-01) + encode P2pMessage to bytes via Encode::encode() for direct_sender.send()
- Publish handler: check ack_rx for zero recipients -> queue for retry (BCAST-04)
- Publish handler: flush retry queue when peers available, re-broadcast queued messages
- Subscribe/Unsubscribe handlers: update ServiceRouter for service filtering
- GetStatus handler: return subscribed_topics from ServiceRouter
- BlockPeer handler: block via Oracle (carried from Phase 1)
- Remove handle_p2p_command_stub function -- all handlers now implemented inline
- Both lookup and discovery bridge loops have identical handler implementations

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…etry, catch-up, and API

- test_broadcast_to_all_peers (BCAST-01): verify message delivery between connected peers
- test_service_filtering (BCAST-05): verify only subscribed-service messages forwarded
- test_deduplication_by_digest (BCAST-02): verify exactly-once delivery via seen_digests
- test_retry_queue_on_no_peers (BCAST-04): verify publish succeeds with no peers (queued)
- test_catchup_after_reconnect (CATCH-01): verify subsequent broadcast triggers delivery after reconnect
- test_cache_bounded_deque_size (CATCH-02): verify Engine starts with bounded deque, handles 200+ publishes
- test_p2p_handle_api_preserved (INT-01): verify all P2pHandle methods work without errors

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Create 02-02-SUMMARY.md documenting two-channel architecture, all handlers, 7 tests
- Update STATE.md: advance to plan 2/2 complete, add decisions, update metrics
- Update ROADMAP.md: mark phase 02 as complete (2/2 plans done)
- Update REQUIREMENTS.md: mark BCAST-01, CATCH-01, CATCH-02, INT-01 complete

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace libp2p terminology (mDNS, Kademlia, DHT, multiaddr) with commonware concepts
- Document all P2pConfig serde fields: peer_addresses, bootstrappers, authorized_peers, max_message_size, deque_size
- Add local dev preset showing 2-operator localhost setup with wavs-cli identity command
- Reorder options to lead with Disabled (default) for clarity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add 03-02-SUMMARY.md with execution results
- Update STATE.md with phase 3 position and decisions
- Mark CFG-01 and CFG-03 requirements complete

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove libp2p-era fields (external_addresses, topic_peer_counts) from P2pStatus
- Rename subscribed_topics to subscribed_services in P2pStatus and ServiceRouter
- Add optional max_message_size and deque_size tuning fields to P2pConfig Local/Remote
- Add accessor methods max_message_size() and deque_size() with defaults
- Replace hardcoded 65536/128 values with configurable parameters in run_lookup_network and run_discovery_network
- Update both GetStatus handlers to use new field names

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
JakeHartnell and others added 29 commits April 7, 2026 17:27
- TGT-04: Proves get_recipients returns different results before and after
  set_peer_subscriptions changes subscription state
- Before subscription state: Recipients::All (defensive fallback)
- After set_peer_subscriptions: Recipients::Some containing subscribed peer
- Validates that re-resolution at drain time works correctly
- TGT-01: Publish handler uses peer_subscriptions.get_recipients(&service_id.inner())
  for direct channel sends instead of Recipients::All
- TGT-04: Both retry drain sites (Publish ack_rx + heartbeat) re-resolve
  recipients at drain time via get_recipients(&queued_msg.service_id_bytes)
- TGT-02: get_recipients() returns Recipients::All as fallback for empty sets
- TGT-03: All mailbox.broadcast() calls remain Recipients::All (Engine channel)
- Control messages (subscribe/unsubscribe announcements, heartbeat probes) unchanged
- All 33 p2p_broadcast_tests pass
- SUMMARY.md with 2 tasks, 8min duration, all verifications passed
- STATE.md updated: Phase 16 Plan 2 of 2, 80% progress
- ROADMAP.md updated with Phase 16 plan progress (1/2 complete)
- Requirements marked complete: TGT-01, TGT-02, TGT-03, TGT-04, COMPAT-01
… loop

- Replace Recipients::All with get_recipients() at 3 direct_sender.send() submission sites
- Publish handler uses get_recipients(&service_id.inner()) for targeted delivery (TGT-01)
- Both retry drain sites use get_recipients(&queued_msg.service_id_bytes) for re-resolution (TGT-04)
- All mailbox.broadcast() and control message sends remain Recipients::All (TGT-03)
- SUMMARY.md with 2 tasks, 1 file modified, 11min duration
- Both bridge loops now use identical targeted delivery patterns
- STATE.md updated: plan 2/2, progress 100%
- ROADMAP.md updated: Phase 16 complete
- REQUIREMENTS.md: COMPAT-02 marked complete
- RED phase: test_peer_subscription_counts calls peer_subscription_counts() which doesn't exist yet
- Verifies empty map, correct counts after subscriptions, and counts after peer removal
- GREEN phase: add peer_subscription_counts() returning HashMap<String, usize>
- Keys are hex-encoded service_id bytes via const_hex::encode
- Values are number of peers subscribed to each service
- Unit test passes: empty map, correct counts, counts after peer removal
…s handlers

- Add peer_subscriptions: HashMap<String, usize> to P2pStatus with serde(default)
- Populate field from peer_subscriptions.peer_subscription_counts() in lookup and discovery loops
- Update p2p_status_format test to verify field presence and default empty object
- Update TypeScript P2pStatus interface with peer_subscriptions: Record<string, number>
- SUMMARY.md: 2 tasks, 4 files modified, OBS-01 satisfied
- STATE.md: Phase 17 complete, v1.3 progress 100% (4/4 phases)
- ROADMAP.md: Phase 17 marked complete
- REQUIREMENTS.md: OBS-01 marked complete
- Add PeerSubscriptionMap::tracked_peers() for heartbeat prune diffing (SUB-03)
- Modify get_recipients() to accept connected_peers set and include
  un-announced peers for backward compatibility (COMPAT-03)
- has_announced() now called in production code (dead_code warning resolved)
- Update all ~24 existing test call sites with new signature
- Add 8 new unit tests for tracked_peers, heartbeat prune, and COMPAT-03

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…loops

- Add connected_peer_set state variable to both bridge loops (lookup + discovery)
- Update connected_peer_set from broadcast ack and heartbeat ack in both loops
- Add SUB-03 heartbeat prune block: diff tracked_peers vs connected, remove_peer + known_peers.remove for departed
- Update all 6 production get_recipients() calls to pass &connected_peer_set
- Prune block runs BEFORE retry drain so get_recipients uses pruned state
- Both loops have character-for-character identical changes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- SUB-03: heartbeat-driven peer pruning in both bridge loops
- COMPAT-03: backward-compatible recipient resolution for pre-v1.3 nodes
- 8 new unit tests, all 45 p2p tests passing

Co-Authored-By: Claude Opus 4.6 <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