1use serde::{Deserialize, Serialize};
11use std::collections::HashMap;
12
13use crate::layer2::{
14 AssetParams, AssetTransfer, Layer2Error, Layer2Protocol, Proof, ProtocolState,
15 TransactionStatus, TransferResult, ValidationResult, VerificationResult,
16};
17
18#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
20pub enum ChannelState {
21 Creating,
23 Open,
25 Closing,
27 Closed,
29 Disputed,
31}
32
33#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
35pub enum CommitmentType {
36 MultiSig2of2,
38 MuSig2of2,
40 TaprootKeySpend,
42 TaprootScriptSpend,
44}
45
46#[derive(Debug, Clone, Serialize, Deserialize)]
48pub struct StateChannelConfig {
49 pub network: String,
51 pub capacity: u64,
53 pub time_lock: u32,
55 pub commitment_type: CommitmentType,
57 pub use_taproot: bool,
59 pub fee_rate: u64,
61}
62
63impl Default for StateChannelConfig {
64 fn default() -> Self {
65 Self {
66 network: "mainnet".to_string(),
67 capacity: 1_000_000, time_lock: 144, commitment_type: CommitmentType::TaprootKeySpend,
70 use_taproot: true,
71 fee_rate: 10, }
73 }
74}
75
76#[derive(Debug, Clone, Serialize, Deserialize)]
78pub struct StateUpdate {
79 pub channel_id: String,
81 pub version: u64,
83 pub balance_a: u64,
85 pub balance_b: u64,
87 pub timestamp: u64,
89 pub signatures: Vec<String>,
91}
92
93#[derive(Debug)]
95pub struct StateChannel {
96 pub channel_id: String,
98 pub config: StateChannelConfig,
100 pub state: ChannelState,
102 pub balance_a: u64,
104 pub balance_b: u64,
106 pub pubkey_a: String,
108 pub pubkey_b: String,
110 pub version: u64,
112 pub updates: Vec<StateUpdate>,
114 pub transactions: HashMap<String, Vec<u8>>,
116}
117
118impl StateChannel {
119 pub fn new(
121 config: StateChannelConfig,
122 pubkey_a: &str,
123 pubkey_b: &str,
124 initial_balance_a: u64,
125 initial_balance_b: u64,
126 ) -> Result<Self, Box<dyn std::error::Error + Send + Sync>> {
127 if initial_balance_a + initial_balance_b != config.capacity {
129 return Err(Box::new(Layer2Error::Protocol(format!(
130 "Balances must sum to capacity: {} != {}",
131 initial_balance_a + initial_balance_b,
132 config.capacity
133 ))));
134 }
135
136 let channel_id = format!(
138 "sc_{}_{}",
139 pubkey_a.chars().take(8).collect::<String>(),
140 pubkey_b.chars().take(8).collect::<String>()
141 );
142
143 let updates = Vec::new();
145 let transactions = HashMap::new();
146
147 Ok(Self {
148 channel_id,
149 config,
150 state: ChannelState::Creating,
151 balance_a: initial_balance_a,
152 balance_b: initial_balance_b,
153 pubkey_a: pubkey_a.to_string(),
154 pubkey_b: pubkey_b.to_string(),
155 version: 0,
156 updates,
157 transactions,
158 })
159 }
160
161 pub fn new_default() -> Self {
163 let config = StateChannelConfig::default();
165 let pubkey_a = "02d0de0aaeaefad02b8bdc8a01a1b8b11c696bd3d66a2c5f10780d95b7df42645c";
166 let pubkey_b = "03a36339f413da869df12b1ab0def91749413a0dee87f0bfa85ba7196e6cdad102";
167 let half_capacity = config.capacity / 2;
168
169 match Self::new(config, pubkey_a, pubkey_b, half_capacity, half_capacity) {
170 Ok(channel) => channel,
171 Err(_) => {
172 Self {
175 channel_id: "sc_default".to_string(),
176 config: StateChannelConfig::default(),
177 state: ChannelState::Creating,
178 balance_a: 500_000,
179 balance_b: 500_000,
180 pubkey_a: pubkey_a.to_string(),
181 pubkey_b: pubkey_b.to_string(),
182 version: 0,
183 updates: Vec::new(),
184 transactions: HashMap::new(),
185 }
186 }
187 }
188 }
189}
190
191impl Default for StateChannel {
192 fn default() -> Self {
193 Self::new_default()
194 }
195}
196
197impl StateChannel {
198 pub fn open(&mut self) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
200 if self.state != ChannelState::Creating {
201 return Err(Box::new(Layer2Error::Protocol(
202 "Channel must be in Creating state to open".to_string(),
203 )));
204 }
205
206 let funding_tx_id = format!("funding_{}", self.channel_id);
211
212 let tx_data = vec![0u8; 32]; self.transactions.insert(funding_tx_id.clone(), tx_data);
217
218 self.state = ChannelState::Open;
220
221 Ok(funding_tx_id)
222 }
223
224 pub fn update_state(
226 &mut self,
227 balance_a: u64,
228 balance_b: u64,
229 signatures: Vec<String>,
230 ) -> Result<StateUpdate, Box<dyn std::error::Error + Send + Sync>> {
231 if self.state != ChannelState::Open {
232 return Err(Box::new(Layer2Error::Protocol(
233 "Channel must be open to update state".to_string(),
234 )));
235 }
236
237 if balance_a + balance_b != self.config.capacity {
239 return Err(Box::new(Layer2Error::Protocol(format!(
240 "Balances must sum to capacity: {} != {}",
241 balance_a + balance_b,
242 self.config.capacity
243 ))));
244 }
245
246 if signatures.len() != 2 {
248 return Err(Box::new(Layer2Error::Protocol(
249 "Must provide exactly 2 signatures".to_string(),
250 )));
251 }
252
253 self.version += 1;
255
256 let timestamp = std::time::SystemTime::now()
258 .duration_since(std::time::UNIX_EPOCH)
259 .unwrap()
260 .as_secs();
261
262 let update = StateUpdate {
264 channel_id: self.channel_id.clone(),
265 version: self.version,
266 balance_a,
267 balance_b,
268 timestamp,
269 signatures,
270 };
271
272 self.balance_a = balance_a;
274 self.balance_b = balance_b;
275
276 self.updates.push(update.clone());
278
279 Ok(update)
280 }
281
282 pub fn close_cooperative(
284 &mut self,
285 ) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
286 if self.state != ChannelState::Open {
287 return Err(Box::new(Layer2Error::Protocol(
288 "Channel must be open to close cooperatively".to_string(),
289 )));
290 }
291
292 let closing_tx_id = format!("closing_{}", self.channel_id);
296
297 let tx_data = vec![0u8; 32]; self.transactions.insert(closing_tx_id.clone(), tx_data);
302
303 self.state = ChannelState::Closing;
305
306 Ok(closing_tx_id)
307 }
308
309 pub fn force_close(&mut self) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
311 if self.state != ChannelState::Open && self.state != ChannelState::Disputed {
312 return Err(Box::new(Layer2Error::Protocol(
313 "Channel must be open or disputed to force close".to_string(),
314 )));
315 }
316
317 let force_closing_tx_id = format!("force_closing_{}", self.channel_id);
321
322 let tx_data = vec![0u8; 32]; self.transactions
327 .insert(force_closing_tx_id.clone(), tx_data);
328
329 self.state = ChannelState::Closing;
331
332 Ok(force_closing_tx_id)
333 }
334
335 pub fn get_latest_update(&self) -> Option<&StateUpdate> {
337 self.updates.last()
338 }
339
340 pub fn get_update_by_version(&self, version: u64) -> Option<&StateUpdate> {
342 self.updates.iter().find(|u| u.version == version)
343 }
344
345 pub fn get_transaction(&self, tx_id: &str) -> Option<&Vec<u8>> {
347 self.transactions.get(tx_id)
348 }
349}
350
351impl crate::layer2::Layer2ProtocolTrait for StateChannel {
353 fn initialize(&self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
354 Ok(())
356 }
357
358 fn get_state(&self) -> Result<ProtocolState, Box<dyn std::error::Error + Send + Sync>> {
359 Ok(crate::layer2::create_protocol_state(
360 "1.0.0",
361 2,
362 Some(self.config.capacity),
363 self.state == ChannelState::Open,
364 ))
365 }
366
367 fn submit_transaction(
368 &self,
369 tx_data: &[u8],
370 ) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
371 let tx_id = format!("tx_{}", hex::encode(&tx_data[0..4]));
376 Ok(tx_id)
377 }
378
379 fn check_transaction_status(
380 &self,
381 tx_id: &str,
382 ) -> Result<TransactionStatus, Box<dyn std::error::Error + Send + Sync>> {
383 if self.transactions.contains_key(tx_id) {
385 Ok(TransactionStatus::Confirmed)
386 } else {
387 Ok(TransactionStatus::Pending)
388 }
389 }
390
391 fn sync_state(&mut self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
392 Ok(())
395 }
396
397 fn issue_asset(
398 &self,
399 _params: AssetParams,
400 ) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
401 Err(Box::new(Layer2Error::Protocol(
403 "Asset issuance not supported in state channels".to_string(),
404 )))
405 }
406
407 fn transfer_asset(
408 &self,
409 _transfer: AssetTransfer,
410 ) -> Result<TransferResult, Box<dyn std::error::Error + Send + Sync>> {
411 if self.state != ChannelState::Open {
414 return Err(Box::new(Layer2Error::Protocol(
415 "Channel must be open to transfer assets".to_string(),
416 )));
417 }
418
419 let timestamp = std::time::SystemTime::now()
421 .duration_since(std::time::UNIX_EPOCH)
422 .unwrap()
423 .as_secs();
424
425 Ok(TransferResult {
426 tx_id: format!("sc_transfer_{timestamp}"),
427 status: TransactionStatus::Confirmed,
428 fee: Some(0), timestamp,
430 })
431 }
432
433 fn verify_proof(
434 &self,
435 proof: Proof,
436 ) -> Result<VerificationResult, Box<dyn std::error::Error + Send + Sync>> {
437 let is_valid = proof.proof_type == "state_update_proof";
440
441 let _timestamp = std::time::SystemTime::now()
443 .duration_since(std::time::UNIX_EPOCH)
444 .unwrap()
445 .as_secs();
446
447 Ok(crate::layer2::create_verification_result(
448 is_valid,
449 if is_valid {
450 None
451 } else {
452 Some("Invalid proof type".to_string())
453 },
454 ))
455 }
456
457 fn validate_state(
458 &self,
459 _state_data: &[u8],
460 ) -> Result<ValidationResult, Box<dyn std::error::Error + Send + Sync>> {
461 let _timestamp = std::time::SystemTime::now()
467 .duration_since(std::time::UNIX_EPOCH)
468 .unwrap()
469 .as_secs();
470
471 Ok(crate::layer2::create_validation_result(true, vec![]))
472 }
473}
474
475#[derive(Debug)]
477pub struct StateChannelsProtocol {
478 channels: HashMap<String, StateChannel>,
479}
480
481impl StateChannelsProtocol {
482 pub fn new() -> Self {
484 Self {
485 channels: HashMap::new(),
486 }
487 }
488}
489
490impl Default for StateChannelsProtocol {
491 fn default() -> Self {
492 Self::new()
493 }
494}
495
496#[async_trait::async_trait]
497impl crate::layer2::Layer2Protocol for StateChannelsProtocol {
498 async fn initialize(&self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
499 Ok(())
500 }
501
502 async fn connect(&self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
503 Ok(())
504 }
505
506 async fn get_state(
507 &self,
508 ) -> Result<crate::layer2::ProtocolState, Box<dyn std::error::Error + Send + Sync>> {
509 Ok(crate::layer2::create_protocol_state(
510 "1.0.0",
511 self.channels.len() as u32,
512 Some(4000000),
513 true,
514 ))
515 }
516
517 async fn submit_transaction(
518 &self,
519 _tx_data: &[u8],
520 ) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
521 Ok("mock_state_channel_tx_id".to_string())
522 }
523
524 async fn check_transaction_status(
525 &self,
526 _tx_id: &str,
527 ) -> Result<crate::layer2::TransactionStatus, Box<dyn std::error::Error + Send + Sync>> {
528 Ok(crate::layer2::TransactionStatus::Confirmed)
529 }
530
531 async fn sync_state(&mut self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
532 Ok(())
533 }
534
535 async fn issue_asset(
536 &self,
537 _params: crate::layer2::AssetParams,
538 ) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
539 Ok("mock_state_channel_asset_id".to_string())
540 }
541
542 async fn transfer_asset(
543 &self,
544 _transfer: crate::layer2::AssetTransfer,
545 ) -> Result<crate::layer2::TransferResult, Box<dyn std::error::Error + Send + Sync>> {
546 Ok(crate::layer2::TransferResult {
547 tx_id: "mock_state_channel_transfer_id".to_string(),
548 status: crate::layer2::TransactionStatus::Confirmed,
549 fee: Some(100),
550 timestamp: std::time::SystemTime::now()
551 .duration_since(std::time::UNIX_EPOCH)
552 .unwrap()
553 .as_secs(),
554 })
555 }
556
557 async fn verify_proof(
558 &self,
559 _proof: crate::layer2::Proof,
560 ) -> Result<crate::layer2::VerificationResult, Box<dyn std::error::Error + Send + Sync>> {
561 Ok(crate::layer2::create_verification_result(true, None))
562 }
563
564 async fn validate_state(
565 &self,
566 _state_data: &[u8],
567 ) -> Result<crate::layer2::ValidationResult, Box<dyn std::error::Error + Send + Sync>> {
568 Ok(crate::layer2::create_validation_result(true, vec![]))
569 }
570}
571
572#[async_trait::async_trait]
574impl Layer2Protocol for StateChannel {
575 async fn initialize(&self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
576 println!("Asynchronously initializing State Channel...");
577 Ok(())
578 }
579
580 async fn connect(&self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
581 println!("Asynchronously connecting State Channel...");
582 Ok(())
583 }
584
585 async fn get_state(&self) -> Result<ProtocolState, Box<dyn std::error::Error + Send + Sync>> {
586 println!("Asynchronously getting State Channel state...");
587 Ok(ProtocolState {
588 version: "1.0".to_string(),
589 connections: 1,
590 capacity: Some(self.config.capacity),
591 operational: true,
592 height: 0,
593 hash: "0000000000000000000000000000000000000000000000000000000000000000".to_string(),
594 timestamp: std::time::SystemTime::now()
595 .duration_since(std::time::UNIX_EPOCH)
596 .unwrap()
597 .as_secs(),
598 })
599 }
600
601 async fn submit_transaction(
602 &self,
603 tx_data: &[u8],
604 ) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
605 println!(
606 "Asynchronously submitting transaction to State Channel: {} bytes",
607 tx_data.len()
608 );
609 Ok(format!("tx_{}", hex::encode(&tx_data[0..4])))
610 }
611
612 async fn check_transaction_status(
613 &self,
614 tx_id: &str,
615 ) -> Result<TransactionStatus, Box<dyn std::error::Error + Send + Sync>> {
616 println!(
617 "Asynchronously checking State Channel transaction status: {}",
618 tx_id
619 );
620 Ok(TransactionStatus::Confirmed)
621 }
622
623 async fn sync_state(&mut self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
624 println!("Asynchronously syncing State Channel state...");
625 Ok(())
626 }
627
628 async fn issue_asset(
629 &self,
630 params: AssetParams,
631 ) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
632 println!(
633 "Asynchronously issuing asset {} on State Channel",
634 params.name
635 );
636 Ok(format!("sc_asset_{}", params.asset_id))
637 }
638
639 async fn transfer_asset(
640 &self,
641 transfer: AssetTransfer,
642 ) -> Result<TransferResult, Box<dyn std::error::Error + Send + Sync>> {
643 println!(
644 "Asynchronously transferring {} of asset {} to {} on State Channel",
645 transfer.amount, transfer.asset_id, transfer.recipient
646 );
647
648 Ok(TransferResult {
649 tx_id: format!("sc_transfer_{}", transfer.asset_id),
650 status: TransactionStatus::Confirmed,
651 fee: Some(100),
652 timestamp: std::time::SystemTime::now()
653 .duration_since(std::time::UNIX_EPOCH)
654 .unwrap()
655 .as_secs(),
656 })
657 }
658
659 async fn verify_proof(
660 &self,
661 proof: Proof,
662 ) -> Result<VerificationResult, Box<dyn std::error::Error + Send + Sync>> {
663 println!(
664 "Asynchronously verifying {} proof on State Channel",
665 proof.proof_type
666 );
667
668 Ok(VerificationResult {
669 valid: true,
670 is_valid: true,
671 error: None,
672 timestamp: std::time::SystemTime::now()
673 .duration_since(std::time::UNIX_EPOCH)
674 .unwrap()
675 .as_secs(),
676 })
677 }
678
679 async fn validate_state(
680 &self,
681 state_data: &[u8],
682 ) -> Result<ValidationResult, Box<dyn std::error::Error + Send + Sync>> {
683 println!(
684 "Asynchronously validating state on State Channel: {} bytes",
685 state_data.len()
686 );
687
688 Ok(ValidationResult {
689 is_valid: true,
690 violations: vec![],
691 timestamp: std::time::SystemTime::now()
692 .duration_since(std::time::UNIX_EPOCH)
693 .unwrap()
694 .as_secs(),
695 })
696 }
697}
698
699#[cfg(test)]
700mod tests {
701 use super::*;
702
703 #[test]
704 fn test_state_channel_creation() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
705 let config = StateChannelConfig {
706 network: "testnet".to_string(),
707 capacity: 1_000_000, time_lock: 144, commitment_type: CommitmentType::TaprootKeySpend,
710 use_taproot: true,
711 fee_rate: 1, };
713
714 let pubkey_a = "0283863a78ec0df67ae8f369e4082a1f67ce09e309e3ce35c6dc4a7e2cb425993c";
715 let pubkey_b = "02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9";
716
717 let channel = StateChannel::new(config, pubkey_a, pubkey_b, 600_000, 400_000)?;
718
719 assert_eq!(channel.state, ChannelState::Creating);
720 assert_eq!(channel.balance_a, 600_000);
721 assert_eq!(channel.balance_b, 400_000);
722 assert_eq!(channel.version, 0);
723 assert!(channel.updates.is_empty());
724
725 Ok(())
726 }
727
728 #[test]
729 fn test_state_channel_open_and_update() -> Result<(), Box<dyn std::error::Error + Send + Sync>>
730 {
731 let config = StateChannelConfig {
732 network: "testnet".to_string(),
733 capacity: 1_000_000, time_lock: 144, commitment_type: CommitmentType::TaprootKeySpend,
736 use_taproot: true,
737 fee_rate: 1, };
739
740 let pubkey_a = "0283863a78ec0df67ae8f369e4082a1f67ce09e309e3ce35c6dc4a7e2cb425993c";
741 let pubkey_b = "02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9";
742
743 let mut channel = StateChannel::new(config, pubkey_a, pubkey_b, 600_000, 400_000)?;
744
745 let funding_tx_id = channel.open()?;
747 assert!(funding_tx_id.starts_with("funding_"));
748 assert_eq!(channel.state, ChannelState::Open);
749
750 let signatures = vec!["sig_a".to_string(), "sig_b".to_string()];
752 let update = channel.update_state(500_000, 500_000, signatures)?;
753
754 assert_eq!(update.version, 1);
755 assert_eq!(update.balance_a, 500_000);
756 assert_eq!(update.balance_b, 500_000);
757 assert_eq!(channel.balance_a, 500_000);
758 assert_eq!(channel.balance_b, 500_000);
759
760 Ok(())
761 }
762}