/ tests / integration_tests.rs
integration_tests.rs
  1  // Copyright (c) 2025 ADnet Contributors
  2  // SPDX-License-Identifier: Apache-2.0
  3  
  4  //! Integration tests for ADnet unified node
  5  //!
  6  //! These tests verify end-to-end functionality of the unified ALPHA/DELTA node,
  7  //! including trading execution, attestation flow, and cross-chain operations.
  8  
  9  use adnet::AdnetNode;
 10  use alphavm::console::network::MainnetV0;
 11  
 12  type CurrentNetwork = MainnetV0;
 13  
 14  /// Test that a node can be created and initialized in dev mode
 15  #[tokio::test]
 16  async fn test_node_creation_and_init() {
 17      // Create a dev node with 4 validators
 18      let node = AdnetNode::<CurrentNetwork>::dev(4, 0);
 19  
 20      // Verify configuration
 21      assert_eq!(node.config().alpha.rest_port, 3030);
 22      assert_eq!(node.config().delta.rest_port, 4030);
 23  
 24      // Initialize the node
 25      node.init().await.expect("Failed to initialize node");
 26  
 27      // Verify state after init
 28      let state = node.state().await;
 29      assert!(state.is_running);
 30      assert_eq!(state.alpha_height, 0);
 31      assert_eq!(state.delta_height, 0);
 32  }
 33  
 34  /// Test that multiple validator nodes can be created without port conflicts
 35  #[tokio::test]
 36  async fn test_multiple_validators_config() {
 37      let node0 = AdnetNode::<CurrentNetwork>::dev(4, 0);
 38      let node1 = AdnetNode::<CurrentNetwork>::dev(4, 1);
 39      let node2 = AdnetNode::<CurrentNetwork>::dev(4, 2);
 40      let node3 = AdnetNode::<CurrentNetwork>::dev(4, 3);
 41  
 42      // Verify unique ports for each validator
 43      assert_eq!(node0.config().alpha.rest_port, 3030);
 44      assert_eq!(node1.config().alpha.rest_port, 3031);
 45      assert_eq!(node2.config().alpha.rest_port, 3032);
 46      assert_eq!(node3.config().alpha.rest_port, 3033);
 47  
 48      assert_eq!(node0.config().delta.rest_port, 4030);
 49      assert_eq!(node1.config().delta.rest_port, 4031);
 50      assert_eq!(node2.config().delta.rest_port, 4032);
 51      assert_eq!(node3.config().delta.rest_port, 4033);
 52  
 53      // Verify unique P2P ports
 54      assert_eq!(node0.config().alpha.p2p_port, 4130);
 55      assert_eq!(node1.config().alpha.p2p_port, 4131);
 56      assert_eq!(node2.config().alpha.p2p_port, 4132);
 57      assert_eq!(node3.config().alpha.p2p_port, 4133);
 58  }
 59  
 60  /// Test trading execution via DeltaRuntime
 61  #[tokio::test]
 62  async fn test_trading_execution() {
 63      use deltavm_console::Address;
 64      use deltavm_execution::{
 65          DeltaRuntime, OrderSide, OrderType, TradingPair, TradingResult, TradingTx,
 66      };
 67  
 68      let mut runtime = DeltaRuntime::new();
 69  
 70      // Create a test user
 71      let user = Address::zero();
 72  
 73      // Fund the user first (in a real test, this would come from deposit)
 74      // Note: Use "AX" for ALPHA token after rebranding
 75      runtime
 76          .ledger
 77          .credit(&user, "AX", 1_000_000)
 78          .expect("Failed to credit");
 79  
 80      // Place a limit buy order
 81      let tx = TradingTx::PlaceOrder {
 82          pair: TradingPair::DeltaAlpha,
 83          side: OrderSide::Buy,
 84          quantity: 100,
 85          price: Some(1000),
 86          order_type: OrderType::Limit,
 87      };
 88  
 89      let result = runtime.execute_trading(user, tx);
 90      assert!(result.is_ok());
 91  
 92      match result.unwrap() {
 93          TradingResult::OrderPlaced { match_result, .. } => {
 94              assert!(match_result.added_to_book);
 95              assert!(match_result.trades.is_empty()); // No matching orders yet
 96          }
 97          _ => panic!("Expected OrderPlaced result"),
 98      }
 99  }
