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

Andymck/subscriber mapping support #846

Closed
wants to merge 11 commits into from
Closed
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
10 changes: 6 additions & 4 deletions Cargo.lock

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

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,13 @@ sqlx = { version = "0", features = [
] }
helium-anchor-gen = { git = "https://github.com/helium/helium-anchor-gen.git" }
helium-crypto = { version = "0.8.4", features = ["multisig"] }
helium-lib = { git = "https://github.com/helium/helium-wallet-rs.git", branch = "master" }
helium-lib = { git = "https://github.com/helium/helium-wallet-rs.git", branch = "andy/temp-subscriber-mapping-support" }
hextree = { git = "https://github.com/jaykickliter/HexTree", branch = "main", features = [
"disktree",
] }
helium-proto = { git = "https://github.com/helium/proto", branch = "master", features = [
helium-proto = { git = "https://github.com/helium/proto", branch = "macpie/verification_mapping", features = [
"services",
] }
beacon = { git = "https://github.com/helium/proto", branch = "master" }
solana-client = "1.18"
solana-sdk = "1.18"
solana-program = "1.18"
Expand All @@ -83,6 +82,7 @@ reqwest = { version = "0", default-features = false, features = [
"json",
"rustls-tls",
] }
beacon = { git = "https://github.com/helium/proto", branch = "macpie/verification_mapping" }
humantime = "2"
humantime-serde = "1"
metrics = ">=0.22"
Expand Down
2 changes: 1 addition & 1 deletion coverage_point_calculator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ use service_provider_boosting::{MAX_AVERAGE_DISTANCE, MIN_WIFI_TRUST_MULTIPLIER}
mod hexes;
mod location;
mod service_provider_boosting;
mod speedtest;
pub mod speedtest;

pub type Result<T = ()> = std::result::Result<T, Error>;

Expand Down
12 changes: 7 additions & 5 deletions coverage_point_calculator/src/speedtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use chrono::{DateTime, Utc};
use rust_decimal::Decimal;
use rust_decimal_macros::dec;

const MIN_REQUIRED_SPEEDTEST_SAMPLES: usize = 2;
const MAX_ALLOWED_SPEEDTEST_SAMPLES: usize = 6;
pub const MIN_REQUIRED_SPEEDTEST_SAMPLES: usize = 2;
pub const MAX_ALLOWED_SPEEDTEST_SAMPLES: usize = 6;

type Millis = u32;

Expand Down Expand Up @@ -86,12 +86,14 @@ impl Speedtest {
}

pub fn multiplier(&self) -> Decimal {
self.tier().multiplier()
}

pub fn tier(&self) -> SpeedtestTier {
let upload = SpeedtestTier::from_upload(self.upload_speed);
let download = SpeedtestTier::from_download(self.download_speed);
let latency = SpeedtestTier::from_latency(self.latency_millis);

let tier = upload.min(download).min(latency);
tier.multiplier()
upload.min(download).min(latency)
}

pub fn avg(speedtests: &[Self]) -> Self {
Expand Down
18 changes: 18 additions & 0 deletions file_store/src/file_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ impl FileInfo {
}
}

pub const VERIFIED_SUBSCRIBER_MAPPING_EVENT_REQ: &str = "verified_subscriber_mapping_event_req";
pub const VERIFIED_SUBSCRIBER_MAPPING_EVENT_INGEST_REPORT: &str =
"verified_subscriber_mapping_event_report";

pub const INVALIDATED_RADIO_THRESHOLD_REQ: &str = "invalidated_radio_threshold_req";
pub const INVALIDATED_RADIO_THRESHOLD_INGEST_REPORT: &str =
"invalidated_radio_threshold_ingest_report";
Expand Down Expand Up @@ -214,11 +218,17 @@ pub enum FileType {
VerifiedInvalidatedRadioThresholdIngestReport,
SPBoostedRewardsBannedRadioIngestReport,
VerifiedSPBoostedRewardsBannedRadioIngestReport,
VerifiedSubscriberMappingEventReq,
VerifiedSubscriberMappingEventIngestReport,
}

impl fmt::Display for FileType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let s = match self {
Self::VerifiedSubscriberMappingEventReq => VERIFIED_SUBSCRIBER_MAPPING_EVENT_REQ,
Self::VerifiedSubscriberMappingEventIngestReport => {
VERIFIED_SUBSCRIBER_MAPPING_EVENT_INGEST_REPORT
}
Self::InvalidatedRadioThresholdReq => INVALIDATED_RADIO_THRESHOLD_REQ,
Self::InvalidatedRadioThresholdIngestReport => {
INVALIDATED_RADIO_THRESHOLD_INGEST_REPORT
Expand Down Expand Up @@ -287,6 +297,10 @@ impl fmt::Display for FileType {
impl FileType {
pub fn to_str(&self) -> &'static str {
match self {
Self::VerifiedSubscriberMappingEventReq => VERIFIED_SUBSCRIBER_MAPPING_EVENT_REQ,
Self::VerifiedSubscriberMappingEventIngestReport => {
VERIFIED_SUBSCRIBER_MAPPING_EVENT_INGEST_REPORT
}
Self::InvalidatedRadioThresholdReq => INVALIDATED_RADIO_THRESHOLD_REQ,
Self::InvalidatedRadioThresholdIngestReport => {
INVALIDATED_RADIO_THRESHOLD_INGEST_REPORT
Expand Down Expand Up @@ -355,6 +369,10 @@ impl FromStr for FileType {
type Err = Error;
fn from_str(s: &str) -> Result<Self> {
let result = match s {
VERIFIED_SUBSCRIBER_MAPPING_EVENT_REQ => Self::VerifiedSubscriberMappingEventReq,
VERIFIED_SUBSCRIBER_MAPPING_EVENT_INGEST_REPORT => {
Self::VerifiedSubscriberMappingEventIngestReport
}
INVALIDATED_RADIO_THRESHOLD_REQ => Self::InvalidatedRadioThresholdReq,
INVALIDATED_RADIO_THRESHOLD_INGEST_REPORT => {
Self::InvalidatedRadioThresholdIngestReport
Expand Down
1 change: 1 addition & 0 deletions file_store/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub mod mobile_radio_invalidated_threshold;
pub mod mobile_radio_threshold;
pub mod mobile_session;
pub mod mobile_subscriber;
pub mod mobile_subscriber_mapping;
pub mod mobile_transfer;
pub mod reward_manifest;
mod settings;
Expand Down
154 changes: 154 additions & 0 deletions file_store/src/mobile_subscriber_mapping.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
use crate::{
traits::{MsgDecode, MsgTimestamp, TimestampDecode, TimestampEncode},
Error, Result,
};
use chrono::{DateTime, Utc};
use helium_crypto::PublicKeyBinary;
use helium_proto::services::poc_mobile::{
VerifiedSubscriberMappingEventIngestReportV1, VerifiedSubscriberMappingEventReqV1,
};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct VerifiedSubscriberMappingEvent {
// The id of the verified subscriber mapper
// expressed as a vec of the UUID bytes
pub subscriber_id: Vec<u8>,
pub total_reward_points: u64,
pub timestamp: DateTime<Utc>,
pub verification_mapping_pubkey: PublicKeyBinary,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct VerifiedSubscriberMappingEventIngestReport {
pub received_timestamp: DateTime<Utc>,
pub report: VerifiedSubscriberMappingEvent,
}

impl MsgDecode for VerifiedSubscriberMappingEvent {
type Msg = VerifiedSubscriberMappingEventReqV1;
}

impl MsgDecode for VerifiedSubscriberMappingEventIngestReport {
type Msg = VerifiedSubscriberMappingEventIngestReportV1;
}

impl TryFrom<VerifiedSubscriberMappingEventReqV1> for VerifiedSubscriberMappingEvent {
type Error = Error;
fn try_from(v: VerifiedSubscriberMappingEventReqV1) -> Result<Self> {
Ok(Self {
subscriber_id: v.subscriber_id,
total_reward_points: v.total_reward_points,
timestamp: v.timestamp.to_timestamp()?,
verification_mapping_pubkey: v.verification_mapping_pubkey.into(),
})
}
}

impl From<VerifiedSubscriberMappingEvent> for VerifiedSubscriberMappingEventReqV1 {
fn from(v: VerifiedSubscriberMappingEvent) -> Self {
let timestamp = v.timestamp();
Self {
subscriber_id: v.subscriber_id,
total_reward_points: v.total_reward_points,
timestamp,
verification_mapping_pubkey: v.verification_mapping_pubkey.into(),
signature: vec![],
}
}
}

impl MsgTimestamp<Result<DateTime<Utc>>> for VerifiedSubscriberMappingEventReqV1 {
fn timestamp(&self) -> Result<DateTime<Utc>> {
self.timestamp.to_timestamp()
}
}

impl MsgTimestamp<u64> for VerifiedSubscriberMappingEvent {
fn timestamp(&self) -> u64 {
self.timestamp.encode_timestamp()
}
}

impl MsgTimestamp<Result<DateTime<Utc>>> for VerifiedSubscriberMappingEventIngestReportV1 {
fn timestamp(&self) -> Result<DateTime<Utc>> {
self.received_timestamp.to_timestamp_millis()
}
}

impl MsgTimestamp<u64> for VerifiedSubscriberMappingEventIngestReport {
fn timestamp(&self) -> u64 {
self.received_timestamp.encode_timestamp_millis()
}
}

impl TryFrom<VerifiedSubscriberMappingEventIngestReportV1>
for VerifiedSubscriberMappingEventIngestReport
{
type Error = Error;
fn try_from(v: VerifiedSubscriberMappingEventIngestReportV1) -> Result<Self> {
Ok(Self {
received_timestamp: v.timestamp()?,
report: v
.report
.ok_or_else(|| Error::not_found("verified subscriber mapping event ingest report"))?
.try_into()?,
})
}
}

impl From<VerifiedSubscriberMappingEventIngestReport>
for VerifiedSubscriberMappingEventIngestReportV1
{
fn from(v: VerifiedSubscriberMappingEventIngestReport) -> Self {
let received_timestamp = v.timestamp();
let report: VerifiedSubscriberMappingEventReqV1 = v.report.into();
Self {
received_timestamp,
report: Some(report),
}
}
}

#[cfg(test)]
mod tests {
use chrono::NaiveDateTime;
use std::str::FromStr;
use uuid::Uuid;

use super::*;

#[test]
fn verified_subscriber_mapper_from_proto() -> anyhow::Result<()> {
let subscriber_id = Uuid::parse_str("f47ac10b-58cc-4372-a567-0e02b2c3d479")?
.as_bytes()
.to_vec();
let carrier_pubkey =
PublicKeyBinary::from_str("14ihsKqVhXqfzET1dkLZGNQWrB9ZeGnqJtdMGajFjPmwKsKEEAC")?;

let proto = VerifiedSubscriberMappingEventIngestReportV1 {
received_timestamp: 1712624400000,
report: Some(VerifiedSubscriberMappingEventReqV1 {
subscriber_id: subscriber_id.clone(),
total_reward_points: 1000,
timestamp: 1712624400,
verification_mapping_pubkey: carrier_pubkey.as_ref().into(),
signature: vec![],
}),
};

let report = VerifiedSubscriberMappingEventIngestReport::try_from(proto)?;
assert_eq!(parse_dt("2024-04-09 01:00:00"), report.received_timestamp);
assert_eq!(subscriber_id, report.report.subscriber_id);
assert_eq!(1000, report.report.total_reward_points);
assert_eq!(parse_dt("2024-04-09 01:00:00"), report.report.timestamp);
assert_eq!(carrier_pubkey, report.report.verification_mapping_pubkey);

Ok(())
}

fn parse_dt(dt: &str) -> DateTime<Utc> {
NaiveDateTime::parse_from_str(dt, "%Y-%m-%d %H:%M:%S")
.expect("unable_to_parse")
.and_utc()
}
}
Loading
Loading