Skip to content

Commit cbdc71e

Browse files
authored
Merge pull request #472 from AmbireTech/issue-336-adapter-chains
Issue #336 Multi-chain support
2 parents 371a59a + 61099b4 commit cbdc71e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1758
-1079
lines changed

adapter/src/adapter.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::primitives::*;
22
use async_trait::async_trait;
3+
use primitives::{ChainId, ChainOf, Channel};
34
use std::{marker::PhantomData, sync::Arc};
45

56
use crate::{
@@ -93,8 +94,10 @@ where
9394
self.client.sign(state_root).map_err(Into::into)
9495
}
9596

96-
fn get_auth(&self, intended_for: ValidatorId) -> Result<String, Error> {
97-
self.client.get_auth(intended_for).map_err(Into::into)
97+
fn get_auth(&self, for_chain: ChainId, intended_for: ValidatorId) -> Result<String, Error> {
98+
self.client
99+
.get_auth(for_chain, intended_for)
100+
.map_err(Into::into)
98101
}
99102
}
100103

@@ -134,11 +137,11 @@ where
134137

135138
async fn get_deposit(
136139
&self,
137-
channel: &Channel,
140+
channel_context: &ChainOf<Channel>,
138141
depositor_address: Address,
139142
) -> Result<Deposit, Error> {
140143
self.client
141-
.get_deposit(channel, depositor_address)
144+
.get_deposit(channel_context, depositor_address)
142145
.await
143146
.map_err(Into::into)
144147
}

adapter/src/client.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
77
use crate::primitives::{Deposit, Session};
88
use async_trait::async_trait;
9-
use primitives::{Address, Channel, ValidatorId};
9+
use primitives::{Address, ChainId, ChainOf, Channel, ValidatorId};
1010