100  
101  /// Test order matching between two users
102  #[tokio::test]
103  async fn test_order_matching() {
104      use alphavm::console::types::Group;
105      use deltavm_console::Address;
106      use deltavm_execution::{
107          DeltaRuntime, OrderSide, OrderType, TradingPair, TradingResult, TradingTx,
108      };
109  
110      let mut runtime = DeltaRuntime::new();
111  
112      // Create two test users
113      let buyer = Address::zero();
114      let generator = Group::<CurrentNetwork>::generator();
115      let seller = Address::new(generator);
116  
117      // Fund both users (AX = ALPHA token, DX = DELTA token)
118      runtime
119          .ledger
120          .credit(&buyer, "AX", 1_000_000)
121          .expect("Failed to credit buyer");
122      runtime
123          .ledger
124          .credit(&seller, "DX", 1_000_000)
125          .expect("Failed to credit seller");
126  
127      // Seller places a limit sell order
128      let sell_tx = TradingTx::PlaceOrder {
129          pair: TradingPair::DeltaAlpha,
130          side: OrderSide::Sell,
131          quantity: 100,
132          price: Some(1000),
133          order_type: OrderType::Limit,
134      };
135  
136      let sell_result = runtime.execute_trading(seller, sell_tx).unwrap();
137      assert!(matches!(sell_result, TradingResult::OrderPlaced { .. }));
138  
139      // Buyer places a matching buy order
140      let buy_tx = TradingTx::PlaceOrder {
141          pair: TradingPair::DeltaAlpha,
142          side: OrderSide::Buy,
143          quantity: 100,
144          price: Some(1000),
145          order_type: OrderType::Limit,
146      };
147  
148      let buy_result = runtime.execute_trading(buyer, buy_tx).unwrap();
149  
150      match buy_result {
151          TradingResult::OrderPlaced {
152              match_result,
153              trades_executed,
154          } => {
155              assert_eq!(trades_executed, 1);
156              assert_eq!(match_result.trades.len(), 1);
157  
158              let trade = &match_result.trades[0];
159              assert_eq!(trade.quantity, 100);
160              assert_eq!(trade.price, 1000);
161          }
162          _ => panic!("Expected OrderPlaced with trades"),
163      }
164  }
165  
166  /// Test bridge stats are tracked correctly
167  #[tokio::test]
168  async fn test_bridge_stats() {
169      let node = AdnetNode::<CurrentNetwork>::dev(4, 0);
170      node.init().await.expect("Failed to initialize node");
171  
172      let stats = node.bridge_stats().await;
173      assert_eq!(stats.attestations_sent, 0);
174      assert_eq!(stats.deposits_processed, 0);
175      assert_eq!(stats.withdrawals_processed, 0);
176      assert!(!stats.is_halted);
177  }
178  
179  /// Test order book snapshot
180  #[tokio::test]
181  async fn test_orderbook_snapshot() {
182      use deltavm_console::Address;
183      use deltavm_execution::{DeltaRuntime, OrderSide, OrderType, TradingPair, TradingTx};
184  
185      let mut runtime = DeltaRuntime::new();
186      let user = Address::zero();
187      runtime
188          .ledger
189          .credit(&user, "AX", 1_000_000)
190          .expect("Failed to credit");
191  
192      // Place multiple orders at different prices
193      for price in [1000, 1010, 1020] {
194          let tx = TradingTx::PlaceOrder {
195              pair: TradingPair::DeltaAlpha,
196              side: OrderSide::Buy,
197              quantity: 100,
198              price: Some(price),
199              order_type: OrderType::Limit,
200          };
201          runtime.execute_trading(user, tx).unwrap();
202      }
203  
204      // Get order book snapshot
205      let snapshot = runtime
206          .matching_engine
207          .get_order_book_snapshot(&TradingPair::DeltaAlpha);
208  
209      // Verify we have 3 bid levels
210      assert_eq!(snapshot.bids.len(), 3);
211  
212      // Verify all prices are present
213      let prices: Vec<u64> = snapshot.bids.iter().map(|l| l.price).collect();
214      assert!(prices.contains(&1000));
215      assert!(prices.contains(&1010));
216      assert!(prices.contains(&1020));
217  
218      // Verify best bid is set
219      assert!(snapshot.best_bid.is_some());
220  }
221  
222  /// Test order cancellation
223  #[tokio::test]
224  async fn test_order_cancellation() {
225      use deltavm_console::Address;
226      use deltavm_execution::{
227          DeltaRuntime, OrderSide, OrderType, TradingPair, TradingResult, TradingTx,
228      };
229  
230      let mut runtime = DeltaRuntime::new();
231      let user = Address::zero();
232      runtime
233          .ledger
234          .credit(&user, "AX", 1_000_000)
235          .expect("Failed to credit");
236  
237      // Place an order
238      let tx = TradingTx::PlaceOrder {
239          pair: TradingPair::DeltaAlpha,
240          side: OrderSide::Buy,
241          quantity: 100,
242          price: Some(1000),
243          order_type: OrderType::Limit,
244      };
245  
246      let place_result = runtime.execute_trading(user, tx).unwrap();
247      let order_id = match place_result {
248          TradingResult::OrderPlaced { match_result, .. } => match_result.order.id,
249          _ => panic!("Expected OrderPlaced"),
250      };
251  
252      // Cancel the order
253      let cancel_tx = TradingTx::CancelOrder {
254          order_id: order_id.clone(),
255      };
256      let cancel_result = runtime.execute_trading(user, cancel_tx);
257  
258      assert!(cancel_result.is_ok());
259      match cancel_result.unwrap() {
260          TradingResult::OrderCancelled { order } => {
261              assert_eq!(order.id.0, order_id.0);
262          }
263          TradingResult::Failed { reason } => {
264              panic!("Cancel failed: {}", reason);
265          }
266          _ => panic!("Expected OrderCancelled"),
267      }
268  }
269  
270  /// Test ledger balance operations
271  #[tokio::test]
272  async fn test_ledger_balances() {
273      use deltavm_console::Address;
274      use deltavm_ledger::TradingLedger;
275  
276      let mut ledger = TradingLedger::new();
277      let user = Address::zero();
278  
279      // Credit some balance (AX = ALPHA token)
280      ledger.credit(&user, "AX", 1000).expect("Failed to credit");
281      assert_eq!(ledger.balance(&user, "AX"), 1000);
282  
283      // Debit some balance
284      ledger.debit(&user, "AX", 400).expect("Failed to debit");
285      assert_eq!(ledger.balance(&user, "AX"), 600);
286  
287      // Debit more than available should fail
288      let result = ledger.debit(&user, "AX", 1000);
289      assert!(result.is_err());
290  }
291  
292  /// Test withdrawal processor via DeltaRuntime.bridge
293  #[tokio::test]
294  async fn test_withdrawal_processor() {
295      use deltavm_execution::DeltaRuntime;
296  
297      let runtime = DeltaRuntime::new();
298  
299      // Verify initial state
300      let stats = runtime.bridge_stats();
301      assert_eq!(stats.total_fees, 0);
302      assert_eq!(stats.total_deposits, 0);
303      assert_eq!(stats.total_withdrawals, 0);
304  }
305  
306  /// Test deposit processor (finalization)
307  #[tokio::test]
308  async fn test_deposit_finalization() {
309      use deltavm_ledger::DepositProcessor;
310  
311      let processor = DepositProcessor::<CurrentNetwork>::new(10);
312  
313      // Verify finalization depth
314      assert_eq!(processor.finalization_depth(), 10);
315      assert_eq!(processor.total_deposited(), 0);
316  }