@@ -34,8 +34,8 @@ use url::Url;
34
34
use uuid:: Uuid ;
35
35
36
36
use crate :: stores:: redis_ethereum_ledger:: * ;
37
-
38
- use crate :: { ApiResponse , Quantity , SettlementEngine , SettlementEngineApi } ;
37
+ use crate :: { ApiResponse , CreateAccount , SettlementEngine , SettlementEngineApi } ;
38
+ use interledger_settlement :: Quantity ;
39
39
40
40
const MAX_RETRIES : usize = 10 ;
41
41
const ETH_CREATE_ACCOUNT_PREFIX : & [ u8 ] = b"ilp-ethl-create-account-message" ;
@@ -78,6 +78,7 @@ pub struct EthereumLedgerSettlementEngine<S, Si, A> {
78
78
confirmations : u8 ,
79
79
poll_frequency : Duration ,
80
80
connector_url : Url ,
81
+ asset_scale : u8 ,
81
82
}
82
83
83
84
pub struct EthereumLedgerSettlementEngineBuilder < ' a , S , Si , A > {
@@ -91,6 +92,7 @@ pub struct EthereumLedgerSettlementEngineBuilder<'a, S, Si, A> {
91
92
poll_frequency : Option < Duration > ,
92
93
connector_url : Option < Url > ,
93
94
token_address : Option < Address > ,
95
+ asset_scale : Option < u8 > ,
94
96
watch_incoming : bool ,
95
97
account_type : PhantomData < A > ,
96
98
}
@@ -111,6 +113,7 @@ where
111
113
poll_frequency : None ,
112
114
connector_url : None ,
113
115
token_address : None ,
116
+ asset_scale : None ,
114
117
watch_incoming : false ,
115
118
account_type : PhantomData ,
116
119
}
@@ -126,6 +129,11 @@ where
126
129
self
127
130
}
128
131
132
+ pub fn asset_scale ( & mut self , asset_scale : u8 ) -> & mut Self {
133
+ self . asset_scale = Some ( asset_scale) ;
134
+ self
135
+ }
136
+
129
137
pub fn chain_id ( & mut self , chain_id : u8 ) -> & mut Self {
130
138
self . chain_id = Some ( chain_id) ;
131
139
self
@@ -178,6 +186,11 @@ where
178
186
} else {
179
187
Duration :: from_secs ( 5 )
180
188
} ;
189
+ let asset_scale = if let Some ( asset_scale) = self . asset_scale {
190
+ asset_scale
191
+ } else {
192
+ 18
193
+ } ;
181
194
182
195
let ( eloop, transport) = Http :: new ( ethereum_endpoint) . unwrap ( ) ;
183
196
eloop. into_remote ( ) ;
@@ -196,6 +209,7 @@ where
196
209
confirmations,
197
210
poll_frequency,
198
211
connector_url,
212
+ asset_scale,
199
213
account_type : PhantomData ,
200
214
} ;
201
215
if self . watch_incoming {
@@ -355,11 +369,7 @@ where
355
369
store
356
370
. load_account_id_from_address ( addr)
357
371
. and_then ( move |id| {
358
- self_clone. notify_connector (
359
- id. to_string ( ) ,
360
- amount. low_u64 ( ) ,
361
- tx_hash,
362
- )
372
+ self_clone. notify_connector ( id. to_string ( ) , amount, tx_hash)
363
373
} )
364
374
. and_then ( move |_| {
365
375
// only save the transaction hash if the connector
@@ -442,7 +452,7 @@ where
442
452
Either :: A (
443
453
store. load_account_id_from_address ( addr)
444
454
. and_then ( move |id| {
445
- self_clone. notify_connector ( id. to_string ( ) , amount. low_u64 ( ) , tx_hash)
455
+ self_clone. notify_connector ( id. to_string ( ) , amount, tx_hash)
446
456
} )
447
457
. and_then ( move |_| {
448
458
// only save the transaction hash if the connector
@@ -463,11 +473,12 @@ where
463
473
fn notify_connector (
464
474
& self ,
465
475
account_id : String ,
466
- amount : u64 ,
476
+ amount : U256 ,
467
477
tx_hash : H256 ,
468
478
) -> impl Future < Item = ( ) , Error = ( ) > {
469
479
let mut url = self . connector_url . clone ( ) ;
470
480
let account_id_clone = account_id. clone ( ) ;
481
+ let asset_scale = self . asset_scale ;
471
482
url. path_segments_mut ( )
472
483
. expect ( "Invalid connector URL" )
473
484
. push ( "accounts" )
@@ -480,7 +491,7 @@ where
480
491
client
481
492
. post ( url. clone ( ) )
482
493
. header ( "Idempotency-Key" , tx_hash. to_string ( ) )
483
- . json ( & json ! ( { "amount" : amount } ) )
494
+ . json ( & json ! ( { "amount" : amount. to_string ( ) , "scale" : asset_scale } ) )
484
495
. send ( )
485
496
. map_err ( move |err| {
486
497
error ! (
@@ -611,10 +622,11 @@ where
611
622
/// the store.
612
623
fn create_account (
613
624
& self ,
614
- account_id : String ,
625
+ account_id : CreateAccount ,
615
626
) -> Box < dyn Future < Item = ApiResponse , Error = ApiResponse > + Send > {
616
627
let self_clone = self . clone ( ) ;
617
628
let store: S = self . store . clone ( ) ;
629
+ let account_id = account_id. id ;
618
630
619
631
Box :: new (
620
632
result ( A :: AccountId :: from_str ( & account_id) . map_err ( {
@@ -741,27 +753,32 @@ where
741
753
account_id : String ,
742
754
body : Quantity ,
743
755
) -> Box < dyn Future < Item = ApiResponse , Error = ApiResponse > + Send > {
744
- let amount = U256 :: from ( body. amount ) ;
745
756
let self_clone = self . clone ( ) ;
746
-
747
757
Box :: new (
748
- self_clone
749
- . load_account ( account_id)
750
- . map_err ( move |err| {
751
- let error_msg = format ! ( "Error loading account {:?}" , err) ;
752
- error ! ( "{}" , error_msg) ;
753
- ( StatusCode :: from_u16 ( 400 ) . unwrap ( ) , error_msg)
754
- } )
755
- . and_then ( move |( _account_id, addresses) | {
756
- self_clone
757
- . settle_to ( addresses. own_address , amount, addresses. token_address )
758
- . map_err ( move |_| {
759
- let error_msg = "Error connecting to the blockchain." . to_string ( ) ;
760
- error ! ( "{}" , error_msg) ;
761
- ( StatusCode :: from_u16 ( 502 ) . unwrap ( ) , error_msg)
762
- } )
763
- } )
764
- . and_then ( move |_| Ok ( ( StatusCode :: OK , "OK" . to_string ( ) ) ) ) ,
758
+ result ( U256 :: from_dec_str ( & body. amount ) . map_err ( move |err| {
759
+ let error_msg = format ! ( "Error converting to U256 {:?}" , err) ;
760
+ error ! ( "{:?}" , error_msg) ;
761
+ ( StatusCode :: from_u16 ( 400 ) . unwrap ( ) , error_msg)
762
+ } ) )
763
+ . and_then ( move |amount| {
764
+ self_clone
765
+ . load_account ( account_id)
766
+ . map_err ( move |err| {
767
+ let error_msg = format ! ( "Error loading account {:?}" , err) ;
768
+ error ! ( "{}" , error_msg) ;
769
+ ( StatusCode :: from_u16 ( 400 ) . unwrap ( ) , error_msg)
770
+ } )
771
+ . and_then ( move |( _account_id, addresses) | {
772
+ self_clone
773
+ . settle_to ( addresses. own_address , amount, addresses. token_address )
774
+ . map_err ( move |_| {
775
+ let error_msg = "Error connecting to the blockchain." . to_string ( ) ;
776
+ error ! ( "{}" , error_msg) ;
777
+ ( StatusCode :: from_u16 ( 502 ) . unwrap ( ) , error_msg)
778
+ } )
779
+ } )
780
+ . and_then ( move |_| Ok ( ( StatusCode :: OK , "OK" . to_string ( ) ) ) )
781
+ } ) ,
765
782
)
766
783
}
767
784
}
@@ -804,6 +821,7 @@ pub fn run_ethereum_engine<R, Si>(
804
821
private_key : Si ,
805
822
chain_id : u8 ,
806
823
confirmations : u8 ,
824
+ asset_scale : u8 ,
807
825
poll_frequency : u64 ,
808
826
connector_url : String ,
809
827
token_address : Option < Address > ,
@@ -824,6 +842,7 @@ where
824
842
. chain_id ( chain_id)
825
843
. connector_url ( & connector_url)
826
844
. confirmations ( confirmations)
845
+ . asset_scale ( asset_scale)
827
846
. poll_frequency ( poll_frequency)
828
847
. watch_incoming ( watch_incoming)
829
848
. token_address ( token_address)
@@ -907,7 +926,7 @@ mod tests {
907
926
908
927
let bob_mock = mockito:: mock ( "POST" , "/accounts/42/settlements" )
909
928
. match_body ( mockito:: Matcher :: JsonString (
910
- "{\" amount\" : 100 }" . to_string ( ) ,
929
+ "{\" amount\" : \" 100\" , \" scale \" : 18 }" . to_string ( ) ,
911
930
) )
912
931
. with_status ( 200 )
913
932
. with_body ( "OK" . to_string ( ) )
@@ -930,8 +949,8 @@ mod tests {
930
949
false , // alice sends the transaction to bob (set it up so that she doesn't listen for inc txs)
931
950
) ;
932
951
933
- let ret = block_on ( alice_engine . send_money ( bob . id . to_string ( ) , Quantity { amount : 100 } ) )
934
- . unwrap ( ) ;
952
+ let ret =
953
+ block_on ( alice_engine . send_money ( bob . id . to_string ( ) , Quantity :: new ( 100 , 6 ) ) ) . unwrap ( ) ;
935
954
assert_eq ! ( ret. 0 . as_u16( ) , 200 ) ;
936
955
assert_eq ! ( ret. 1 , "OK" ) ;
937
956
@@ -974,7 +993,7 @@ mod tests {
974
993
975
994
// the signed message does not match. We are not able to make Mockito
976
995
// capture the challenge and return a signature on it.
977
- let ret = block_on ( engine. create_account ( bob. id . to_string ( ) ) ) . unwrap_err ( ) ;
996
+ let ret = block_on ( engine. create_account ( CreateAccount :: new ( bob. id ) ) ) . unwrap_err ( ) ;
978
997
assert_eq ! ( ret. 0 . as_u16( ) , 502 ) ;
979
998
// assert_eq!(ret.1, "CREATED");
980
999
0 commit comments