Skip to content

Commit 21287ed

Browse files
authored
Issue #75 Validator MemoryChannelRepository (#91)
* validator - persistence - channel - memory: - add module - add MemoryChannelRepository struct - impl `all()` * validator - persistence - channel - api - no need for clone * validator - persistence - channel - export Api & Memory repositories * domain - channel - SpecValidators - add `new()` * validator - Cargo.toml - add `fixtures` feature for `domain` * [+test] validator - persistence - channel - memory - add tests & fix typos * domain - channel - fixtures - create a ValidatorsOption to clarify & clean `get_channel_spec` * refactor to use the `ValidatorsOption` for `get_channel_spec` * domain - validator - ValidatorId impl `AsRef<str>` & `Display` * validator - channel - ChannelRepository - use `ValidatorId` for `all()`
1 parent 0c0e322 commit 21287ed

File tree

12 files changed

+153
-27
lines changed

12 files changed

+153
-27
lines changed

adapter/src/sanity.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ impl error::Error for SanityError {
105105
mod test {
106106
use time::Duration;
107107

108-
use domain::channel::fixtures::get_channel_spec;
108+
use domain::channel::fixtures::{get_channel_spec, ValidatorsOption};
109109
use domain::fixtures::{get_channel, get_validator};
110110

111111
use crate::adapter::ConfigBuilder;
@@ -250,7 +250,7 @@ mod test {
250250
get_validator("my leader", Some(10.into())),
251251
get_validator("my follower", Some(15.into())),
252252
];
253-
let spec = get_channel_spec("channel_1", Some(validators.into()));
253+
let spec = get_channel_spec(ValidatorsOption::SpecValidators(validators.into()));
254254
let channel = get_channel("channel_1", &None, Some(spec));
255255

256256
// as identity use the leader, otherwise we won't pass the AdapterNotIncluded check

domain/src/channel.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ impl fmt::Display for ChannelId {
3030
/// let channel_hex_string = format!("{}", channel_id);
3131
/// assert_eq!("0x061d5e2a67d0a9a10f1c732bca12a676d83f79663a396f7d87b3e30b9b411088", &channel_hex_string);
3232
/// ```
33-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
33+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3434
let hex_string = SerHex::<StrictPfx>::into_hex(&self.bytes).unwrap();
3535
write!(f, "{}", hex_string)
3636
}
@@ -183,6 +183,10 @@ impl<'a> SpecValidator<'a> {
183183
pub struct SpecValidators([ValidatorDesc; 2]);
184184

185185
impl SpecValidators {
186+
pub fn new(leader: ValidatorDesc, follower: ValidatorDesc) -> Self {
187+
Self([leader, follower])
188+
}
189+
186190
pub fn leader(&self) -> &ValidatorDesc {
187191
&self.0[0]
188192
}

domain/src/channel_fixtures.rs

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::fixtures::{get_targeting_tags, get_validator};
77
use crate::test_util;
88
use crate::BigNum;
99

10-
use super::{Channel, ChannelId, ChannelSpec, SpecValidators};
10+
use super::{Channel, ChannelId, ChannelSpec, SpecValidators, ValidatorDesc};
1111

1212
/// It will get the length of channel_id bytes and will fill enough bytes in front
1313
/// If > 32 bytes &str is passed it will `panic!`
@@ -38,7 +38,11 @@ pub fn get_channel(
3838
});
3939
let creator = <Faker as Name>::name();
4040
let deposit_asset = get_asset();
41-
let spec = spec.unwrap_or_else(|| get_channel_spec(id, None));
41+
let spec = spec.unwrap_or_else(|| {
42+
get_channel_spec(ValidatorsOption::Generate {
43+
validators_prefix: id,
44+
})
45+
});
4246

4347
Channel {
4448
id: channel_id,
@@ -63,15 +67,27 @@ pub fn get_channels(count: usize, valid_until_ge: Option<DateTime<Utc>>) -> Vec<
6367
.collect()
6468
}
6569

66-
pub fn get_channel_spec(prefix: &str, validators_option: Option<SpecValidators>) -> ChannelSpec {
70+
pub enum ValidatorsOption<'a> {
71+
Pair {
72+
leader: ValidatorDesc,
73+
follower: ValidatorDesc,
74+
},
75+
SpecValidators(SpecValidators),
76+
Generate {
77+
validators_prefix: &'a str,
78+
},
79+
}
80+
81+
pub fn get_channel_spec(validators_option: ValidatorsOption<'_>) -> ChannelSpec {
6782
use crate::EventSubmission;
6883
use test_util::take_one;
6984

7085
let validators = match validators_option {
71-
Some(validators) => validators,
72-
None => [
73-
get_validator(&format!("{} leader", prefix), None),
74-
get_validator(&format!("{} follower", prefix), None),
86+
ValidatorsOption::Pair { leader, follower } => [leader, follower].into(),
87+
ValidatorsOption::SpecValidators(spec_validators) => spec_validators,
88+
ValidatorsOption::Generate { validators_prefix } => [
89+
get_validator(&format!("{} leader", validators_prefix), None),
90+
get_validator(&format!("{} follower", validators_prefix), None),
7591
]
7692
.into(),
7793
};

domain/src/validator.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::convert::TryFrom;
2+
use std::fmt;
23

34
use serde::{Deserialize, Serialize};
45

@@ -21,6 +22,18 @@ impl TryFrom<&str> for ValidatorId {
2122
}
2223
}
2324

25+
impl AsRef<str> for ValidatorId {
26+
fn as_ref(&self) -> &str {
27+
self.0.as_str()
28+
}
29+
}
30+
31+
impl fmt::Display for ValidatorId {
32+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33+
write!(f, "{}", self.0)
34+
}
35+
}
36+
2437
#[derive(Serialize, Deserialize, Debug, Clone)]
2538
#[serde(rename_all = "camelCase")]
2639
pub struct ValidatorDesc {
@@ -38,12 +51,15 @@ pub mod fixtures {
3851

3952
use super::ValidatorDesc;
4053

41-
pub fn get_validator(validator_id: &str, fee: Option<BigNum>) -> ValidatorDesc {
54+
pub fn get_validator<V: AsRef<str>>(validator_id: V, fee: Option<BigNum>) -> ValidatorDesc {
4255
let fee = fee.unwrap_or_else(|| BigNum::from(<Faker as Number>::between(1, 13)));
43-
let url = format!("http://{}-validator-url.com/validator", validator_id);
56+
let url = format!(
57+
"http://{}-validator-url.com/validator",
58+
validator_id.as_ref()
59+
);
4460

4561
ValidatorDesc {
46-
id: validator_id.to_string(),
62+
id: validator_id.as_ref().to_string(),
4763
url,
4864
fee,
4965
}

sentry/src/infrastructure/persistence/channel/memory_test.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,8 @@ fn listing_channels_can_handles_validator_filtration_and_keeps_valid_until_filtr
134134
get_validator("validator-2", None),
135135
]
136136
.into();
137-
let channel_2_spec = get_channel_spec("channel 2", Some(validators.clone()));
138-
let channel_5_spec = get_channel_spec("channel 5", Some(validators));
137+
let channel_2_spec = get_channel_spec(ValidatorsOption::SpecValidators(validators.clone()));
138+
let channel_5_spec = get_channel_spec(ValidatorsOption::SpecValidators(validators));
139139

140140
let channels = [
141141
get_channel("channel 1", &None, None),

validator/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ path = "src/lib.rs"
1010

1111
[dependencies]
1212
# Domain
13-
domain = { version = "0.1", path = "../domain", features = ["repositories"] }
13+
domain = { version = "0.1", path = "../domain", features = ["repositories", "fixtures"] }
1414
adapter = { version = "0.1", path = "../adapter", features = ["dummy-adapter"] }
1515
memory-repository = { version = "0.1", path = "../memory-repository" }
1616
chrono = { version = "0.4", features = ["serde"] }

validator/src/application/worker.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ pub use self::infinite::InfiniteWorker;
22
pub use self::single::TickWorker;
33

44
pub mod single {
5+
use std::convert::TryFrom;
56
use std::sync::Arc;
67
use std::time::Duration;
78

89
use futures::compat::Future01CompatExt;
910
use futures::future::{FutureExt, TryFutureExt};
1011
use tokio::util::FutureExt as TokioFutureExt;
1112

12-
use domain::{Channel, SpecValidator};
13+
use domain::{Channel, SpecValidator, ValidatorId};
1314

1415
use crate::application::validator::{Follower, Leader};
1516
use crate::domain::{ChannelRepository, Validator, Worker, WorkerFuture};
@@ -28,7 +29,10 @@ pub mod single {
2829
/// Single tick worker
2930
impl TickWorker {
3031
pub async fn tick(self) -> Result<(), ()> {
31-
let all_channels = await!(self.channel_repository.all(&self.identity));
32+
// @TODO: Update once we figure out if ValidatorId can fail from a &str
33+
let validator_id = ValidatorId::try_from(self.identity.as_str())
34+
.expect("ValidatorId doesn't have a failing case right now");
35+
let all_channels = await!(self.channel_repository.all(&validator_id));
3236

3337
match all_channels {
3438
Ok(channels) => {

validator/src/domain/channel.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
use domain::{Channel, RepositoryFuture};
1+
use domain::{Channel, RepositoryFuture, ValidatorId};
22

33
pub trait ChannelRepository: Send + Sync {
44
/// Returns list of all channels, based on the passed validator identity
5-
fn all(&self, identity: &str) -> RepositoryFuture<Vec<Channel>>;
5+
fn all(&self, identity: &ValidatorId) -> RepositoryFuture<Vec<Channel>>;
66
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
1+
pub use self::api::ApiChannelRepository;
2+
pub use self::memory::MemoryChannelRepository;
3+
14
pub mod api;
5+
pub mod memory;

validator/src/infrastructure/persistence/channel/api.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
11
use futures::{FutureExt, TryFutureExt};
22

3-
use domain::{Channel, RepositoryFuture};
3+
use domain::{Channel, RepositoryFuture, ValidatorId};
44

55
use crate::domain::channel::ChannelRepository;
66
use crate::infrastructure::persistence::api::ApiPersistenceError;
77
use crate::infrastructure::sentry::SentryApi;
88

9-
#[derive(Clone)]
109
// @TODO: make pub(crate)
1110
pub struct ApiChannelRepository {
1211
pub sentry: SentryApi,
1312
}
1413

1514
impl ChannelRepository for ApiChannelRepository {
16-
fn all(&self, identity: &str) -> RepositoryFuture<Vec<Channel>> {
15+
fn all(&self, identity: &ValidatorId) -> RepositoryFuture<Vec<Channel>> {
1716
self.sentry
1817
.clone()
19-
.all_channels(Some(identity.to_string()))
18+
.all_channels(Some(identity))
2019
// @TODO: Error handling
2120
.map_err(|_error| ApiPersistenceError::Reading.into())
2221
.boxed()

0 commit comments

Comments
 (0)