Skip to content

Commit 0b3d0cc

Browse files
authored
Issue #94 Validator MessageRepository add to specific validator (#97)
* [+test] domain - validator - MessageRepository - change signature of `add` * The `State` as `Adapter` associated type instead of the `Adapter` to impl `State` * run `rustfmt`
1 parent 4bf4a2d commit 0b3d0cc

File tree

7 files changed

+94
-62
lines changed

7 files changed

+94
-62
lines changed

adapter/src/adapter.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,22 +42,27 @@ impl fmt::Display for AdapterError {
4242
}
4343
}
4444

45-
pub trait Adapter: SanityChecker + State {
45+
pub trait Adapter: SanityChecker {
46+
type State: State;
47+
4648
fn config(&self) -> &Config;
4749

4850
fn validate_channel(&self, channel: &Channel) -> AdapterFuture<bool> {
4951
futures::future::ok(Self::check(&self.config(), &channel).is_ok()).boxed()
5052
}
5153

5254
/// Signs the provided state_root
53-
fn sign(&self, state_root: &Self::StateRoot) -> AdapterFuture<Self::Signature>;
55+
fn sign(
56+
&self,
57+
state_root: &<Self::State as State>::StateRoot,
58+
) -> AdapterFuture<<Self::State as State>::Signature>;
5459

5560
/// Verify, based on the signature & state_root, that the signer is the same
5661
fn verify(
5762
&self,
5863
signer: &str,
59-
state_root: &Self::StateRoot,
60-
signature: &Self::Signature,
64+
state_root: &<Self::State as State>::StateRoot,
65+
signature: &<Self::State as State>::Signature,
6166
) -> AdapterFuture<bool>;
6267

6368
/// Gets authentication for specific validator
@@ -66,9 +71,10 @@ pub trait Adapter: SanityChecker + State {
6671
fn signable_state_root(
6772
channel_id: ChannelId,
6873
balance_root: BalanceRoot,
69-
) -> SignableStateRoot<Self::StateRoot>;
74+
) -> SignableStateRoot<<Self::State as State>::StateRoot>;
7075
}
7176

77+
#[derive(Clone)]
7278
pub struct Config {
7379
pub identity: String,
7480
pub validators_whitelist: Vec<String>,

adapter/src/dummy.rs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ impl AsRef<[u8]> for DummyStateRoot {
6363
}
6464
impl Hexable for DummyStateRoot {}
6565

66+
#[derive(Clone)]
67+
pub struct DummyState {}
68+
impl State for DummyState {
69+
type Signature = DummySignature;
70+
type StateRoot = DummyStateRoot;
71+
}
72+
6673
pub struct DummyAdapter<'a> {
6774
pub config: Config,
6875
/// Dummy participants which will be used for
@@ -72,12 +79,9 @@ pub struct DummyAdapter<'a> {
7279

7380
impl SanityChecker for DummyAdapter<'_> {}
7481

75-
impl State for DummyAdapter<'_> {
76-
type Signature = DummySignature;
77-
type StateRoot = DummyStateRoot;
78-
}
79-
8082
impl<'a> Adapter for DummyAdapter<'a> {
83+
type State = DummyState;
84+
8185
fn config(&self) -> &Config {
8286
&self.config
8387
}
@@ -98,7 +102,10 @@ impl<'a> Adapter for DummyAdapter<'a> {
98102
/// assert_eq!(DummySignature::from(expected), actual);
99103
/// # });
100104
/// ```
101-
fn sign(&self, state_root: &Self::StateRoot) -> AdapterFuture<Self::Signature> {
105+
fn sign(
106+
&self,
107+
state_root: &<Self::State as State>::StateRoot,
108+
) -> AdapterFuture<<Self::State as State>::Signature> {
102109
let signature = format!(
103110
"Dummy adapter signature for {} by {}",
104111
state_root.to_hex(),
@@ -125,8 +132,8 @@ impl<'a> Adapter for DummyAdapter<'a> {
125132
fn verify(
126133
&self,
127134
signer: &str,
128-
_state_root: &Self::StateRoot,
129-
signature: &Self::Signature,
135+
_state_root: &<Self::State as State>::StateRoot,
136+
signature: &<Self::State as State>::Signature,
130137
) -> AdapterFuture<bool> {
131138
// select the `identity` and compare it to the signer
132139
// for empty string this will return array with 1 element - an empty string `[""]`
@@ -183,7 +190,7 @@ impl<'a> Adapter for DummyAdapter<'a> {
183190
fn signable_state_root(
184191
channel_id: ChannelId,
185192
balance_root: BalanceRoot,
186-
) -> SignableStateRoot<Self::StateRoot> {
193+
) -> SignableStateRoot<<Self::State as State>::StateRoot> {
187194
let state_root = format!(
188195
"Signable State Root for Adapter channel id {} with balance root {}",
189196
channel_id.to_hex(),

domain/src/channel.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,15 @@ impl From<[ValidatorDesc; 2]> for SpecValidators {
212212
}
213213
}
214214

215+
impl<'a> IntoIterator for &'a SpecValidators {
216+
type Item = &'a ValidatorDesc;
217+
type IntoIter = ::std::vec::IntoIter<Self::Item>;
218+
219+
fn into_iter(self) -> Self::IntoIter {
220+
vec![self.leader(), self.follower()].into_iter()
221+
}
222+
}
223+
215224
#[cfg(any(test, feature = "fixtures"))]
216225
#[path = "./channel_fixtures.rs"]
217226
pub mod fixtures;

domain/src/validator/message.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
66

77
use crate::BalancesMap;
88

9-
pub trait State {
9+
pub trait State: Clone {
1010
type Signature: DeserializeOwned + Serialize + fmt::Display + fmt::Debug + Clone;
1111
type StateRoot: DeserializeOwned + Serialize + fmt::Display + fmt::Debug + Clone;
1212
}
@@ -119,7 +119,7 @@ pub mod fixtures {
119119

120120
use super::*;
121121

122-
#[derive(Serialize, Deserialize, Debug)]
122+
#[derive(Serialize, Deserialize, Debug, Clone)]
123123
pub struct DummyState {}
124124

125125
impl State for DummyState {

validator/src/application/heartbeat.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use domain::{Channel, ChannelId, RepositoryError, ValidatorId};
99

1010
use crate::domain::MessageRepository;
1111

12-
pub struct HeartbeatFactory<A: Adapter + State> {
12+
pub struct HeartbeatFactory<A: Adapter> {
1313
adapter: A,
1414
}
1515

@@ -40,22 +40,25 @@ impl fmt::Display for HeartbeatError {
4040
}
4141
}
4242

43-
impl<A: Adapter + State> HeartbeatFactory<A> {
44-
pub async fn create(&self, state_root: A::StateRoot) -> Result<Heartbeat<A>, HeartbeatError> {
43+
impl<A: Adapter> HeartbeatFactory<A> {
44+
pub async fn create(
45+
&self,
46+
state_root: <A::State as State>::StateRoot,
47+
) -> Result<Heartbeat<A::State>, HeartbeatError> {
4548
let signature = await!(self.adapter.sign(&state_root)).map_err(HeartbeatError::Adapter)?;
4649

4750
Ok(Heartbeat::new(signature, state_root))
4851
}
4952
}
5053

51-
pub struct HeartbeatSender<A: Adapter + State> {
52-
message_repository: Box<dyn MessageRepository<A>>,
54+
pub struct HeartbeatSender<A: Adapter> {
55+
message_repository: Box<dyn MessageRepository<A::State>>,
5356
adapter: A,
5457
factory: HeartbeatFactory<A>,
5558
// @TODO: Add config value for Heartbeat send frequency
5659
}
5760

58-
impl<A: Adapter + State> HeartbeatSender<A> {
61+
impl<A: Adapter> HeartbeatSender<A> {
5962
pub async fn conditional_send(&self, channel: Channel) -> Result<(), HeartbeatError> {
6063
// get latest Heartbeat message from repo
6164
// TODO: Handle this error, removing this ValidatorId from here
@@ -75,7 +78,7 @@ impl<A: Adapter + State> HeartbeatSender<A> {
7578

7679
// if it doesn't exist or the Passed time is greater than the Timer Time
7780
match latest_heartbeat.as_ref() {
78-
Some(heartbeat) if !self.is_heartbeat_time(&heartbeat) => {
81+
Some(heartbeat) if !self.is_heartbeat_time(heartbeat) => {
7982
return Err(HeartbeatError::NotYetTime)
8083
}
8184
_ => (),
@@ -91,14 +94,15 @@ impl<A: Adapter + State> HeartbeatSender<A> {
9194
// call the HeartbeatFactory and create the new Heartbeat
9295
let heartbeat = await!(self.factory.create(signable_state_root.0))?;
9396

97+
// @TODO: Issue #93 - this should propagate the message to all validators!
9498
// `add()` the heartbeat with the Repository
9599
await!(self
96100
.message_repository
97-
.add(channel.id, Message::Heartbeat(heartbeat)))
101+
.add(&channel.id, &validator, Message::Heartbeat(heartbeat)))
98102
.map_err(HeartbeatError::Repository)
99103
}
100104

101-
fn is_heartbeat_time(&self, latest_heartbeat: &Heartbeat<A>) -> bool {
105+
fn is_heartbeat_time(&self, latest_heartbeat: &Heartbeat<A::State>) -> bool {
102106
// @TODO: Use the configuration value for the duration!
103107
latest_heartbeat.timestamp - Utc::now() >= Duration::seconds(10)
104108
}

validator/src/domain/validator.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,16 @@ pub mod repository {
2323
use domain::{ChannelId, RepositoryFuture};
2424

2525
pub trait MessageRepository<S: State> {
26-
fn add(&self, channel_id: ChannelId, message: Message<S>) -> RepositoryFuture<()>;
26+
fn add(
27+
&self,
28+
channel: &ChannelId,
29+
validator: &ValidatorId,
30+
message: Message<S>,
31+
) -> RepositoryFuture<()>;
2732

2833
fn latest(
2934
&self,
30-
channel_id: &ChannelId,
35+
channel: &ChannelId,
3136
from: &ValidatorId,
3237
types: Option<&[&MessageType]>,
3338
) -> RepositoryFuture<Option<Message<S>>>;

0 commit comments

Comments
 (0)