Skip to content

Commit df192f7

Browse files
authored
Merge pull request #545 from AmbireTech/get-cfg-documentation
GET `/cfg` Sentry API documentation
2 parents 64df5d4 + e2924a2 commit df192f7

File tree

8 files changed

+176
-63
lines changed

8 files changed

+176
-63
lines changed

primitives/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ name = "validator_messages_list_query"
7575
[[example]]
7676
name = "validator_messages_list_response"
7777

78+
[[example]]
79+
name = "get_cfg_response"
80+
7881
[dependencies]
7982
# (De)Serialization
8083
serde = { version = "1.0", features = ["derive"] }
+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
use primitives::Config;
2+
use serde_json::{from_value, json};
3+
4+
fn main() {
5+
let json = json!({
6+
"max_channels": 512,
7+
"channels_find_limit": 200,
8+
"campaigns_find_limit": 200,
9+
"spendable_find_limit": 200,
10+
"wait_time": 500,
11+
"msgs_find_limit": 10,
12+
"analytics_find_limit": 5000,
13+
"analytics_maxtime": 20000,
14+
"heartbeat_time": 30000,
15+
"health_threshold_promilles": 950,
16+
"health_unsignable_promilles": 750,
17+
"propagation_timeout": 2000,
18+
"fetch_timeout": 5000,
19+
"all_campaigns_timeout": 5000,
20+
"channel_tick_timeout": 8000,
21+
"ip_rate_limit": {
22+
"type": "ip",
23+
"timeframe": 1200000
24+
},
25+
"creators_whitelist": [],
26+
"validators_whitelist": [],
27+
"admins": [
28+
"0x80690751969B234697e9059e04ed72195c3507fa"
29+
],
30+
"chain": {
31+
"Ganache #1337": {
32+
"chain_id": 1337,
33+
"rpc": "http://localhost:1337/",
34+
"outpace": "0xAbc27d46a458E2e49DaBfEf45ca74dEDBAc3DD06",
35+
"token": {
36+
"Mocked TOKEN 1337": {
37+
"min_campaign_budget": "1000000000000000000",
38+
"min_validator_fee": "1000000000000",
39+
"precision": 18,
40+
"address": "0x2BCaf6968aEC8A3b5126FBfAb5Fd419da6E8AD8E"
41+
}
42+
}
43+
},
44+
"Ganache #1": {
45+
"chain_id": 1,
46+
"rpc": "http://localhost:8545/",
47+
"outpace": "0x26CBc2eAAe377f6Ac4b73a982CD1125eF4CEC96f",
48+
"token": {
49+
"Mocked TOKEN 1": {
50+
"min_campaign_budget": "1000000000000000000",
51+
"min_validator_fee": "1000000000000",
52+
"precision": 18,
53+
"address": "0x12a28f2bfBFfDf5842657235cC058242f40fDEa6"
54+
}
55+
}
56+
}
57+
},
58+
"platform": {
59+
"url": "https://platform.adex.network/",
60+
"keep_alive_interval": 1200000
61+
},
62+
"limits": {
63+
"units_for_slot": {
64+
"max_campaigns_earning_from": 25,
65+
"global_min_impression_price": "1000000"
66+
}
67+
}
68+
});
69+
assert!(from_value::<Config>(json).is_ok());
70+
}

primitives/src/config.rs

+39-21
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::{
55
Address, BigNum, ChainOf, ValidatorId,
66
};
77
use once_cell::sync::Lazy;
8-
use serde::{Deserialize, Deserializer, Serialize};
8+
use serde::{Deserialize, Serialize};
99
use std::{collections::HashMap, num::NonZeroU8, time::Duration};
1010
use thiserror::Error;
1111

@@ -47,6 +47,10 @@ impl Default for Environment {
4747
}
4848
}
4949

