feat(gossip): add accredited_keys placeholder (for future Join/Leave)

This commit is contained in:
erhant
2026-08-07 12:59:24 +03:00
parent df28b0c8b2
commit e19f5818de
2 changed files with 83 additions and 0 deletions
@@ -0,0 +1,82 @@
//! Source of the channel's current accredited key set, polled by the
//! gossip layer to validate announcements.
//!
//! FIXME: `NodeKeysProvider` will be replaced by an L2 Join/Leave-derived provider in a follow-up.
use std::{collections::HashSet, future::Future};
use anyhow::{Context as _, Result};
use logos_blockchain_core::mantle::ops::channel::ChannelId;
use logos_blockchain_zone_sdk::{
CommonHttpClient,
adapter::{Node as _, NodeHttpClient},
};
use crate::config::BedrockConfig;
pub trait AccreditedKeysProvider: Send + 'static {
/// The channel's current accredited Ed25519 keys. An empty set is valid
/// (channel does not exist yet); errors keep the caller's last set.
fn accredited_keys(&self) -> impl Future<Output = Result<HashSet<[u8; 32]>>> + Send;
}
/// Reads accredited keys from the bedrock node's channel state, on its own
/// HTTP connection (no coupling to the publisher's drive task).
pub struct NodeKeysProvider {
node: NodeHttpClient,
channel_id: ChannelId,
}
impl NodeKeysProvider {
#[must_use]
pub fn new(config: &BedrockConfig) -> Self {
let node = NodeHttpClient::new(
CommonHttpClient::new(config.auth.clone().map(Into::into)),
config.node_url.clone(),
);
Self {
node,
channel_id: config.channel_id,
}
}
}
impl AccreditedKeysProvider for NodeKeysProvider {
async fn accredited_keys(&self) -> Result<HashSet<[u8; 32]>> {
let state = self
.node
.channel_state(self.channel_id)
.await
.context("Failed to read channel state for accredited keys")?;
Ok(state
.map(|state| {
state
.accredited_keys
.iter()
.map(|key| key.to_bytes())
.collect()
})
.unwrap_or_default())
}
}
/// Fixed key set, for tests.
pub struct StaticKeysProvider(pub HashSet<[u8; 32]>);
impl AccreditedKeysProvider for StaticKeysProvider {
async fn accredited_keys(&self) -> Result<HashSet<[u8; 32]>> {
Ok(self.0.clone())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn static_provider_returns_its_set() {
let keys = HashSet::from([[1; 32], [2; 32]]);
let provider = StaticKeysProvider(keys.clone());
assert_eq!(provider.accredited_keys().await.unwrap(), keys);
}
}
+1
View File
@@ -7,3 +7,4 @@
pub mod announcement;
pub mod directory;
pub mod keys_provider;