Skip to content

Commit 38a7a76

Browse files
committed
primitives - BalancesMap - use ValidatorId
1 parent ddfa568 commit 38a7a76

File tree

7 files changed

+221
-134
lines changed

7 files changed

+221
-134
lines changed

primitives/src/balances_map.rs

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,69 @@
11
use std::collections::BTreeMap;
22

3-
use crate::BigNum;
4-
use serde_hex::{SerHexSeq, StrictPfx};
3+
use crate::{BigNum, ValidatorId};
54
use std::collections::btree_map::{Entry, Iter, Values};
65

7-
use serde::{Deserialize, Serialize};
6+
use serde::{ser::SerializeMap, Deserialize, Serialize, Serializer};
87
use std::iter::FromIterator;
8+
use std::ops::Index;
99

10-
#[derive(Debug, Clone, Serialize, Deserialize, PartialOrd, Ord, PartialEq, Eq)]
10+
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq)]
1111
#[serde(transparent)]
12-
pub struct BalancesKey(#[serde(with = "SerHexSeq::<StrictPfx>")] Vec<u8>);
13-
impl AsRef<[u8]> for BalancesKey {
14-
fn as_ref(&self) -> &[u8] {
15-
&self.0
16-
}
17-
}
12+
pub struct BalancesMap(BTreeMap<ValidatorId, BigNum>);
1813

19-
type BalancesValue = BigNum;
14+
impl Index<&'_ ValidatorId> for BalancesMap {
15+
type Output = BigNum;
2016

21-
#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq, Eq)]
22-
#[serde(transparent)]
23-
pub struct BalancesMap(BTreeMap<BalancesKey, BalancesValue>);
17+
fn index(&self, index: &ValidatorId) -> &Self::Output {
18+
self.0.index(index)
19+
}
20+
}
2421

2522
impl BalancesMap {
26-
pub fn iter(&self) -> Iter<'_, BalancesKey, BalancesValue> {
23+
pub fn iter(&self) -> Iter<'_, ValidatorId, BigNum> {
2724
self.0.iter()
2825
}
2926

30-
pub fn values(&self) -> Values<'_, BalancesKey, BalancesValue> {
27+
pub fn values(&self) -> Values<'_, ValidatorId, BigNum> {
3128
self.0.values()
3229
}
3330

34-
pub fn get(&self, key: &BalancesKey) -> Option<&BalancesValue> {
31+
pub fn get(&self, key: &ValidatorId) -> Option<&BigNum> {
3532
self.0.get(key)
3633
}
3734

38-
pub fn entry(&mut self, key: BalancesKey) -> Entry<'_, BalancesKey, BalancesValue> {
35+
pub fn entry(&mut self, key: ValidatorId) -> Entry<'_, ValidatorId, BigNum> {
3936
self.0.entry(key)
4037
}
4138

42-
pub fn insert(&mut self, key: BalancesKey, value: BalancesValue) -> Option<BalancesValue> {
39+
pub fn insert(&mut self, key: ValidatorId, value: BigNum) -> Option<BigNum> {
4340
self.0.insert(key, value)
4441
}
4542
}
4643

