Governance Gossip Handler
File: kinetic-node/src/gossip.rs
Crate: kinetic-node | Stage: 12
What Is This?
handle_kinetic_governance_gossip() is called every time a GOSSIP_TOPIC_GOVERNANCE message arrives over P2P. It is the only place in kinetic-node that writes to the application state.
The daemon also handles governance gossip in kinetic-daemon/src/services/gossip.rs. The difference: the node version also writes NameRecord::Premium and NameRecord::PremiumRevoked entries directly into the Sled storage, making the change immediately queryable via DHT.
How It Works
Parse and verify
#![allow(unused)]
fn main() {
serde_json::from_slice::<SignedGovernanceMessage>(payload)
process_governance_message(&mut state, &signed_msg)
}
-> See: kinetic-node/src/gossip.rs — Lines 18–24
serde_json::from_slice::<SignedGovernanceMessage>(payload) — if this fails (invalid JSON, wrong schema), the function returns silently. No panic, no error propagation.
process_governance_message(&mut state, &signed_msg) — validates the message signatures against the governance keys in GLOBAL_GOVERNANCE_STATE. The global mutex is acquired, the state is mutated, then immediately cloned and the mutex is released before any disk I/O. This keeps the critical section minimal.
Three outcomes
#![allow(unused)]
fn main() {
GovernanceEffect::PremiumNameGranted
GovernanceEffect::PremiumNameRevoked
NameRecord::Premium
<DB_PREFIX_REVEAL><name>
tokio::task::spawn_blocking()
}
-> See: kinetic-node/src/gossip.rs — Lines 27–80
Ok(Some(effect)) — the message was valid and produced a state change:
GovernanceEffect::PremiumNameGranted { name, target_pubkey }→ writes aNameRecord::Premiumto Sled under the key<DB_PREFIX_REVEAL><name>. This makes the premium name immediately resolvable via DHT without waiting for a user to register it.GovernanceEffect::PremiumNameRevoked { name }→ deletes theNameRecord::Premiumfrom Sled. The name becomes unresolvable.- Any other effect → no storage write.
- Saves updated
GovernanceStateto disk viatokio::task::spawn_blocking()(disk I/O offloaded from the async executor).
Ok(None) — message was valid but produced no effect (e.g., already applied):
- Saves state to disk anyway (to update timestamps/sequence numbers).
Err(e) — message was rejected (bad signature, replay attack, wrong sequence):
- Logs at
DEBUGlevel only. No storage write, no disk save.
Why spawn_blocking for disk saves?
#![allow(unused)]
fn main() {
GovernanceState::save_to_disk()
std::fs::write()
spawn_blocking
}
GovernanceState::save_to_disk() calls std::fs::write(), which blocks the OS thread.
Important
Inside a Tokio async context, blocking the executor thread stalls all other tasks.
spawn_blockingmoves the disk write to Tokio’s blocking thread pool, keeping the async executor free.
Tests
test_handle_invalid_json_payload— garbage bytes → no panic.test_handle_invalid_signature— valid JSON, empty signatures → rejected gracefully.test_handle_wrong_json_schema—{"hello":"world"}→ fails JSON parse ofSignedGovernanceMessage.test_handle_massive_payload— 1MB of[]→ serde rejects it, no OOM.test_handle_unexpected_fields— extra JSON fields → parsed with#[serde(deny_unknown_fields)]behavior.test_save_to_disk_failure— lockpath is a directory →save_to_diskreturnsErr, no panic.- Fuzz:
doesnt_crash_on_random_gossip_bytes— proptest random bytes → never panics.
-> See: kinetic-node/src/gossip.rs — Lines 87–197
Quick Reference
| Event | Storage Effect |
|---|---|
PremiumNameGranted | Write NameRecord::Premium to Sled |
PremiumNameRevoked | Delete NameRecord::Premium from Sled |
| Other governance effect | No storage write |
| Invalid signature | Ignored, DEBUG log |
| Bad JSON | Ignored, DEBUG log |