Skip to content

Commit ae053ec

Browse files
authored
Merge pull request #428 from AdExNetwork/v5-validator-workflow
V5 validator workflow - Follower & Leader ticks
2 parents f966cd3 + f15044d commit ae053ec

File tree

14 files changed

+683
-492
lines changed

14 files changed

+683
-492
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

adapter/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ reqwest = { version = "0.11", features = ["json"] }
2929
sha2 = "0.9"
3030
base64 = "0.13"
3131
lazy_static = "^1.4"
32+
thiserror = "^1"
3233
# Futures
3334
futures = "0.3"
3435
async-trait = "0.1"

adapter/src/dummy.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ impl Adapter for DummyAdapter {
107107

108108
fn verify(
109109
&self,
110-
signer: &ValidatorId,
110+
signer: ValidatorId,
111111
_state_root: &str,
112112
signature: &str,
113113
) -> AdapterResult<bool, Self::AdapterError> {

adapter/src/ethereum.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ impl Adapter for EthereumAdapter {
172172
/// `sig` is hex string which **should be** `0x` prefixed
173173
fn verify(
174174
&self,
175-
signer: &ValidatorId,
175+
signer: ValidatorId,
176176
state_root: &str,
177177
sig: &str,
178178
) -> AdapterResult<bool, Self::AdapterError> {
@@ -543,7 +543,7 @@ mod test {
543543
"0x9e07f12958ce7c5eb1362eb9461e4745dd9d74a42b921391393caea700bfbd6e1ad876a7d8f9202ef1fe6110dbfe87840c5676ca5c4fda9f3330694a1ac2a1fc1b";
544544
let verify = eth_adapter
545545
.verify(
546-
&ValidatorId::try_from("2892f6C41E0718eeeDd49D98D648C789668cA67d")
546+
ValidatorId::try_from("2892f6C41E0718eeeDd49D98D648C789668cA67d")
547547
.expect("Failed to parse id"),
548548
"8bc45d8eb27f4c98cab35d17b0baecc2a263d6831ef0800f4c190cbfac6d20a3",
549549
&signature,
@@ -555,7 +555,7 @@ mod test {
555555

556556
let verify2 = eth_adapter
557557
.verify(
558-
&ValidatorId::try_from("ce07CbB7e054514D590a0262C93070D838bFBA2e")
558+
ValidatorId::try_from("ce07CbB7e054514D590a0262C93070D838bFBA2e")
559559
.expect("Failed to parse id"),
560560
message2,
561561
&signature2,

adapter/src/lib.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@
22
#![deny(clippy::all)]
33
#![deny(clippy::match_bool)]
44

5-
use std::error::Error;
6-
7-
use primitives::{channel::ChannelError, Address, BigNum};
5+
use primitives::{Address, BigNum};
86
use tiny_keccak::Keccak;
97
use web3::{
108
ethabi::{encode, token::Token},
119
types::{Address as EthAddress, U256},
1210
};
11+
use thiserror::Error;
1312

1413
pub use self::dummy::DummyAdapter;
1514
pub use self::ethereum::EthereumAdapter;
@@ -22,10 +21,14 @@ pub enum AdapterTypes {
2221
EthereumAdapter(Box<EthereumAdapter>),
2322
}
2423

24+
#[derive(Debug, Error)]
25+
#[error("{0}")]
26+
pub struct BalanceLeafError(String);
27+
2528
pub fn get_signable_state_root(
2629
channel_id: &[u8],
2730
balance_root: &[u8; 32],
28-
) -> Result<[u8; 32], Box<dyn Error>> {
31+
) -> [u8; 32] {
2932
let tokens = [
3033
Token::FixedBytes(channel_id.to_vec()),
3134
Token::FixedBytes(balance_root.to_vec()),
@@ -39,18 +42,18 @@ pub fn get_signable_state_root(
3942
let mut res: [u8; 32] = [0; 32];
4043
result.finalize(&mut res);
4144

42-
Ok(res)
45+
res
4346
}
4447

4548
pub fn get_balance_leaf(
4649
is_spender: bool,
4750
acc: &Address,
4851
amnt: &BigNum,
49-
) -> Result<[u8; 32], Box<dyn Error>> {
52+
) -> Result<[u8; 32], BalanceLeafError> {
5053
let address = Token::Address(EthAddress::from_slice(acc.as_bytes()));
5154
let amount = Token::Uint(
5255
U256::from_dec_str(&amnt.to_str_radix(10))
53-
.map_err(|_| ChannelError::InvalidArgument("failed to parse amt".into()))?,
56+
.map_err(|_| BalanceLeafError("Failed to parse amt".into()))?,
5457
);
5558

5659
let tokens = if is_spender {
@@ -95,8 +98,7 @@ mod test {
9598
let state_root = get_signable_state_root(
9699
&hex::decode(&channel_id).expect("failed"),
97100
&merkle_tree.root(),
98-
)
99-
.expect("Should get state_root");
101+
);
100102

101103
let expected_hex =
102104
hex::decode("b68cde9b0c8b63ac7152e78a65c736989b4b99bfc252758b1c3fd6ca357e0d6b")

primitives/src/adapter.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ pub trait Adapter: Send + Sync + fmt::Debug + Clone {
8989
/// Verify, based on the signature & state_root, that the signer is the same
9090
fn verify(
9191
&self,
92-
signer: &ValidatorId,
92+
signer: ValidatorId,
9393
state_root: &str,
9494
signature: &str,
9595
) -> AdapterResult<bool, Self::AdapterError>;

validator_worker/src/channel.rs

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
use crate::{
22
error::{Error, TickError},
3-
follower,
3+
follower, leader,
44
sentry_interface::{campaigns::all_campaigns, Validator, Validators},
55
SentryApi,
66
};
77
use primitives::{adapter::Adapter, channel_v5::Channel, config::Config, util::ApiUrl, ChannelId};
8-
// use slog::{error, info, Logger};
98
use slog::Logger;
109
use std::collections::{hash_map::Entry, HashSet};
1110

@@ -15,27 +14,22 @@ pub async fn channel_tick<A: Adapter + 'static>(
1514
logger: &Logger,
1615
channel: Channel,
1716
validators: Validators,
18-
) -> Result<ChannelId, Error<A::AdapterError>> {
17+
) -> Result<ChannelId, Error> {
1918
let tick = channel
2019
.find_validator(adapter.whoami())
2120
.ok_or(Error::ChannelNotIntendedForUs)?;
2221

23-
let sentry = SentryApi::init(
24-
adapter,
25-
logger.clone(),
26-
config.clone(),
27-
(channel, validators),
28-
)?;
29-
// `GET /channel/:id/spender/all`
30-
let all_spenders = sentry.get_all_spenders().await?;
22+
let sentry = SentryApi::init(adapter, logger.clone(), config.clone(), validators)?;
23+
// 1. `GET /channel/:id/spender/all`
24+
let all_spenders = sentry.get_all_spenders(channel.id()).await?;
3125

32-
// `GET /channel/:id/accounting`
26+
// 2. `GET /channel/:id/accounting`
3327
// Validation #1:
3428
// sum(Accounting.spenders) == sum(Accounting.earners)
3529
let accounting = sentry.get_accounting(channel.id()).await?;
3630

3731
// Validation #2:
38-
// spender.spender_leaf.total_deposit >= accounting.balances.spenders[spender.address]
32+
// spender.total_deposit >= accounting.balances.spenders[spender.address]
3933
if !all_spenders.iter().all(|(address, spender)| {
4034
spender.total_deposited
4135
>= accounting
@@ -48,22 +42,28 @@ pub async fn channel_tick<A: Adapter + 'static>(
4842
return Err(Error::Validation);
4943
}
5044

45+
let token = config
46+
.token_address_whitelist
47+
.get(&channel.token)
48+
.ok_or(Error::ChannelTokenNotWhitelisted)?;
49+
5150
// TODO: Add timeout
52-
let _tick_result = match tick {
53-
primitives::Validator::Leader(_v) => todo!(),
54-
primitives::Validator::Follower(_v) => {
55-
follower::tick(&sentry, channel, accounting.balances)
51+
match tick {
52+
primitives::Validator::Leader(_v) => {
53+
let _leader_tick_status = leader::tick(&sentry, channel, accounting.balances, token)
5654
.await
57-
.map_err(|err| Error::FollowerTick(channel.id(), TickError::Tick(err)))?
55+
.map_err(|err| Error::LeaderTick(channel.id(), TickError::Tick(Box::new(err))))?;
56+
}
57+
primitives::Validator::Follower(_v) => {
58+
let _follower_tick_status =
59+
follower::tick(&sentry, channel, all_spenders, accounting.balances, token)
60+
.await
61+
.map_err(|err| {
62+
Error::FollowerTick(channel.id(), TickError::Tick(Box::new(err)))
63+
})?;
5864
}
5965
};
6066

61-
// Validation #3
62-
// Accounting.balances != NewState.balances
63-
64-
// Validation #4
65-
// OUTPACE Rules:
66-
6767
Ok(channel.id())
6868
}
6969

0 commit comments

Comments
 (0)