Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hip138 - iot verifier #900

Draft
wants to merge 12 commits into
base: andymck/hip138-mobile
Choose a base branch
from
Draft
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
14 changes: 9 additions & 5 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion boost_manager/src/updater.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ where
Ok(())
}

async fn confirm_txn<'a>(&self, txn_row: &TxnRow) -> Result<()> {
async fn confirm_txn(&self, txn_row: &TxnRow) -> Result<()> {
if self.solana.confirm_transaction(&txn_row.txn_id).await? {
tracing::info!("txn_id {} confirmed on chain, updated db", txn_row.txn_id);
db::update_verified_txns_onchain(&self.pool, &txn_row.txn_id).await?
Expand Down
50 changes: 35 additions & 15 deletions file_store/src/cli/dump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::{
mobile_radio_threshold::VerifiedRadioThresholdIngestReport,
mobile_session::{DataTransferSessionIngestReport, InvalidDataTransferIngestReport},
mobile_subscriber::{SubscriberLocationIngestReport, VerifiedSubscriberLocationIngestReport},
reward_manifest::RewardManifest,
speedtest::{CellSpeedtest, CellSpeedtestIngestReport},
traits::{MsgDecode, TimestampDecode},
unique_connections::UniqueConnectionReq,
Expand All @@ -23,12 +24,13 @@ use helium_proto::{
services::{
packet_verifier::ValidDataTransferSession as ValidDataTransferSessionProto,
poc_lora::{
iot_reward_share::Reward as IotReward, IotRewardShare as IotRewardShareProto,
LoraBeaconIngestReportV1, LoraInvalidWitnessReportV1, LoraPocV1,
LoraWitnessIngestReportV1,
},
poc_mobile::{
mobile_reward_share::Reward, CellHeartbeatIngestReportV1, CellHeartbeatReqV1,
CoverageObjectV1, Heartbeat, HexUsageStatsIngestReportV1,
mobile_reward_share::Reward as MobileReward, CellHeartbeatIngestReportV1,
CellHeartbeatReqV1, CoverageObjectV1, Heartbeat, HexUsageStatsIngestReportV1,
InvalidDataTransferIngestReportV1, MobileRewardShare, OracleBoostingReportV1,
RadioRewardShare, RadioUsageStatsIngestReportV1, SpeedtestAvg, SpeedtestIngestReportV1,
SpeedtestReqV1, UniqueConnectionsIngestReportV1,
Expand All @@ -38,7 +40,7 @@ use helium_proto::{
router::PacketRouterPacketReportV1,
},
BlockchainTxn, BoostedHexUpdateV1 as BoostedHexUpdateProto, Message, PriceReportV1,
RewardManifest, SubnetworkRewards,
RewardManifest as RewardManifestProto, SubnetworkRewards,
};
use serde_json::json;
use std::io;
Expand Down Expand Up @@ -255,29 +257,51 @@ impl Cmd {
"validity": heartbeat.validity,
}))?;
}
FileType::IotRewardShare => {
let reward = IotRewardShareProto::decode(msg)?;
match reward.reward {
Some(IotReward::GatewayReward(reward)) => print_json(&json!({
"type": "gateway_reward",
"hotspot_key": PublicKey::try_from(reward.hotspot_key)?,
"dc_transfer_amount": reward.dc_transfer_amount,
"beacon_amount": reward.beacon_amount,
"witness_amount": reward.witness_amount,
}))?,
Some(IotReward::OperationalReward(reward)) => print_json(&json!({
"type": "operational_reward",
"amount": reward.amount,
}))?,
Some(IotReward::UnallocatedReward(reward)) => print_json(&json!({
"type": "unallocated_reward",
"unallocated_reward_type": reward.reward_type,
"amount": reward.amount,
}))?,
_ => (),
}
}
FileType::MobileRewardShare => {
let reward = MobileRewardShare::decode(msg)?;
match reward.reward {
Some(Reward::GatewayReward(reward)) => print_json(&json!({
Some(MobileReward::GatewayReward(reward)) => print_json(&json!({
"hotspot_key": PublicKey::try_from(reward.hotspot_key)?,
"dc_transfer_reward": reward.dc_transfer_reward,
}))?,
Some(Reward::RadioReward(reward)) => print_json(&json!({
Some(MobileReward::RadioReward(reward)) => print_json(&json!({
"hotspot_key": PublicKey::try_from(reward.hotspot_key)?,
"cbsd_id": reward.cbsd_id,
"poc_reward": reward.poc_reward,
"boosted_hexes": reward.boosted_hexes,
}))?,
Some(Reward::SubscriberReward(reward)) => print_json(&json!({
Some(MobileReward::SubscriberReward(reward)) => print_json(&json!({
"subscriber_id": reward.subscriber_id,
"discovery_location_amount": reward.discovery_location_amount,
"verification_mapping_amount": reward.verification_mapping_amount,
}))?,
Some(Reward::ServiceProviderReward(reward)) => print_json(&json!({
Some(MobileReward::ServiceProviderReward(reward)) => print_json(&json!({
"service_provider": reward.service_provider_id,
"amount": reward.amount,
}))?,
Some(Reward::UnallocatedReward(reward)) => print_json(&json!({
Some(MobileReward::UnallocatedReward(reward)) => print_json(&json!({
"unallocated_reward_type": reward.reward_type,
"amount": reward.amount,
}))?,
Expand All @@ -296,13 +320,9 @@ impl Cmd {
}))?;
}
FileType::RewardManifest => {
let manifest = RewardManifest::decode(msg)?;
print_json(&json!({
"written_files": manifest.written_files,
"start_timestamp": manifest.start_timestamp,
"end_timestamp": manifest.end_timestamp,
"reward_data": manifest.reward_data.unwrap()
}))?;
let manifest = RewardManifestProto::decode(msg)?;
let report = RewardManifest::try_from(manifest)?;
print_json(&report)?;
}
FileType::SignedPocReceiptTxn => {
// This just outputs a binary of the txns instead of the typical decode.
Expand Down
6 changes: 6 additions & 0 deletions file_store/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ pub enum DecodeError {
UnsupportedPacketType(String, i32),
#[error("file stream try decode error: {0}")]
FileStreamTryDecode(String),
#[error("unsupported token type {0}")]
UnsupportedTokenType(String, i32),
}

#[derive(Error, Debug)]
Expand Down Expand Up @@ -174,6 +176,10 @@ impl DecodeError {
pub const fn empty_field(field: &'static str) -> Error {
Error::Decode(Self::EmptyField(field))
}

pub fn unsupported_token_type<E: ToString>(msg1: E, msg2: i32) -> Error {
Error::Decode(Self::UnsupportedTokenType(msg1.to_string(), msg2))
}
}

impl From<helium_crypto::Error> for Error {
Expand Down
6 changes: 3 additions & 3 deletions file_store/src/file_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,19 +141,19 @@ pub const SPEEDTEST_AVG: &str = "speedtest_avg";
pub const VALIDATED_HEARTBEAT: &str = "validated_heartbeat";
pub const SIGNED_POC_RECEIPT_TXN: &str = "signed_poc_receipt_txn";
pub const RADIO_REWARD_SHARE: &str = "radio_reward_share";
pub const REWARD_MANIFEST: &str = "reward_manifest";
pub const REWARD_MANIFEST: &str = "network_reward_manifest_v1";
pub const IOT_PACKET_REPORT: &str = "packetreport";
pub const IOT_VALID_PACKET: &str = "iot_valid_packet";
pub const INVALID_PACKET: &str = "invalid_packet";
pub const NON_REWARDABLE_PACKET: &str = "non_rewardable_packet";
pub const IOT_REWARD_SHARE: &str = "iot_reward_share";
pub const IOT_REWARD_SHARE: &str = "iot_network_reward_shares_v1";
pub const DATA_TRANSFER_SESSION_INGEST_REPORT: &str = "data_transfer_session_ingest_report";
pub const INVALID_DATA_TRANSFER_SESSION_INGEST_REPORT: &str =
"invalid_data_transfer_session_ingest_report";
pub const VALID_DATA_TRANSFER_SESSION: &str = "valid_data_transfer_session";
pub const VERIFIED_DATA_TRANSFER_SESSION: &str = "verified_data_transfer_session";
pub const PRICE_REPORT: &str = "price_report";
pub const MOBILE_REWARD_SHARE: &str = "mobile_reward_share";
pub const MOBILE_REWARD_SHARE: &str = "mobile_network_reward_shares_v1";
pub const MAPPER_MSG: &str = "mapper_msg";
pub const COVERAGE_OBJECT: &str = "coverage_object";
pub const COVERAGE_OBJECT_INGEST_REPORT: &str = "coverage_object_ingest_report";
Expand Down
2 changes: 1 addition & 1 deletion file_store/src/file_sink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -676,7 +676,7 @@ mod tests {
.file_name()
.to_str()
.and_then(|file_name| FileInfo::from_str(file_name).ok())
.map_or(false, |file_info| {
.is_some_and(|file_info| {
FileType::from_str(&file_info.prefix).expect("entropy report prefix")
== FileType::EntropyReport
})
Expand Down
26 changes: 24 additions & 2 deletions file_store/src/reward_manifest.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
use crate::{error::DecodeError, traits::MsgDecode, Error};
use chrono::{DateTime, TimeZone, Utc};
use helium_proto as proto;
use helium_proto::{IotRewardToken, MobileRewardToken};
use rust_decimal::Decimal;
use serde::Serialize;

#[derive(Clone, Debug)]
#[derive(Clone, Debug, Serialize)]
pub struct RewardManifest {
pub written_files: Vec<String>,
pub start_timestamp: DateTime<Utc>,
pub end_timestamp: DateTime<Utc>,
pub reward_data: Option<RewardData>,
pub epoch: u64,
pub price: u64,
}

#[derive(Clone, Debug)]
#[derive(Clone, Debug, Serialize)]
pub enum RewardData {
MobileRewardData {
poc_bones_per_reward_share: Decimal,
boosted_poc_bones_per_reward_share: Decimal,
token: MobileRewardToken,
},
IotRewardData {
poc_bones_per_beacon_reward_share: Decimal,
poc_bones_per_witness_reward_share: Decimal,
dc_bones_per_share: Decimal,
token: IotRewardToken,
},
}

Expand All @@ -46,8 +52,16 @@ impl TryFrom<proto::RewardManifest> for RewardManifest {
.ok_or(Error::Decode(DecodeError::InvalidTimestamp(
value.end_timestamp,
)))?,
epoch: value.epoch,
price: value.price,
reward_data: match value.reward_data {
Some(proto::reward_manifest::RewardData::MobileRewardData(reward_data)) => {
let token = MobileRewardToken::try_from(reward_data.token).map_err(|_| {
DecodeError::unsupported_token_type(
"mobile_reward_manifest",
reward_data.token,
)
})?;
Some(RewardData::MobileRewardData {
poc_bones_per_reward_share: reward_data
.poc_bones_per_reward_share
Expand All @@ -63,9 +77,16 @@ impl TryFrom<proto::RewardManifest> for RewardManifest {
.value
.parse()
.map_err(DecodeError::from)?,
token,
})
}
Some(proto::reward_manifest::RewardData::IotRewardData(reward_data)) => {
let token = IotRewardToken::try_from(reward_data.token).map_err(|_| {
DecodeError::unsupported_token_type(
"iot_reward_manifest",
reward_data.token,
)
})?;
Some(RewardData::IotRewardData {
poc_bones_per_beacon_reward_share: reward_data
.poc_bones_per_beacon_reward_share
Expand All @@ -89,6 +110,7 @@ impl TryFrom<proto::RewardManifest> for RewardManifest {
.value
.parse()
.map_err(DecodeError::from)?,
token,
})
}
None => None,
Expand Down
3 changes: 3 additions & 0 deletions iot_config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ chrono = { workspace = true }
clap = { workspace = true }
config = { workspace = true }
db-store = { path = "../db_store" }
rust_decimal = { workspace = true, features = ["maths"] }
rust_decimal_macros = { workspace = true }
file-store = { path = "../file_store" }
futures = { workspace = true }
futures-util = { workspace = true }
helium-crypto = { workspace = true, features = ["sqlx-postgres"] }
helium-lib = { workspace = true }
helium-proto = { workspace = true }
hextree = { workspace = true }
http = { workspace = true }
Expand Down
4 changes: 4 additions & 0 deletions iot_config/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use std::{sync::Arc, time::Duration};

pub mod org_client;
mod settings;
pub mod sub_dao_client;

pub use org_client::OrgClient;
pub use settings::Settings;
Expand All @@ -24,6 +25,8 @@ pub enum ClientError {
Verification(#[from] file_store::Error),
#[error("error resolving region params: {0}")]
UndefinedRegionParams(String),
#[error("Invalid SubDaoRewardInfo proto response {0}")]
InvalidSubDaoRewardInfoProto(#[from] SubDaoRewardInfoParseError),
}

#[async_trait::async_trait]
Expand Down Expand Up @@ -77,6 +80,7 @@ macro_rules! call_with_retry {
}};
}

use crate::sub_dao_epoch_reward_info::SubDaoRewardInfoParseError;
pub(crate) use call_with_retry;

impl Client {
Expand Down
Loading