47-
impl<K: AsRef<[u8]>> FromIterator<(K, BalancesValue)> for BalancesMap {
48-
fn from_iter<I: IntoIterator<Item = (K, BalancesValue)>>(iter: I) -> Self {
44+
impl FromIterator<(ValidatorId, BigNum)> for BalancesMap {
45+
fn from_iter<I: IntoIterator<Item = (ValidatorId, BigNum)>>(iter: I) -> Self {
4946
// @TODO: Is there better way to do this?
50-
let btree_map: BTreeMap<BalancesKey, BalancesValue> = iter
51-
.into_iter()
52-
.map(|(k, v)| (BalancesKey(k.as_ref().to_vec()), v))
53-
.collect();
47+
let btree_map: BTreeMap<ValidatorId, BigNum> = iter.into_iter().collect();
5448

5549
BalancesMap(btree_map)
5650
}
5751
}
5852

53+
impl Serialize for BalancesMap {
54+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
55+
where
56+
S: Serializer,
57+
{
58+
let mut map = serializer.serialize_map(Some(self.0.len()))?;
59+
60+
for (key, big_num) in self.0.iter() {
61+
map.serialize_entry(&key.to_hex_prefix_string(), big_num)?;
62+
}
63+
map.end()
64+
}
65+
}
66+
5967
#[cfg(test)]
6068
mod test {
6169
use super::*;

primitives/src/sentry.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ pub struct EventAggregate {
7474
#[serde(rename_all = "camelCase")]
7575
pub struct AggregateEvents {
7676
#[serde(default, skip_serializing_if = "Option::is_none")]
77-
pub event_counts: Option<HashMap<String, BigNum>>,
78-
pub event_payouts: HashMap<String, BigNum>,
77+
pub event_counts: Option<HashMap<ValidatorId, BigNum>>,
78+
pub event_payouts: HashMap<ValidatorId, BigNum>,
7979
}
8080

8181
#[derive(Debug, Serialize, Deserialize)]

primitives/src/validator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pub enum ValidatorError {
1414
InvalidTransition,
1515
}
1616

17-
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
17+
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1818
#[serde(transparent)]
1919
pub struct ValidatorId(#[serde(with = "SerHex::<StrictPfx>")] [u8; 20]);
2020

validator_worker/src/core/events.rs

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,9 @@ mod test {
7777
use chrono::Utc;
7878

7979
use primitives::util::tests::prep_db::{
80-
DUMMY_CHANNEL, DUMMY_VALIDATOR_FOLLOWER, DUMMY_VALIDATOR_LEADER,
80+
DUMMY_CHANNEL, DUMMY_VALIDATOR_FOLLOWER, DUMMY_VALIDATOR_LEADER, IDS,
8181
};
82-
use primitives::{Channel, ChannelSpec, ValidatorDesc};
82+
use primitives::{Channel, ChannelSpec, ValidatorDesc, ValidatorId};
8383

8484
use super::*;
8585

@@ -102,10 +102,12 @@ mod test {
102102
};
103103
channel.spec.validators = (leader, follower).into();
104104

105-
let balances_before_fees: BalancesMap =
106-
vec![("a".to_string(), 100.into()), ("b".to_string(), 200.into())]
107-
.into_iter()
108-
.collect();
105+
let balances_before_fees: BalancesMap = vec![
106+
(IDS["publisher"].clone(), 100.into()),
107+
(IDS["publisher2"].clone(), 200.into()),
108+
]
109+
.into_iter()
110+
.collect();
109111

110112
let acc = Accounting {
111113
last_event_aggregate: Utc::now(),
@@ -114,16 +116,17 @@ mod test {
114116
};
115117

116118
let (balances, new_accounting) =
117-
merge_aggrs(&acc, &[gen_ev_aggr(5, "a")], &channel).expect("Something went wrong");
119+
merge_aggrs(&acc, &[gen_ev_aggr(5, &IDS["publisher"])], &channel)
120+
.expect("Something went wrong");
118121

119122
assert_eq!(balances, new_accounting.balances, "balances is the same");
120123
assert_eq!(
121-
new_accounting.balances_before_fees["a"],
124+
new_accounting.balances_before_fees[&IDS["publisher"]],
122125
150.into(),
123126
"balance of recipient incremented accordingly"
124127
);
125128
assert_eq!(
126-
new_accounting.balances["a"],
129+
new_accounting.balances[&IDS["publisher"]],
127130
148.into(),
128131
"balanceAfterFees is ok"
129132
);
@@ -150,10 +153,12 @@ mod test {
150153
..DUMMY_CHANNEL.clone()
151154
};
152155

153-
let balances_before_fees: BalancesMap =
154-
vec![("a".to_string(), 100.into()), ("b".to_string(), 200.into())]
155-
.into_iter()
156-
.collect();
156+
let balances_before_fees: BalancesMap = vec![
157+
(IDS["publisher"].clone(), 100.into()),
158+
(IDS["publisher2"].clone(), 200.into()),
159+
]
160+
.into_iter()
161+
.collect();
157162

158163
let acc = Accounting {
159164
last_event_aggregate: Utc::now(),
@@ -162,21 +167,22 @@ mod test {
162167
};
163168

164169
let (balances, new_accounting) =
165-
merge_aggrs(&acc, &[gen_ev_aggr(1_001, "a")], &channel).expect("Something went wrong");
170+
merge_aggrs(&acc, &[gen_ev_aggr(1_001, &IDS["publisher"])], &channel)
171+
.expect("Something went wrong");
166172

167173
assert_eq!(balances, new_accounting.balances, "balances is the same");
168174
assert_eq!(
169-
new_accounting.balances_before_fees["a"],
175+
new_accounting.balances_before_fees[&IDS["publisher"]],
170176
9_800.into(),
171177
"balance of recipient incremented accordingly"
172178
);
173179
assert_eq!(
174-
new_accounting.balances_before_fees["b"],
180+
new_accounting.balances_before_fees[&IDS["publisher2"]],
175181
200.into(),
176182
"balances of non-recipient remains the same"
177183
);
178184
assert_eq!(
179-
new_accounting.balances["a"],
185+
new_accounting.balances[&IDS["publisher"]],
180186
9_702.into(),
181187
"balanceAfterFees is ok"
182188
);
@@ -192,14 +198,14 @@ mod test {
192198
);
193199
}
194200

195-
fn gen_ev_aggr(count: u64, recipient: &str) -> EventAggregate {
201+
fn gen_ev_aggr(count: u64, recipient: &ValidatorId) -> EventAggregate {
196202
let aggregate_events = AggregateEvents {
197203
event_counts: Some(
198-
vec![(recipient.to_string(), count.into())]
204+
vec![(recipient.clone(), count.into())]
199205
.into_iter()
200206
.collect(),
201207
),
202-
event_payouts: vec![(recipient.to_string(), (count * 10).into())]
208+
event_payouts: vec![(recipient.clone(), (count * 10).into())]
203209
.into_iter()
204210
.collect(),
205211
};

validator_worker/src/core/fees.rs

Lines changed: 41 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ fn distribute_fee<'a>(
7777

7878
if fee_rounded > 0.into() {
7979
let addr = validator.fee_addr.as_ref().unwrap_or(&validator.id);
80-
let entry = balances.entry(addr.to_string()).or_insert_with(|| 0.into());
80+
let entry = balances.entry(addr.to_owned()).or_insert_with(|| 0.into());
8181

8282
*entry += &fee_rounded;
8383
}
@@ -105,9 +105,9 @@ mod test {
105105
#[test]
106106
fn case_1_three_values() {
107107
let balances_map: BalancesMap = vec![
108-
("a".to_string(), 1001.into()),
109-
("b".to_string(), 3124.into()),
110-
("c".to_string(), 122.into()),
108+
(IDS["publisher"].clone(), 1001.into()),
109+
(IDS["publisher2"].clone(), 3124.into()),
110+
(IDS["tester"].clone(), 122.into()),
111111
]
112112
.into_iter()
113113
.collect();
@@ -118,9 +118,9 @@ mod test {
118118
#[test]
119119
fn case_2_three_simple_values() {
120120
let balances_map: BalancesMap = vec![
121-
("a".to_string(), 1.into()),
122-
("b".to_string(), 2.into()),
123-
("c".to_string(), 3.into()),
121+
(IDS["publisher"].clone(), 1.into()),
122+
(IDS["publisher2"].clone(), 2.into()),
123+
(IDS["tester"].clone(), 3.into()),
124124
]
125125
.into_iter()
126126
.collect();
@@ -130,7 +130,7 @@ mod test {
130130

131131
#[test]
132132
fn case_3_one_value() {
133-
let balances_map = vec![("a".to_string(), BigNum::from(1))]
133+
let balances_map = vec![(IDS["publisher"].clone(), BigNum::from(1))]
134134
.into_iter()
135135
.collect();
136136

@@ -140,8 +140,8 @@ mod test {
140140
#[test]
141141
fn case_4_two_values() {
142142
let balances_map = vec![
143-
("a".to_string(), 1.into()),
144-
("b".to_string(), 99_999.into()),
143+
(IDS["publisher"].clone(), 1.into()),
144+
(IDS["publisher2"].clone(), 99_999.into()),
145145
]
146146
.into_iter()
147147
.collect();
@@ -199,17 +199,17 @@ mod test {
199199
#[test]
200200
fn case_1_partially_distributed() {
201201
let balances_map = vec![
202-
("a".to_string(), 1_000.into()),
203-
("b".to_string(), 1_200.into()),
202+
(IDS["publisher"].clone(), 1_000.into()),
203+
(IDS["publisher2"].clone(), 1_200.into()),
204204
]
205205
.into_iter()
206206
.collect();
207207

208208
let expected_balances: BalancesMap = vec![
209-
("a".to_string(), 990.into()),
210-
("b".to_string(), 1_188.into()),
211-
(IDS.get("leader").unwrap().to_string(), 11.into()),
212-
(IDS.get("follower").unwrap().to_string(), 11.into()),
209+
(IDS["publisher"].clone(), 990.into()),
210+
(IDS["publisher2"].clone(), 1_188.into()),
211+
(IDS["leader"].clone(), 11.into()),
212+
(IDS["follower"].clone(), 11.into()),
213213
]
214214
.into_iter()
215215
.collect();
@@ -230,18 +230,18 @@ mod test {
230230
#[test]
231231
fn case_2_partially_distributed_with_validator_in_the_input_balances_map() {
232232
let balances_map = vec![
233-
("a".to_string(), 100.into()),
234-
("b".to_string(), 2_000.into()),
235-
(IDS.get("leader").unwrap().to_string(), 200.into()),
233+
(IDS["publisher"].clone(), 100.into()),
234+
(IDS["publisher2"].clone(), 2_000.into()),
235+
(IDS["leader"].clone(), 200.into()),
236236
]
237237
.into_iter()
238238
.collect();
239239

240240
let expected_balances: BalancesMap = vec![
241-
("a".to_string(), 99.into()),
242-
("b".to_string(), 1_980.into()),
243-
(IDS.get("leader").unwrap().to_string(), 209.into()),
244-
(IDS.get("follower").unwrap().to_string(), 11.into()),
241+
(IDS["publisher"].clone(), 99.into()),
242+
(IDS["publisher2"].clone(), 1_980.into()),
243+
(IDS["leader"].clone(), 209.into()),
244+
(IDS["follower"].clone(), 11.into()),
245245
]
246246
.into_iter()
247247
.collect();
@@ -263,23 +263,23 @@ mod test {
263263
/// also testing the rounding error correction
264264
fn case_3_fully_distributed() {
265265
let balances_map = vec![
266-
("a".to_string(), 105.into()),
267-
("b".to_string(), 195.into()),
268-
("c".to_string(), 700.into()),
269-
("d".to_string(), 5_000.into()),
270-
("e".to_string(), 4_000.into()),
266+
(IDS["publisher"].clone(), 105.into()),
267+
(IDS["publisher2"].clone(), 195.into()),
268+
(IDS["tester"].clone(), 700.into()),
269+
(IDS["user"].clone(), 5_000.into()),
270+
(IDS["creator"].clone(), 4_000.into()),
271271
]
272272
.into_iter()
273273
.collect();
274274

275275
let expected_balances: BalancesMap = vec![
276-
("a".to_string(), 103.into()),
277-
("b".to_string(), 193.into()),
278-
("c".to_string(), 693.into()),
279-
("d".to_string(), 4_950.into()),
280-
("e".to_string(), 3_960.into()),
281-
(IDS.get("leader").unwrap().to_string(), 51.into()),
282-
(IDS.get("follower").unwrap().to_string(), 50.into()),
276+
(IDS["publisher"].clone(), 103.into()),
277+
(IDS["publisher2"].clone(), 193.into()),
278+
(IDS["tester"].clone(), 693.into()),
279+
(IDS["user"].clone(), 4_950.into()),
280+
(IDS["creator"].clone(), 3_960.into()),
281+
(IDS["leader"].clone(), 51.into()),
282+
(IDS["follower"].clone(), 50.into()),
283283
]
284284
.into_iter()
285285
.collect();
@@ -300,9 +300,12 @@ mod test {
300300

301301
#[test]
302302
fn errors_when_fees_larger_that_deposit() {
303-
let balances_map = vec![("a".to_string(), 10.into()), ("b".to_string(), 10.into())]
304-
.into_iter()
305-
.collect();
303+
let balances_map = vec![
304+
(IDS["publisher"].clone(), 10.into()),
305+
(IDS["publisher2"].clone(), 10.into()),
306+
]
307+
.into_iter()
308+
.collect();
306309

307310
let leader = ValidatorDesc {
308311
fee: 600.into(),

0 commit comments

Comments
 (0)