Skip to content

Commit 387fb4b

Browse files
authored
Merge pull request #423 from AdExNetwork/new-state-balances-update
primitives - Balances & BalancesState
2 parents a2144eb + 3cb833e commit 387fb4b

17 files changed

+195
-541
lines changed

primitives/src/sentry/accounting.rs renamed to primitives/src/balances.rs

Lines changed: 33 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,14 @@
11
use std::{convert::TryFrom, marker::PhantomData};
22

3-
use crate::{balances_map::UnifiedMap, channel_v5::Channel, Address, UnifiedNum};
4-
use chrono::{DateTime, Utc};
5-
use serde::{Deserialize, Deserializer, Serialize};
3+
use crate::{Address, UnifiedMap, UnifiedNum};
4+
use serde::{de::DeserializeOwned, Deserialize, Serialize};
65
use thiserror::Error;
76

8-
#[derive(Serialize, Debug, Clone, PartialEq, Eq)]
9-
#[serde(rename_all = "camelCase")]
10-
pub struct Accounting<S: BalancesState> {
11-
pub channel: Channel,
12-
#[serde(flatten)]
13-
pub balances: Balances<S>,
14-
pub updated: Option<DateTime<Utc>>,
15-
pub created: DateTime<Utc>,
16-
}
17-
187
#[derive(Serialize, Debug, Clone, PartialEq, Eq, Default)]
198
#[serde(rename_all = "camelCase")]
20-
pub struct Balances<S> {
9+
pub struct Balances<S: BalancesState> {
2110
pub earners: UnifiedMap,
2211
pub spenders: UnifiedMap,
23-
#[serde(skip_serializing, skip_deserializing)]
2412
state: PhantomData<S>,
2513
}
2614

@@ -82,6 +70,14 @@ impl<S: BalancesState> Balances<S> {
8270
.entry(earner)
8371
.or_insert_with(UnifiedNum::default);
8472
}
73+
74+
pub fn into_unchecked(self) -> Balances<UncheckedState> {
75+
Balances {
76+
earners: self.earners,
77+
spenders: self.spenders,
78+
state: PhantomData::default(),
79+
}
80+
}
8581
}
8682

8783
#[derive(Debug, Error)]
@@ -103,15 +99,25 @@ pub enum Error {
10399
},
104100
}
105101

106-
pub trait BalancesState {}
102+
pub trait BalancesState: std::fmt::Debug + Eq + Clone + Serialize + DeserializeOwned {
103+
fn from_unchecked(balances: Balances<UncheckedState>) -> Result<Balances<Self>, Error>;
104+
}
107105

108-
#[derive(Debug, Clone, PartialEq, Eq, Default)]
106+
#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
109107
pub struct CheckedState;
110-
impl BalancesState for CheckedState {}
108+
impl BalancesState for CheckedState {
109+
fn from_unchecked(balances: Balances<UncheckedState>) -> Result<Balances<Self>, Error> {
110+
balances.check()
111+
}
112+
}
111113

112-
#[derive(Debug, Clone, PartialEq, Eq, Default)]
114+
#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
113115
pub struct UncheckedState;
114-
impl BalancesState for UncheckedState {}
116+
impl BalancesState for UncheckedState {
117+
fn from_unchecked(balances: Balances<Self>) -> Result<Balances<Self>, Error> {
118+
Ok(balances)
119+
}
120+
}
115121