1111
#[async_trait]
1212
/// Available methods for Locked clients.
@@ -30,7 +30,7 @@ pub trait Locked: Sync + Send {
3030

3131
async fn get_deposit(
3232
&self,
33-
channel: &Channel,
33+
channel_context: &ChainOf<Channel>,
3434
depositor_address: Address,
3535
) -> Result<Deposit, Self::Error>;
3636

@@ -48,14 +48,19 @@ pub trait Locked: Sync + Send {
4848
}
4949

5050
/// Available methods for Unlocked clients.
51+
///
5152
/// Unlocked clients should also implement [`Locked`].
5253
#[async_trait]
5354
pub trait Unlocked: Locked {
5455
// requires Unlocked
5556
fn sign(&self, state_root: &str) -> Result<String, Self::Error>;
5657

5758
// requires Unlocked
58-
fn get_auth(&self, intended_for: ValidatorId) -> Result<String, Self::Error>;
59+
fn get_auth(
60+
&self,
61+
for_chain: ChainId,
62+
intended_for: ValidatorId,
63+
) -> Result<String, Self::Error>;
5964
}
6065

6166
/// A client that can be `unlock()`ed

adapter/src/dummy.rs

+48-12
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,28 @@ use crate::{
88
use async_trait::async_trait;
99
use dashmap::{mapref::entry::Entry, DashMap};
1010

11-
use primitives::{Address, Channel, ChannelId, ToETHChecksum, ValidatorId};
11+
use once_cell::sync::Lazy;
12+
use primitives::{
13+
Address, Chain, ChainId, ChainOf, Channel, ChannelId, ToETHChecksum, ValidatorId,
14+
};
1215
use std::{collections::HashMap, sync::Arc};
1316

1417
pub type Adapter<S> = crate::Adapter<Dummy, S>;
1518

19+
/// The Dummy Chain to be used with this adapter
20+
/// The Chain is not applicable to the adapter, however, it is required for
21+
/// applications because of the `authentication` & [`Channel`] interactions.
22+
pub static DUMMY_CHAIN: Lazy<Chain> = Lazy::new(|| Chain {
23+
chain_id: ChainId::new(1),
24+
rpc: "http://dummy.com".parse().expect("Should parse ApiUrl"),
25+
outpace: "0x0000000000000000000000000000000000000000"
26+
.parse()
27+
.unwrap(),
28+
sweeper: "0x0000000000000000000000000000000000000000"
29+
.parse()
30+
.unwrap(),
31+
});
32+
1633
/// Dummy adapter implementation intended for testing.
1734
#[derive(Debug, Clone)]
1835
pub struct Dummy {
@@ -86,6 +103,9 @@ impl Locked for Dummy {
86103
}
87104

88105
/// Verify, based on the signature & state_root, that the signer is the same
106+
///
107+
/// Splits the signature by `" "` (whitespace) and takes
108+
/// the last part of it which contains the signer [`Address`].
89109
fn verify(
90110
&self,
91111
signer: ValidatorId,
@@ -102,8 +122,8 @@ impl Locked for Dummy {
102122
Ok(is_same)
103123
}
104124

105-
/// Creates a `Session` from a provided Token by calling the Contract.
106-
/// Does **not** cache the (`Token`, `Session`) pair.
125+
/// Finds the authorization token from the configured values
126+
/// and creates a [`Session`] out of it using a [`ChainId`] of `1`.
107127
async fn session_from_token(&self, token: &str) -> Result<Session, crate::Error> {
108128
let identity = self
109129
.authorization_tokens
@@ -114,6 +134,7 @@ impl Locked for Dummy {
114134
Some((address, _token)) => Ok(Session {
115135
uid: *address,
116136
era: 0,
137+
chain: DUMMY_CHAIN.clone(),
117138
}),
118139
None => Err(Error::authentication(format!(
119140
"No identity found that matches authentication token: {}",
@@ -124,11 +145,11 @@ impl Locked for Dummy {
124145

125146
async fn get_deposit(
126147
&self,
127-
channel: &Channel,
148+
channel_context: &ChainOf<Channel>,
128149
depositor_address: Address,
129150
) -> Result<Deposit, crate::Error> {
130151
self.deposits
131-
.get_next_deposit(channel.id(), depositor_address)
152+
.get_next_deposit(channel_context.context.id(), depositor_address)
132153
.ok_or_else(|| {
133154
Error::adapter(format!(
134155
"No more mocked deposits found for depositor {:?}",
@@ -151,7 +172,7 @@ impl Unlocked for Dummy {
151172
}
152173

153174
// requires Unlocked
154-
fn get_auth(&self, _intended_for: ValidatorId) -> Result<String, Error> {
175+
fn get_auth(&self, _for_chain: ChainId, _intended_for: ValidatorId) -> Result<String, Error> {
155176
self.authorization_tokens
156177
.get(&self.identity.to_address())
157178
.cloned()
@@ -174,16 +195,31 @@ impl Unlockable for Dummy {
174195

175196
#[cfg(test)]
176197
mod test {
198+
use std::num::NonZeroU8;
199+
177200
use primitives::{
201+
config::TokenInfo,
178202
util::tests::prep_db::{ADDRESSES, DUMMY_CAMPAIGN, IDS},
179-
BigNum,
203+
BigNum, ChainOf, UnifiedNum,
180204
};
181205

182206
use super::*;
183207

184208
#[tokio::test]
185209
async fn test_deposits_calls() {
186210
let channel = DUMMY_CAMPAIGN.channel;
211+
212+
let channel_context = ChainOf {
213+
context: channel,
214+
token: TokenInfo {
215+
min_token_units_for_deposit: 1_u64.into(),
216+
min_validator_fee: 1_u64.into(),
217+
precision: NonZeroU8::new(UnifiedNum::PRECISION).expect("Non zero u8"),
218+
address: channel.token,
219+
},
220+
chain: DUMMY_CHAIN.clone(),
221+
};
222+
187223
let dummy_client = Dummy::init(Options {
188224
dummy_identity: IDS["leader"],
189225
dummy_auth_tokens: Default::default(),
@@ -193,7 +229,7 @@ mod test {
193229

194230
// no mocked deposit calls should cause an Error
195231
{
196-
let result = dummy_client.get_deposit(&channel, address).await;
232+
let result = dummy_client.get_deposit(&channel_context, address).await;
197233

198234
assert!(result.is_err());
199235
}
@@ -211,25 +247,25 @@ mod test {
211247
dummy_client.add_deposit_call(channel.id(), address, deposits[1].clone());
212248

213249
let first_call = dummy_client
214-
.get_deposit(&channel, address)
250+
.get_deposit(&channel_context, address)
215251
.await
216252
.expect("Should get first mocked deposit");
217253
assert_eq!(&deposits[0], &first_call);
218254

219255
// should not affect the Mocked deposit calls and should cause an error
220256
let different_address_call = dummy_client
221-
.get_deposit(&channel, ADDRESSES["leader"])
257+
.get_deposit(&channel_context, ADDRESSES["leader"])
222258
.await;
223259
assert!(different_address_call.is_err());
224260

225261
let second_call = dummy_client
226-
.get_deposit(&channel, address)
262+
.get_deposit(&channel_context, address)
227263
.await
228264
.expect("Should get second mocked deposit");
229265
assert_eq!(&deposits[1], &second_call);
230266

231267
// Third call should error, we've only mocked 2 calls!
232-
let third_call = dummy_client.get_deposit(&channel, address).await;
268+
let third_call = dummy_client.get_deposit(&channel_context, address).await;
233269
assert!(third_call.is_err());
234270
}
235271
}

adapter/src/error.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ impl fmt::Display for Inner {
7070
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7171
match &self.source {
7272
// Writes: "Kind: Error message here"
73-
Some(source) => write!(f, "{}: {}", self.kind, source.to_string()),
73+
Some(source) => write!(f, "{}: {}", self.kind, source),
7474
// Writes: "Kind"
7575
None => write!(f, "{}", self.kind),
7676
}

0 commit comments

Comments
 (0)