tatanka: Add coordinated whitelist transitions#12
Open
martonp wants to merge 6 commits intobisoncraft:masterfrom
Open
tatanka: Add coordinated whitelist transitions#12martonp wants to merge 6 commits intobisoncraft:masterfrom
martonp wants to merge 6 commits intobisoncraft:masterfrom
Conversation
Add tatanka/types with Whitelist and WhitelistState types that provide map-based peer ID sets with lazy SHA256 hashing for deterministic equality comparisons, JSON serialization, and deep-copy support.
Persist known peer multiaddresses to a JSON file in the data directory. On startup, the cache populates the libp2p peerstore so nodes can reconnect to known peers without needing bootstrap addresses after the initial run.
Move handleGetState to http_handlers.go and handleWebSocket + broadcast to websocket.go, reducing the size of admin/server.go. No behavior changes.
Replace the whitelist request/response handshake with a symmetric state exchange. Each node now broadcasts its current and proposed whitelists via gossipsub; a two-phase consensus mechanism (ready + commit) drives the transition when a 2/3 overlap quorum agrees. Key changes: - Add whitelist_manager for proposal lifecycle and consensus tracking. - Refactor mesh_connection_manager with callback-based config, tracker reconciliation, and per-peer whitelist state tracking. - Refactor admin server with config-struct initialization, new HTTP endpoints (propose, force, adopt, clear), and granular WebSocket broadcast messages. - Add admin notifier abstraction to avoid nil-checks for disabled UI. - Add whitelist persistence (JSON) with init/save/load and flexible matching across current and proposed whitelists. - Wire peerstore cache into startup and shutdown. - Decompose TatankaNode.Run into discrete init phases.
Add TUI views for whitelist proposal lifecycle: - Whitelist view showing current whitelist, active proposal, and network proposals aggregated from connected peers. - Whitelist editor with checkbox-based peer selection for composing and submitting proposals. - Diff view with adopt-peer's-whitelist flow for resolving mismatches. - API client methods for propose, clear, force, and adopt operations. - WebSocket message handlers for real-time peer, whitelist state, and whitelist membership updates.
Add 'init' subcommand that generates a private key and prints the peer ID. Replace --whitelistpath with --whitelist (plain text, one peer ID per line with # comments), --forcewl, and --bootstrap flags. Update test harness to use 'tatanka init' instead of makeprivkey, generate bootstrap flags automatically, and open TUI windows for each node.
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.
This PR adds coordinated whitelist transitions to the tatanka mesh network. Previously, whitelist changes required manually stopping nodes, editing files, and restarting. Now, nodes can propose a new whitelist and transition to it while running, using a two-phase consensus protocol.
When a node proposes a new whitelist, it broadcasts its proposal to the network via gossipsub. Other nodes in the mesh can independently propose the same whitelist. The whitelist manager on each node tracks the proposals of all peers and drives the transition through two phases. In the ready phase, a node marks itself as ready once at least 2/3 of the overlap peers (those present in both the current and proposed whitelists) are proposing the same whitelist, and no online overlap peer disagrees. In the commit phase, once a node is ready, it waits until every online overlap peer is also ready or has already switched, then atomically replaces its current whitelist with the proposed one. Offline overlap peers are not counted as disagreeing, but because the quorum threshold is computed from the full overlap set, they can block progress until they reconnect.
Nodes only actively maintain connections to peers in their current whitelist. Proposed peers are not connected to until the transition commits. During the handshake, nodes exchange both their current and proposed whitelists, and a connection is accepted as long as any combination of the two nodes' current and proposed whitelists match. This prevents nodes from rejecting each other when one has already committed the new whitelist while the other is still running the old one.
The whitelist is now stored as a JSON array of peer ID strings in the node's data directory. On disk, this file is the source of truth. The
--whitelistpathflag has been replaced with--whitelist, which points to a plain-text file containing one peer ID per line (with support for#comments). On first run, the provided whitelist is installed into the data directory. On subsequent runs, the flag is only used for validation. If the provided list doesn't match the stored whitelist, the node refuses to start unless--forcewlis passed to explicitly overwrite it. If no--whitelistflag is given, the node loads its existing whitelist from the data directory.Bootstrap addresses are now passed via
--bootstrapflags (repeatable) in multiaddr format, e.g.--bootstrap /ip4/1.2.3.4/tcp/12345/p2p/12D3KooW.... A peerstore cache persists known peer addresses to disk, so after the first run bootstrap flags are no longer needed.A new
tatanka initsubcommand generates (or loads) the node's private key and prints its peer ID to stdout. To set up a new network, you runtatanka initon each machine to get peer IDs, assemble a whitelist file containing all the peer IDs, then start each node with the whitelist and bootstrap addresses pointing to the other nodes.The admin server has been refactored with new HTTP endpoints for proposing, clearing, force-setting, and adopting whitelists. The tatankactl TUI adds views for monitoring whitelist state, composing proposals with a checkbox-based peer editor, viewing diffs against mismatched peers, and adopting a peer's whitelist to resolve mismatches.