116122
impl TryFrom<Balances<UncheckedState>> for Balances<CheckedState> {
117123
type Error = Error;
@@ -123,82 +129,30 @@ impl TryFrom<Balances<UncheckedState>> for Balances<CheckedState> {
123129

124130
/// This modules implements the needed non-generic structs that help with Deserialization of the `Balances<S>`
125131
mod de {
126-
use super::*;
127-
128-
#[derive(Deserialize)]
129-
struct DeserializeAccounting {
130-
pub channel: Channel,
131-
#[serde(flatten)]
132-
pub balances: DeserializeBalances,
133-
pub created: DateTime<Utc>,
134-
pub updated: Option<DateTime<Utc>>,
135-
}
132+
use serde::Deserializer;
136133

137-
impl<'de> Deserialize<'de> for Accounting<UncheckedState> {
138-
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
139-
where
140-
D: Deserializer<'de>,
141-
{
142-
let de_acc = DeserializeAccounting::deserialize(deserializer)?;
143-
144-
Ok(Self {
145-
channel: de_acc.channel,
146-
balances: Balances::<UncheckedState>::try_from(de_acc.balances)
147-
.map_err(serde::de::Error::custom)?,
148-
created: de_acc.created,
149-
updated: de_acc.updated,
150-
})
151-
}
152-
}
153-
154-
impl<'de> Deserialize<'de> for Accounting<CheckedState> {
155-
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
156-
where
157-
D: Deserializer<'de>,
158-
{
159-
let unchecked_acc = Accounting::<UncheckedState>::deserialize(deserializer)?;
160-
161-
Ok(Self {
162-
channel: unchecked_acc.channel,
163-
balances: unchecked_acc
164-
.balances
165-
.check()
166-
.map_err(serde::de::Error::custom)?,
167-
created: unchecked_acc.created,
168-
updated: unchecked_acc.updated,
169-
})
170-
}
171-
}
134+
use super::*;
172135

173136
#[derive(Deserialize, Debug, Clone, PartialEq, Eq)]
174137
struct DeserializeBalances {
175138
pub earners: UnifiedMap,
176139
pub spenders: UnifiedMap,
177140
}
178141

179-
impl<'de> Deserialize<'de> for Balances<CheckedState> {
180-
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
181-
where
182-
D: Deserializer<'de>,
183-
{
184-
let unchecked_balances = Balances::<UncheckedState>::deserialize(deserializer)?;
185-
186-
unchecked_balances.check().map_err(serde::de::Error::custom)
187-
}
188-
}
189-
190-
impl<'de> Deserialize<'de> for Balances<UncheckedState> {
142+
impl<'de, S: BalancesState> Deserialize<'de> for Balances<S> {
191143
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
192144
where
193145
D: Deserializer<'de>,
194146
{
195147
let deser_balances = DeserializeBalances::deserialize(deserializer)?;
196148

197-
Ok(Balances {
149+
let unchecked_balances = Balances {
198150
earners: deser_balances.earners,
199151
spenders: deser_balances.spenders,
200152
state: PhantomData::<UncheckedState>::default(),
201-
})
153+
};
154+
155+
S::from_unchecked(unchecked_balances).map_err(serde::de::Error::custom)
202156
}
203157
}
204158

primitives/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ pub use self::{
66
ad_slot::AdSlot,
77
ad_unit::AdUnit,
88
address::Address,
9+
balances::Balances,
910
balances_map::{BalancesMap, UnifiedMap},
1011
big_num::BigNum,
1112
campaign::{Campaign, CampaignId},
@@ -22,6 +23,7 @@ mod ad_unit;
2223
pub mod adapter;
2324
pub mod address;
2425
pub mod analytics;
26+
pub mod balances;
2527
pub mod balances_map;
2628
pub mod big_num;
2729
pub mod campaign;

primitives/src/sentry.rs

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,29 @@
11
use crate::{
2+
balances::BalancesState,
3+
channel_v5::Channel as ChannelV5,
24
validator::{ApproveState, Heartbeat, MessageTypes, NewState, Type as MessageType},
3-
Address, BigNum, Channel, ChannelId, ValidatorId, IPFS,
5+
Address, Balances, BigNum, Channel, ChannelId, ValidatorId, IPFS,
46
};
57
use chrono::{DateTime, Utc};
68
use serde::{Deserialize, Serialize};
79
use std::{collections::HashMap, fmt, hash::Hash};
810

9-
pub mod accounting;
11+
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
12+
#[serde(rename_all = "camelCase")]
13+
pub struct Accounting<S: BalancesState> {
14+
pub channel: ChannelV5,
15+
#[serde(flatten, bound = "S: BalancesState")]
16+
pub balances: Balances<S>,
17+
pub updated: Option<DateTime<Utc>>,
18+
pub created: DateTime<Utc>,
19+
}
1020

1121
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
1222
#[serde(rename_all = "camelCase")]
13-
pub struct LastApproved {
23+
pub struct LastApproved<S: BalancesState> {
1424
/// NewState can be None if the channel is brand new
15-
pub new_state: Option<MessageResponse<NewState>>,
25+
#[serde(bound = "S: BalancesState")]
26+
pub new_state: Option<MessageResponse<NewState<S>>>,
1627
/// ApproveState can be None if the channel is brand new
1728
pub approve_state: Option<MessageResponse<ApproveState>>,
1829
}
@@ -53,7 +64,7 @@ pub mod message {
5364
}
5465

5566
impl<T: Type> TryFrom<MessageTypes> for Message<T> {
56-
type Error = MessageTypeError<T>;
67+
type Error = MessageError<T>;
5768

5869
fn try_from(value: MessageTypes) -> Result<Self, Self::Error> {
5970
<T as TryFrom<MessageTypes>>::try_from(value).map(Self)
@@ -81,8 +92,7 @@ pub mod message {
8192
"type":"ApproveState",
8293
"stateRoot":"4739522efc1e81499541621759dadb331eaf08829d6a3851b4b654dfaddc9935",
8394
"signature":"0x00128a39b715e87475666c3220fc0400bf34a84d24f77571d2b4e1e88b141d52305438156e526ff4fe96b7a13e707ab2f6f3ca00bd928dabc7f516b56cfe6fd61c",
84-
"isHealthy":true,
85-
"exhausted":false
95+
"isHealthy":true
8696
},
8797
"received":"2021-01-05T14:00:48.549Z"
8898
});
@@ -96,7 +106,6 @@ pub mod message {
96106
state_root: "4739522efc1e81499541621759dadb331eaf08829d6a3851b4b654dfaddc9935".to_string(),
97107
signature: "0x00128a39b715e87475666c3220fc0400bf34a84d24f77571d2b4e1e88b141d52305438156e526ff4fe96b7a13e707ab2f6f3ca00bd928dabc7f516b56cfe6fd61c".to_string(),
98108
is_healthy: true,
99-
exhausted: false,
100109
}),
101110
};
102111

@@ -184,8 +193,9 @@ pub struct ChannelListResponse {
184193

185194
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
186195
#[serde(rename_all = "camelCase")]
187-
pub struct LastApprovedResponse {
188-
pub last_approved: Option<LastApproved>,
196+
pub struct LastApprovedResponse<S: BalancesState> {
197+
#[serde(bound = "S: BalancesState")]
198+
pub last_approved: Option<LastApproved<S>>,
189199
/// None -> withHeartbeat=true wasn't passed
190200
/// Some(vec![]) (empty vec) or Some(heartbeats) - withHeartbeat=true was passed
191201
#[serde(default, skip_serializing_if = "Option::is_none")]

0 commit comments

Comments
 (0)