Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 35 additions & 17 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,10 @@ aws-smithy-types-convert = { version = "0.60.9", features = [
url = "2.5.4"

### Protobuf
helium-proto = { git = "https://github.com/helium/proto", branch = "master", features = [
helium-proto = { git = "https://github.com/helium/proto", branch = "macpie/info_stream_v2", features = [
"services",
] }
beacon = { git = "https://github.com/helium/proto", branch = "master" }
beacon = { git = "https://github.com/helium/proto", branch = "macpie/info_stream_v2" }
# Pickup versions from above
prost = "*"
tonic = { version = "*", features = ["tls-aws-lc", "tls-native-roots"] }
Expand Down
1 change: 1 addition & 0 deletions file_store_oracles/src/traits/msg_verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ impl_msg_verify!(iot_config::AdminLoadRegionReqV1, signature);
impl_msg_verify!(iot_config::AdminRemoveKeyReqV1, signature);
impl_msg_verify!(iot_config::GatewayInfoReqV1, signature);
impl_msg_verify!(iot_config::GatewayInfoStreamReqV1, signature);
impl_msg_verify!(iot_config::GatewayInfoStreamReqV2, signature);
impl_msg_verify!(iot_config::RegionParamsReqV1, signature);
impl_msg_verify!(iot_config::GatewayInfoResV1, signature);
impl_msg_verify!(iot_config::GatewayInfoStreamResV1, signature);
Expand Down
3 changes: 2 additions & 1 deletion iot_config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,6 @@ poc-metrics = { path = "../metrics" }
task-manager = { path = "../task_manager" }

[dev-dependencies]
rand = { workspace = true }
backon = { version = "0", features = ["tokio-sleep"] }
h3o = { workspace = true }
rand = { workspace = true }
21 changes: 21 additions & 0 deletions iot_config/migrations/20251027000000_gateways.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
CREATE TABLE IF NOT EXISTS gateways (
address BYTEA PRIMARY KEY,
created_at TIMESTAMPTZ NOT NULL,
elevation INTEGER,
gain INTEGER,
hash TEXT,
is_active BOOLEAN,
is_full_hotspot BOOLEAN,
last_changed_at TIMESTAMPTZ NOT NULL,
location BIGINT,
location_asserts INTEGER,
location_changed_at TIMESTAMPTZ,
refreshed_at TIMESTAMPTZ NOT NULL,
updated_at TIMESTAMPTZ NOT NULL
);

CREATE INDEX IF NOT EXISTS gateways_last_changed_idx ON gateways (last_changed_at DESC);

CREATE INDEX IF NOT EXISTS gateways_location_changed_idx ON gateways (location_changed_at DESC)
WHERE
location IS NOT NULL;
99 changes: 99 additions & 0 deletions iot_config/src/cli/daemon.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
use std::sync::Arc;

use crate::gateway::tracker::Tracker;
use crate::grpc_server::GrpcServer;
use crate::sub_dao_service::SubDaoService;
use crate::{
admin::AuthCache, admin_service::AdminService, db_cleaner::DbCleaner,
gateway::service::GatewayService, org, org_service::OrgService, region_map::RegionMapReader,
route_service::RouteService, settings::Settings, telemetry,
};
use task_manager::TaskManager;

#[derive(Debug, clap::Args)]
pub struct Daemon;

impl Daemon {
pub async fn run(&self, settings: &Settings) -> anyhow::Result<()> {
custom_tracing::init(settings.log.clone(), settings.custom_tracing.clone()).await?;

// Install prometheus metrics exporter
poc_metrics::start_metrics(&settings.metrics)?;
telemetry::initialize();

// Create database pool
let pool = settings.database.connect("iot-config-store").await?;
sqlx::migrate!().run(&pool).await?;

// Create on-chain metadata pool
let metadata_pool = settings.metadata.connect("iot-config-metadata").await?;

let (auth_updater, auth_cache) = AuthCache::new(settings.admin_pubkey()?, &pool).await?;
let (region_updater, region_map) = RegionMapReader::new(&pool).await?;
let (delegate_key_updater, delegate_key_cache) = org::delegate_keys_cache(&pool).await?;

let signing_keypair = Arc::new(settings.signing_keypair()?);

let gateway_svc = GatewayService::new(
signing_keypair.clone(),
pool.clone(),
region_map.clone(),
auth_cache.clone(),
delegate_key_cache,
)?;

let route_svc =
RouteService::new(signing_keypair.clone(), auth_cache.clone(), pool.clone());

let org_svc = OrgService::new(
signing_keypair.clone(),
auth_cache.clone(),
pool.clone(),
route_svc.clone_update_channel(),
delegate_key_updater,
)?;

let admin_svc = AdminService::new(
settings,
auth_cache.clone(),
auth_updater,
pool.clone(),
region_map.clone(),
region_updater,
)?;

let subdao_svc = SubDaoService::new(settings, auth_cache, metadata_pool.clone())?;

let listen_addr = settings.listen;
let pubkey = settings
.signing_keypair()
.map(|keypair| keypair.public_key().to_string())?;
tracing::debug!("listening on {listen_addr}");
tracing::debug!("signing as {pubkey}");

let tracker = Tracker::new(
pool.clone(),
metadata_pool.clone(),
settings.gateway_tracker_interval,
);

let grpc_server = GrpcServer::new(
listen_addr,
gateway_svc,
route_svc,
org_svc,
admin_svc,
subdao_svc,
);

let db_cleaner = DbCleaner::new(pool.clone(), settings.deleted_entry_retention);

TaskManager::builder()
.add_task(tracker)
.add_task(grpc_server)
.add_task(db_cleaner)
.build()
.start()
.await
}
}
34 changes: 34 additions & 0 deletions iot_config/src/cli/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use crate::{cli::daemon::Daemon, Settings};
use std::path::PathBuf;

pub mod daemon;

#[derive(Debug, clap::Parser)]
#[clap(version = env!("CARGO_PKG_VERSION"))]
#[clap(about = "Helium IoT Config Service")]
pub struct Cli {
/// Optional configuration file to use. If present, the toml file at the
/// given path will be loaded. Environment variables can override the
/// settings in the given file.
#[clap(short = 'c')]
config: Option<PathBuf>,

#[clap(subcommand)]
cmd: Cmd,
}

impl Cli {
pub async fn run(self) -> anyhow::Result<()> {
match self.cmd {
Cmd::Server(server) => {
let settings = Settings::new(self.config)?;
server.run(&settings).await
}
}
}
}

#[derive(Debug, clap::Subcommand)]
pub enum Cmd {
Server(Daemon),
}
2 changes: 1 addition & 1 deletion iot_config/src/client/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::gateway_info::{self, GatewayInfo, GatewayInfoStream};
use crate::gateway::service::info::{self as gateway_info, GatewayInfo, GatewayInfoStream};
use file_store_oracles::traits::MsgVerify;
use futures::stream::{self, StreamExt};
use helium_crypto::{Keypair, PublicKey, PublicKeyBinary, Sign};
Expand Down
Loading