Skip to content

Commit

Permalink
add region params resolver to iot config client
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffgrunewald committed Apr 4, 2023
1 parent d1c3488 commit 428764b
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 20 deletions.
1 change: 1 addition & 0 deletions file_store/src/traits/msg_verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ impl_msg_verify!(iot_config::GatewayInfoStreamReqV1, signature);
impl_msg_verify!(iot_config::RegionParamsReqV1, signature);
impl_msg_verify!(iot_config::GatewayInfoResV1, signature);
impl_msg_verify!(iot_config::GatewayInfoStreamResV1, signature);
impl_msg_verify!(iot_config::RegionParamsResV1, signature);

#[cfg(test)]
mod test {
Expand Down
61 changes: 51 additions & 10 deletions iot_config/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,70 @@ use file_store::traits::MsgVerify;
use futures::stream::{self, StreamExt};
use helium_crypto::{Keypair, PublicKey, PublicKeyBinary, Sign};
use helium_proto::{
services::{iot_config, Channel},
Message,
services::{iot_config, Channel, Endpoint},
BlockchainRegionParamV1, Message, Region,
};
use std::sync::Arc;
use std::{sync::Arc, time::Duration};

mod settings;
pub use settings::Settings;

#[derive(thiserror::Error, Debug)]
pub enum ClientError {
#[error("error signing request: {0}")]
SigningError(#[from] helium_crypto::Error),
Signing(#[from] helium_crypto::Error),
#[error("grpc error response: {0}")]
GrpcError(#[from] tonic::Status),
Rpc(#[from] tonic::Status),
#[error("error verifying response signature: {0}")]
VerificationError(#[from] file_store::Error),
Verification(#[from] file_store::Error),
#[error("error resolving region params: {0}")]
UndefinedRegionParams(String),
}

#[derive(Clone, Debug)]
pub struct Client {
pub client: iot_config::GatewayClient<Channel>,
pub gateway_client: iot_config::gateway_client::GatewayClient<Channel>,
pub admin_client: iot_config::admin_client::AdminClient<Channel>,
signing_key: Arc<Keypair>,
config_pubkey: PublicKey,
batch_size: u32,
}

impl Client {
pub fn from_settings(settings: &Settings) -> Result<Self, Box<helium_crypto::Error>> {
let channel = Endpoint::from(settings.url.clone())
.connect_timeout(Duration::from_secs(settings.connect_timeout))
.timeout(Duration::from_secs(settings.rpc_timeout))
.connect_lazy();
Ok(Self {
client: settings.connect(),
gateway_client: iot_config::gateway_client::GatewayClient::new(channel.clone()),
admin_client: iot_config::admin_client::AdminClient::new(channel),
signing_key: settings.signing_keypair()?,
config_pubkey: settings.config_pubkey()?,
batch_size: settings.batch_size,
})
}

pub async fn resolve_region_params(
&mut self,
region: Region,
) -> Result<RegionParamsInfo, ClientError> {
let mut request = iot_config::RegionParamsReqV1 {
region: region.into(),
signer: self.signing_key.public_key().into(),
signature: vec![],
};
request.signature = self.signing_key.sign(&request.encode_to_vec())?;
let response = self.admin_client.region_params(request).await?.into_inner();
response.verify(&self.config_pubkey)?;
Ok(RegionParamsInfo {
region: response.region(),
region_params: response
.params
.ok_or_else(|| ClientError::UndefinedRegionParams(format!("{region}")))?
.region_params,
})
}
}

#[async_trait::async_trait]
Expand All @@ -55,7 +84,7 @@ impl gateway_info::GatewayInfoResolver for Client {
};
request.signature = self.signing_key.sign(&request.encode_to_vec())?;
tracing::debug!(pubkey = address.to_string(), "fetching gateway info");
let response = match self.client.info(request).await {
let response = match self.gateway_client.info(request).await {
Ok(info_resp) => {
let response = info_resp.into_inner();
response.verify(&self.config_pubkey)?;
Expand All @@ -79,7 +108,7 @@ impl gateway_info::GatewayInfoResolver for Client {
tracing::debug!("fetching gateway info stream");
let pubkey = Arc::new(self.config_pubkey.clone());
let response_stream = self
.client
.gateway_client
.info_stream(request)
.await?
.into_inner()
Expand All @@ -98,3 +127,15 @@ impl gateway_info::GatewayInfoResolver for Client {
Ok(response_stream)
}
}

#[derive(Clone, Debug)]
pub struct RegionParamsInfo {
pub region: Region,
pub region_params: Vec<BlockchainRegionParamV1>,
}

#[derive(thiserror::Error, Debug)]
pub enum RegionParamsResolveError {
#[error("params undefined for region: {0}")]
Undefined(String),
}
11 changes: 1 addition & 10 deletions iot_config/src/client/settings.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use helium_proto::services::{iot_config, Channel, Endpoint};
use serde::Deserialize;
use std::{str::FromStr, sync::Arc, time::Duration};
use std::{str::FromStr, sync::Arc};

#[derive(Clone, Debug, Deserialize)]
pub struct Settings {
Expand Down Expand Up @@ -35,14 +34,6 @@ pub fn default_batch_size() -> u32 {
}

impl Settings {
pub fn connect(&self) -> iot_config::GatewayClient<Channel> {
let channel = Endpoint::from(self.url.clone())
.connect_timeout(Duration::from_secs(self.connect_timeout))
.timeout(Duration::from_secs(self.rpc_timeout))
.connect_lazy();
iot_config::GatewayClient::new(channel)
}

pub fn signing_keypair(
&self,
) -> Result<Arc<helium_crypto::Keypair>, Box<helium_crypto::Error>> {
Expand Down

0 comments on commit 428764b

Please sign in to comment.