mirror of
https://github.com/aljazceru/cdk.git
synced 2025-12-19 05:35:18 +01:00
Swap saga (#1183)
# Implement Saga Pattern for Swap Operations with Recovery Mechanism ## Overview This PR refactors the swap operation implementation to use the saga pattern - a distributed transaction pattern that provides reliable transaction management through explicit state tracking and compensation-based error handling. The implementation includes a robust recovery mechanism that automatically handles swap operations interrupted by crashes, power loss, or network failures. ## What Changed **Saga Pattern Implementation:** - Introduced a strict linear state machine for swaps: `Initial` → `SetupComplete` → `Signed` → `Completed` - New modular `swap_saga` module with state validation, compensation logic, and saga orchestration - Automatic rollback of database changes on failure, ensuring atomic swap operations - Replaced previous swap implementation (`swap.rs`, `blinded_message_writer.rs`) with saga-based approach **Recovery Mechanism:** - Added `operation_id` and `operation_kind` columns to database schema for tracking which operation proofs belong to - New `recover_from_bad_swaps()` method that runs on mint startup to handle incomplete swaps - For proofs left in `PENDING` state from swap operations: - If blind signatures exist: marks proofs as `SPENT` (swap completed but not finalized) - If no blind signatures exist: removes proofs from database (swap failed partway through) - Database migrations included for both PostgreSQL and SQLite
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use cdk_common::database::{self, MintDatabase, MintKeysDatabase};
|
||||
use cdk_common::mint::{self, MintKeySetInfo, MintQuote};
|
||||
use cdk_common::mint::{self, MintKeySetInfo, MintQuote, Operation};
|
||||
use cdk_common::nuts::{CurrencyUnit, Id, Proofs};
|
||||
use cdk_common::MintInfo;
|
||||
|
||||
@@ -56,8 +56,10 @@ pub async fn new_with_state(
|
||||
tx.add_melt_quote(quote).await?;
|
||||
}
|
||||
|
||||
tx.add_proofs(pending_proofs, None).await?;
|
||||
tx.add_proofs(spent_proofs, None).await?;
|
||||
tx.add_proofs(pending_proofs, None, &Operation::new_swap())
|
||||
.await?;
|
||||
tx.add_proofs(spent_proofs, None, &Operation::new_swap())
|
||||
.await?;
|
||||
let mint_info_bytes = serde_json::to_vec(&mint_info)?;
|
||||
tx.kv_write(
|
||||
CDK_MINT_PRIMARY_NAMESPACE,
|
||||
|
||||
Reference in New Issue
Block a user