Skip to content

Commit 68da282

Browse files
committed
fix(engines): Make leftovers be an associated type
This allows the trait implementer to choose the data type of the leftovers instead of forcing them to use BigUint
1 parent 055d365 commit 68da282

File tree

4 files changed

+75
-37
lines changed

4 files changed

+75
-37
lines changed

crates/interledger-settlement-engines/src/engines/ethereum_ledger/eth_engine.rs

Lines changed: 48 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use tokio_retry::{strategy::ExponentialBackoff, Retry};
3535
use url::Url;
3636
use uuid::Uuid;
3737

38-
use crate::stores::redis_ethereum_ledger::*;
38+
use crate::stores::{redis_ethereum_ledger::*, LeftoversStore};
3939
use crate::{ApiResponse, CreateAccount, SettlementEngine, SettlementEngineApi};
4040
use interledger_settlement::{Convert, ConvertDetails, Quantity};
4141

@@ -101,7 +101,12 @@ pub struct EthereumLedgerSettlementEngineBuilder<'a, S, Si, A> {
101101

102102
impl<'a, S, Si, A> EthereumLedgerSettlementEngineBuilder<'a, S, Si, A>
103103
where
104-
S: EthereumStore<Account = A> + Clone + Send + Sync + 'static,
104+
S: EthereumStore<Account = A>
105+
+ LeftoversStore<AssetType = BigUint>
106+
+ Clone
107+
+ Send
108+
+ Sync
109+
+ 'static,
105110
Si: EthereumLedgerTxSigner + Clone + Send + Sync + 'static,
106111
A: EthereumAccount + Send + Sync + 'static,
107112
{
@@ -223,7 +228,12 @@ where
223228

224229
impl<S, Si, A> EthereumLedgerSettlementEngine<S, Si, A>
225230
where
226-
S: EthereumStore<Account = A> + Clone + Send + Sync + 'static,
231+
S: EthereumStore<Account = A>
232+
+ LeftoversStore<AssetType = BigUint>
233+
+ Clone
234+
+ Send
235+
+ Sync
236+
+ 'static,
227237
Si: EthereumLedgerTxSigner + Clone + Send + Sync + 'static,
228238
A: EthereumAccount + Send + Sync + 'static,
229239
{
@@ -373,7 +383,11 @@ where
373383
store
374384
.load_account_id_from_address(addr)
375385
.and_then(move |id| {
376-
self_clone.notify_connector(id.to_string(), amount.to_string(), tx_hash)
386+
self_clone.notify_connector(
387+
id.to_string(),
388+
amount.to_string(),
389+
tx_hash,
390+
)
377391
})
378392
.and_then(move |_| {
379393
// only save the transaction hash if the connector
@@ -571,29 +585,31 @@ where
571585
})
572586
.and_then(move |quantity: Quantity| {
573587
result(BigUint::from_str(&quantity.amount))
574-
.map_err(|err| {
575-
let error_msg = format!("Error converting to BigUint {:?}", err);
576-
error!("{:?}", error_msg);
577-
})
578-
.and_then(move |connector_amount: BigUint| {
579-
// Scale the amount settled by the
580-
// connector back up to our scale
581-
result(connector_amount.normalize_scale(ConvertDetails {
582-
from: quantity.scale,
583-
to: engine_scale,
584-
}))
585-
.and_then(move |scaled_connector_amount| {
586-
let diff: BigUint = engine_amount - scaled_connector_amount;
587-
if diff > Zero::zero() {
588-
// connector settled less than we
589-
// instructed it to, so we must save
590-
// the difference for the leftovers
591-
Either::A(store.save_leftovers(account_id, diff))
592-
} else {
593-
Either::B(ok(()))
594-
}
588+
.map_err(|err| {
589+
let error_msg = format!("Error converting to BigUint {:?}", err);
590+
error!("{:?}", error_msg);
591+
})
592+
.and_then(move |connector_amount: BigUint| {
593+
// Scale the amount settled by the
594+
// connector back up to our scale
595+
result(connector_amount.normalize_scale(ConvertDetails {
596+
from: quantity.scale,
597+
to: engine_scale,
598+
}))
599+
.and_then(
600+
move |scaled_connector_amount| {
601+
let diff: BigUint = engine_amount - scaled_connector_amount;
602+
if diff > Zero::zero() {
603+
// connector settled less than we
604+
// instructed it to, so we must save
605+
// the difference for the leftovers
606+
Either::A(store.save_leftovers(account_id, diff))
607+
} else {
608+
Either::B(ok(()))
609+
}
610+
},
611+
)
595612
})
596-
})
597613
}),
598614
)
599615
}
@@ -689,7 +705,12 @@ where
689705

690706
impl<S, Si, A> SettlementEngine for EthereumLedgerSettlementEngine<S, Si, A>
691707
where
692-
S: EthereumStore<Account = A> + Clone + Send + Sync + 'static,
708+
S: EthereumStore<Account = A>
709+
+ LeftoversStore<AssetType = BigUint>
710+
+ Clone
711+
+ Send
712+
+ Sync
713+
+ 'static,
693714
Si: EthereumLedgerTxSigner + Clone + Send + Sync + 'static,
694715
A: EthereumAccount + Send + Sync + 'static,
695716
{

crates/interledger-settlement-engines/src/engines/ethereum_ledger/test_helpers.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,17 +68,22 @@ use crate::stores::LeftoversStore;
6868
use num_bigint::BigUint;
6969

7070
impl LeftoversStore for TestStore {
71+
type AssetType = BigUint;
72+
7173
fn save_leftovers(
7274
&self,
7375
account_id: String,
74-
leftovers: BigUint,
76+
leftovers: Self::AssetType,
7577
) -> Box<Future<Item = (), Error = ()> + Send> {
7678
let mut guard = self.leftovers.write();
7779
(*guard).insert(account_id, leftovers);
7880
Box::new(ok(()))
7981
}
8082

81-
fn load_leftovers(&self, account_id: String) -> Box<Future<Item = BigUint, Error = ()> + Send> {
83+
fn load_leftovers(
84+
&self,
85+
account_id: String,
86+
) -> Box<Future<Item = Self::AssetType, Error = ()> + Send> {
8287
let guard = self.leftovers.read();
8388
if let Some(l) = guard.get(&account_id) {
8489
Box::new(ok(l.clone()))
@@ -261,6 +266,7 @@ impl TestStore {
261266
cache_hits: Arc::new(RwLock::new(0)),
262267
last_observed_block: Arc::new(RwLock::new(U256::from(0))),
263268
saved_hashes: Arc::new(RwLock::new(HashMap::new())),
269+
leftovers: Arc::new(RwLock::new(HashMap::new())),
264270
}
265271
}
266272
}
@@ -288,7 +294,13 @@ pub fn test_engine<Si, S, A>(
288294
) -> EthereumLedgerSettlementEngine<S, Si, A>
289295
where
290296
Si: EthereumLedgerTxSigner + Clone + Send + Sync + 'static,
291-
S: EthereumStore<Account = A> + IdempotentStore + Clone + Send + Sync + 'static,
297+
S: EthereumStore<Account = A>
298+
+ LeftoversStore<AssetType = BigUint>
299+
+ IdempotentStore
300+
+ Clone
301+
+ Send
302+
+ Sync
303+
+ 'static,
292304
A: EthereumAccount + Send + Sync + 'static,
293305
{
294306
EthereumLedgerSettlementEngineBuilder::new(store, key)

crates/interledger-settlement-engines/src/stores/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,18 @@ pub trait IdempotentEngineStore {
3030
}
3131

3232
pub trait LeftoversStore {
33+
type AssetType;
34+
3335
/// Saves the leftover data
3436
fn save_leftovers(
3537
&self,
3638
account_id: String,
37-
leftovers: BigUint,
39+
leftovers: Self::AssetType,
3840
) -> Box<dyn Future<Item = (), Error = ()> + Send>;
3941

4042
/// Saves the leftover data
4143
fn load_leftovers(
4244
&self,
4345
account_id: String,
44-
) -> Box<dyn Future<Item = BigUint, Error = ()> + Send>;
46+
) -> Box<dyn Future<Item = Self::AssetType, Error = ()> + Send>;
4547
}

crates/interledger-settlement-engines/src/stores/redis_ethereum_ledger/store.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ use redis::{self, cmd, r#async::SharedConnection, ConnectionInfo, PipelineComman
1414
use log::{error, trace};
1515

1616
use crate::stores::redis_store_common::{EngineRedisStore, EngineRedisStoreBuilder};
17+
use crate::stores::LeftoversStore;
18+
use num_bigint::BigUint;
1719

1820
// Key for the latest observed block and balance. The data is stored in order to
1921
// avoid double crediting transactions which have already been processed, and in
@@ -107,10 +109,12 @@ impl EthereumLedgerRedisStore {
107109
}
108110

109111
impl LeftoversStore for EthereumLedgerRedisStore {
112+
type AssetType = BigUint;
113+
110114
fn save_leftovers(
111115
&self,
112116
account_id: String,
113-
leftovers: BigUint,
117+
leftovers: Self::AssetType,
114118
) -> Box<dyn Future<Item = (), Error = ()> + Send> {
115119
let mut pipe = redis::pipe();
116120
pipe.set(format!("leftovers:{}", account_id), leftovers.to_string())
@@ -125,10 +129,9 @@ impl LeftoversStore for EthereumLedgerRedisStore {
125129
fn load_leftovers(
126130
&self,
127131
account_id: String,
128-
) -> Box<dyn Future<Item = BigUint, Error = ()> + Send> {
132+
) -> Box<dyn Future<Item = Self::AssetType, Error = ()> + Send> {
129133
let mut pipe = redis::pipe();
130-
pipe.get(format!("leftovers:{}", account_id))
131-
.ignore();
134+
pipe.get(format!("leftovers:{}", account_id)).ignore();
132135
Box::new(
133136
pipe.query_async(self.connection.clone())
134137
.map_err(move |err| error!("Error loading leftovers {:?}: ", err))
@@ -138,7 +141,7 @@ impl LeftoversStore for EthereumLedgerRedisStore {
138141
} else {
139142
Box::new(err(()))
140143
}
141-
})
144+
}),
142145
)
143146
}
144147
}

0 commit comments

Comments
 (0)