Implement optimistic locking for read-update-write swap operations (#652)

* Implement optimistic locking for read-update-write swap operations

* Fail on stale swap update and add tests
This commit is contained in:
Daniel Granhão
2025-01-12 22:44:15 +00:00
committed by GitHub
parent 50cb8be18c
commit 95bbd0e49b
10 changed files with 205 additions and 25 deletions

View File

@@ -4,12 +4,17 @@ use std::time::Duration;
use anyhow::{anyhow, Result};
use futures_util::TryFutureExt;
use model::data::PaymentDetailsSyncData;
use tokio::sync::mpsc::Receiver;
use tokio::sync::{watch, Mutex};
use self::client::SyncerClient;
use self::model::{data::SyncData, sync::ListChangesRequest, RecordType, SyncState};
use self::model::{DecryptionError, SyncOutgoingChanges};
use crate::prelude::Swap;
use crate::recover::recoverer::Recoverer;
use crate::sync::model::data::{
ChainSyncData, PaymentDetailsSyncData, ReceiveSyncData, SendSyncData,
};
use crate::sync::model::sync::{Record, SetRecordRequest, SetRecordStatus};
use crate::sync::model::DecryptionInfo;
use crate::utils;
@@ -18,14 +23,6 @@ use crate::{
prelude::Signer,
};
use self::client::SyncerClient;
use self::model::{
data::{ChainSyncData, ReceiveSyncData, SendSyncData, SyncData},
sync::ListChangesRequest,
RecordType, SyncState,
};
use self::model::{DecryptionError, SyncOutgoingChanges};
pub(crate) mod client;
pub(crate) mod model;
@@ -286,7 +283,17 @@ impl SyncService {
for decryption_info in swap_decryption_info {
let record = &decryption_info.record;
match TryInto::<Swap>::try_into(record.data.clone()) {
Ok(swap) => {
Ok(mut swap) => {
// If there is a local swap, take its version to prevent races between the
// recovery of step 2 and other potential changes occurring in parallel
// (e.g. a refund tx being broadcasted)
if let Ok(version) = self
.persister
.fetch_swap_by_id(&swap.id())
.map(|s| s.version())
{
swap.set_version(version);
}
succeded.push(decryption_info);
swaps.push(swap);
}

View File

@@ -110,6 +110,7 @@ impl From<ChainSyncData> for ChainSwap {
user_lockup_tx_id: None,
claim_tx_id: None,
refund_tx_id: None,
version: 0,
}
}
}
@@ -198,6 +199,7 @@ impl From<SendSyncData> for SendSwap {
state: PaymentState::Created,
lockup_tx_id: None,
refund_tx_id: None,
version: 0,
}
}
}
@@ -281,6 +283,7 @@ impl From<ReceiveSyncData> for ReceiveSwap {
claim_tx_id: None,
lockup_tx_id: None,
mrh_tx_id: None,
version: 0,
}
}
}