50+
/// Examples:
51+
/// ```
52+
#[doc = include_str!("../../primitives/examples/get_cfg_response.rs")]
53+
/// ```
5054
#[derive(Serialize, Deserialize, Debug, Clone)]
5155
pub struct Config {
5256
/// The maximum number of [`Channel`](crate::Channel)s that the worker
@@ -73,7 +77,7 @@ pub struct Config {
7377
/// finish before running a new tick in the Validator Worker.
7478
///
7579
/// In milliseconds
76-
#[serde(deserialize_with = "milliseconds_to_std_duration")]
80+
#[serde(with = "std_duration_millis")]
7781
pub wait_time: Duration,
7882
/// The maximum allowed limit of [`ValidatorMessage`](crate::sentry::ValidatorMessage)s per page
7983
/// returned by Sentry's GET `/v5/channel/0xXXX.../validator-messages` route.
@@ -104,12 +108,12 @@ pub struct Config {
104108
/// - GET `/v5/analytics/for-admin`
105109
///
106110
/// In milliseconds
107-
#[serde(deserialize_with = "milliseconds_to_std_duration")]
111+
#[serde(with = "std_duration_millis")]
108112
pub analytics_maxtime: Duration,
109113
/// The amount of time that should have passed before sending a new heartbeat.
110114
///
111115
/// In milliseconds
112-
#[serde(deserialize_with = "milliseconds_to_std_duration")]
116+
#[serde(with = "std_duration_millis")]
113117
pub heartbeat_time: Duration,
114118
/// The pro miles below which the [`ApproveState`](crate::validator::ApproveState)
115119
/// becomes **unhealthy** in the [`Channel`](crate::Channel)'s Follower.
@@ -128,7 +132,7 @@ pub struct Config {
128132
/// to a validator.
129133
///
130134
/// In milliseconds
131-
#[serde(deserialize_with = "milliseconds_to_std_duration")]
135+
#[serde(with = "std_duration_millis")]
132136
pub propagation_timeout: Duration,
133137
/// The Client timeout for `SentryApi`.
134138
///
@@ -138,20 +142,20 @@ pub struct Config {
138142
/// [`Config.propagation_timeout`](Config::propagation_timeout).
139143
///
140144
/// In milliseconds
141-
#[serde(deserialize_with = "milliseconds_to_std_duration")]
145+
#[serde(with = "std_duration_millis")]
142146
pub fetch_timeout: Duration,
143147
/// The Client timeout for `SentryApi` when collecting all channels
144148
/// and Validators using the `/campaign/list` route.
145149
///
146150
/// In milliseconds
147-
#[serde(deserialize_with = "milliseconds_to_std_duration")]
151+
#[serde(with = "std_duration_millis")]
148152
pub all_campaigns_timeout: Duration,
149153
/// The timeout for a single tick of a [`Channel`](crate::Channel) in
150154
/// the Validator Worker.
151155
/// This timeout is applied to both the leader and follower ticks.
152156
///
153157
/// In milliseconds
154-
#[serde(deserialize_with = "milliseconds_to_std_duration")]
158+
#[serde(with = "std_duration_millis")]
155159
pub channel_tick_timeout: Duration,
156160
/// The default IP rate limit that will be imposed if
157161
/// [`Campaign.event_submission`](crate::Campaign::event_submission) is [`None`].
@@ -210,7 +214,7 @@ impl Config {
210214
#[derive(Serialize, Deserialize, Debug, Clone)]
211215
pub struct PlatformConfig {
212216
pub url: ApiUrl,
213-
#[serde(deserialize_with = "milliseconds_to_std_duration")]
217+
#[serde(with = "std_duration_millis")]
214218
pub keep_alive_interval: Duration,
215219
}
216220

@@ -248,21 +252,35 @@ pub struct Limits {
248252
pub units_for_slot: limits::UnitsForSlot,
249253
}
250254

251-
fn milliseconds_to_std_duration<'de, D>(deserializer: D) -> Result<Duration, D::Error>
252-
where
253-
D: Deserializer<'de>,
254-
{
255-
use serde::de::Error;
256-
use toml::Value;
255+
/// Module for [`Config`] (de)serialization of [`std::time::Duration`] from
256+
/// and to milliseconds.
257+
pub mod std_duration_millis {
258+
use serde::{Deserialize, Deserializer, Serializer};
259+
use std::time::Duration;
260+
261+
pub fn deserialize<'de, D>(deserializer: D) -> Result<Duration, D::Error>
262+
where
263+
D: Deserializer<'de>,
264+
{
265+
use serde::de::Error;
266+
use toml::Value;
257267

258-
let toml_value: Value = Value::deserialize(deserializer)?;
268+
let toml_value: Value = Value::deserialize(deserializer)?;
259269

260-
let milliseconds = match toml_value {
261-
Value::Integer(mills) => u64::try_from(mills).map_err(Error::custom),
262-
_ => Err(Error::custom("Only integers allowed for this value")),
263-
}?;
270+
let milliseconds = match toml_value {
271+
Value::Integer(mills) => u64::try_from(mills).map_err(Error::custom),
272+
_ => Err(Error::custom("Only integers allowed for this value")),
273+
}?;
264274

265-
Ok(Duration::from_millis(milliseconds))
275+
Ok(Duration::from_millis(milliseconds))
276+
}
277+
278+
pub fn serialize<S>(duration: &Duration, serializer: S) -> Result<S::Ok, S::Error>
279+
where
280+
S: Serializer,
281+
{
282+
serializer.serialize_str(&duration.as_millis().to_string())
283+
}
266284
}
267285

268286
pub mod limits {

sentry/src/db/analytics.rs

+11-11
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use tokio_postgres::{types::ToSql, Row};
99

1010
use super::{DbPool, PoolError};
1111

12-
pub async fn get_analytics(
12+
pub async fn fetch_analytics(
1313
pool: &DbPool,
1414
query: AnalyticsQuery,
1515
allowed_keys: HashSet<AllowedKey>,
@@ -180,7 +180,7 @@ mod test {
180180
use crate::db::tests_postgres::{setup_test_migrations, DATABASE_POOL};
181181

182182
#[tokio::test]
183-
async fn insert_update_and_get_analytics() {
183+
async fn insert_update_and_fetch_analytics() {
184184
let database = DATABASE_POOL.get().await.expect("Should get a DB pool");
185185

186186
let ad_unit = DUMMY_AD_UNITS[0].clone();
@@ -393,7 +393,7 @@ mod test {
393393

394394
// Impression query - should count all inserted Analytics
395395
{
396-
let count_impressions = get_analytics(
396+
let count_impressions = fetch_analytics(
397397
&database.pool,
398398
impression_query.clone(),
399399
ALLOWED_KEYS.clone(),
@@ -436,7 +436,7 @@ mod test {
436436
let mut paid_impressions_query = impression_query.clone();
437437
paid_impressions_query.metric = Metric::Paid;
438438

439-
let paid_impressions = get_analytics(
439+
let paid_impressions = fetch_analytics(
440440
&database.pool,
441441
paid_impressions_query,
442442
ALLOWED_KEYS.clone(),
@@ -498,7 +498,7 @@ mod test {
498498

499499
// Click query - should count all inserted Analytics
500500
{
501-
let count_clicks = get_analytics(
501+
let count_clicks = fetch_analytics(
502502
&database.pool,
503503
click_query.clone(),
504504
ALLOWED_KEYS.clone(),
@@ -541,7 +541,7 @@ mod test {
541541
let mut paid_clicks_query = impression_query.clone();
542542
paid_clicks_query.metric = Metric::Paid;
543543

544-
let paid_impressions = get_analytics(
544+
let paid_impressions = fetch_analytics(
545545
&database.pool,
546546
paid_clicks_query,
547547
ALLOWED_KEYS.clone(),
@@ -595,7 +595,7 @@ mod test {
595595
};
596596
click_germany_query.country = Some("Germany".into());
597597

598-
let count_clicks = get_analytics(
598+
let count_clicks = fetch_analytics(
599599
&database.pool,
600600
click_germany_query.clone(),
601601
ALLOWED_KEYS.clone(),
@@ -646,7 +646,7 @@ mod test {
646646
chains: vec![],
647647
};
648648

649-
let count_impressions = get_analytics(
649+
let count_impressions = fetch_analytics(
650650
&database.pool,
651651
ad_unit_2_query.clone(),
652652
ALLOWED_KEYS.clone(),
@@ -702,7 +702,7 @@ mod test {
702702
chains: vec![],
703703
};
704704

705-
let count_impressions = get_analytics(
705+
let count_impressions = fetch_analytics(
706706
&database.pool,
707707
filter_by_publisher_2_query.clone(),
708708
ALLOWED_KEYS.clone(),
@@ -758,7 +758,7 @@ mod test {
758758
chains: vec![],
759759
};
760760

761-
let count_impressions = get_analytics(
761+
let count_impressions = fetch_analytics(
762762
&database.pool,
763763
authenticate_as_publisher_2_query.clone(),
764764
ALLOWED_KEYS.clone(),
@@ -814,7 +814,7 @@ mod test {
814814
chains: vec![],
815815
};
816816

817-
let count_impressions = get_analytics(
817+
let count_impressions = fetch_analytics(
818818
&database.pool,
819819
segment_ad_units_query.clone(),
820820
ALLOWED_KEYS.clone(),

sentry/src/routes.rs

+22-2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
//! - [GET `/v5/analytics/for-publisher`](#get-v5analyticsfor-publisher-auth-required) (auth required)
3030
//! - [GET `/v5/analytics/for-advertiser`](#get-v5analyticsfor-advertiser-auth-required) (auth required)
3131
//! - [GET `/v5/analytics/for-admin`](#get-v5analyticsfor-admin-auth-required) (auth required)
32+
//! - [Config](#config) route
33+
//! - [GET `/cfg`](#get-cfg)
3234
//!
3335
//! ## Channel
3436
//!
@@ -475,6 +477,24 @@
475477
//!
476478
//! See [GET `/v5/analytics`](#get-v5analytics)
477479
//!
480+
//! ## Config
481+
//!
482+
//! #### GET `/cfg`
483+
//!
484+
//! Gets the config that the validator is running on.
485+
//!
486+
//! The route is handled by [`get_cfg()`](crate::routes::get_cfg())
487+
//!
488+
//! Response: [`Config`](primitives::Config)
489+
//!
490+
//! ##### Examples
491+
//!
492+
//! Response:
493+
//!
494+
//! ```
495+
#![doc = include_str!("../../primitives/examples/get_cfg_response.rs")]
496+
//! ```
497+
//!
478498
//! [`Adapter`]: adapter::Adapter
479499
//! [`Address`]: primitives::Address
480500
//! [`AllowedKey`]: primitives::analytics::query::AllowedKey
@@ -505,9 +525,9 @@
505525
//! [`SuccessResponse`]: primitives::sentry::SuccessResponse
506526
//! [`ValidatorId`]: primitives::ValidatorId
507527
508-
pub use analytics::analytics as get_analytics;
528+
pub use analytics::get_analytics;
509529

510-
pub use cfg::config as get_cfg;
530+
pub use cfg::get_cfg;
511531

512532
// `analytics` module has single request, so we only export this request
513533
mod analytics;

0 commit comments

Comments
 (0)