1+ //! Tests for ManagedExchangeProvider
2+
3+ use ferrofluid:: {
4+ providers:: { ManagedExchangeProvider , OrderHandle } ,
5+ types:: requests:: { OrderRequest , OrderType , Limit } ,
6+ constants:: * ,
7+ } ;
8+ use alloy:: signers:: local:: PrivateKeySigner ;
9+ use std:: time:: Duration ;
10+
11+ #[ tokio:: test]
12+ async fn test_managed_provider_creation ( ) {
13+ // Initialize CryptoProvider for rustls
14+ rustls:: crypto:: CryptoProvider :: install_default (
15+ rustls:: crypto:: ring:: default_provider ( )
16+ ) . ok ( ) ;
17+
18+ // Create a test signer
19+ let signer = PrivateKeySigner :: random ( ) ;
20+
21+ // Create managed provider with default config
22+ let exchange = ManagedExchangeProvider :: builder ( signer)
23+ . with_network ( ferrofluid:: Network :: Testnet )
24+ . build ( )
25+ . await ;
26+
27+ assert ! ( exchange. is_ok( ) ) ;
28+ }
29+
30+ #[ tokio:: test]
31+ async fn test_managed_provider_with_batching ( ) {
32+ // Initialize CryptoProvider for rustls
33+ rustls:: crypto:: CryptoProvider :: install_default (
34+ rustls:: crypto:: ring:: default_provider ( )
35+ ) . ok ( ) ;
36+
37+ let signer = PrivateKeySigner :: random ( ) ;
38+
39+ // Create with batching enabled
40+ let exchange = ManagedExchangeProvider :: builder ( signer)
41+ . with_network ( ferrofluid:: Network :: Testnet )
42+ . with_auto_batching ( Duration :: from_millis ( 50 ) )
43+ . without_agent_rotation ( ) // Disable for testing
44+ . build ( )
45+ . await
46+ . unwrap ( ) ;
47+
48+ // Create a test order
49+ let order = OrderRequest {
50+ asset : 0 ,
51+ is_buy : true ,
52+ limit_px : "50000" . to_string ( ) ,
53+ sz : "0.01" . to_string ( ) ,
54+ reduce_only : false ,
55+ order_type : OrderType :: Limit ( Limit { tif : TIF_GTC . to_string ( ) } ) ,
56+ cloid : None ,
57+ } ;
58+
59+ // Place order should return pending handle
60+ let handle = exchange. place_order ( & order) . await . unwrap ( ) ;
61+
62+ match handle {
63+ OrderHandle :: Pending { .. } => {
64+ // Expected for batched orders
65+ }
66+ OrderHandle :: Immediate ( _) => {
67+ panic ! ( "Expected pending handle for batched order" ) ;
68+ }
69+ }
70+ }
71+
72+ #[ tokio:: test]
73+ async fn test_alo_order_detection ( ) {
74+ let order = OrderRequest {
75+ asset : 0 ,
76+ is_buy : true ,
77+ limit_px : "50000" . to_string ( ) ,
78+ sz : "0.01" . to_string ( ) ,
79+ reduce_only : false ,
80+ order_type : OrderType :: Limit ( Limit { tif : "Alo" . to_string ( ) } ) ,
81+ cloid : None ,
82+ } ;
83+
84+ assert ! ( order. is_alo( ) ) ;
85+
86+ let regular_order = OrderRequest {
87+ asset : 0 ,
88+ is_buy : true ,
89+ limit_px : "50000" . to_string ( ) ,
90+ sz : "0.01" . to_string ( ) ,
91+ reduce_only : false ,
92+ order_type : OrderType :: Limit ( Limit { tif : "Gtc" . to_string ( ) } ) ,
93+ cloid : None ,
94+ } ;
95+
96+ assert ! ( !regular_order. is_alo( ) ) ;
97+ }
98+
99+ #[ test]
100+ fn test_nonce_generation ( ) {
101+ use ferrofluid:: providers:: nonce:: NonceManager ;
102+
103+ let manager = NonceManager :: new ( false ) ;
104+
105+ let nonce1 = manager. next_nonce ( None ) ;
106+ let nonce2 = manager. next_nonce ( None ) ;
107+
108+ assert ! ( nonce2 > nonce1) ;
109+ assert ! ( NonceManager :: is_valid_nonce( nonce1) ) ;
110+ assert ! ( NonceManager :: is_valid_nonce( nonce2) ) ;
111+ }
112+
113+ #[ test]
114+ fn test_nonce_isolation ( ) {
115+ use ferrofluid:: providers:: nonce:: NonceManager ;
116+ use alloy:: primitives:: Address ;
117+
118+ let manager = NonceManager :: new ( true ) ;
119+ let addr1 = Address :: new ( [ 1u8 ; 20 ] ) ;
120+ let addr2 = Address :: new ( [ 2u8 ; 20 ] ) ;
121+
122+ // Get initial nonces - these should have different millisecond timestamps
123+ let n1_1 = manager. next_nonce ( Some ( addr1) ) ;
124+ std:: thread:: sleep ( std:: time:: Duration :: from_millis ( 1 ) ) ;
125+ let n2_1 = manager. next_nonce ( Some ( addr2) ) ;
126+ std:: thread:: sleep ( std:: time:: Duration :: from_millis ( 1 ) ) ;
127+ let n1_2 = manager. next_nonce ( Some ( addr1) ) ;
128+ std:: thread:: sleep ( std:: time:: Duration :: from_millis ( 1 ) ) ;
129+ let n2_2 = manager. next_nonce ( Some ( addr2) ) ;
130+
131+ // Each address should have independent, increasing nonces
132+ assert ! ( n1_2 > n1_1, "addr1 nonces should increase" ) ;
133+ assert ! ( n2_2 > n2_1, "addr2 nonces should increase" ) ;
134+
135+ // Verify counter independence using the manager's get_counter method
136+ assert_eq ! ( manager. get_counter( Some ( addr1) ) , 2 ) ; // addr1 has 2 nonces
137+ assert_eq ! ( manager. get_counter( Some ( addr2) ) , 2 ) ; // addr2 has 2 nonces
138+
139+ // The nonces themselves should be unique
140+ assert_ne ! ( n1_1, n2_1) ;
141+ assert_ne ! ( n1_2, n2_2) ;
142+ }
0 commit comments