From 75fed63a3dfdc4522ea1a98b46893647b525d8d2 Mon Sep 17 00:00:00 2001 From: Lucas Soriano del Pino Date: Wed, 6 Mar 2024 20:42:51 +0100 Subject: [PATCH] feat(coordinator): Allow to run full sync via HTTP API --- coordinator/src/admin.rs | 18 +--------------- coordinator/src/routes.rs | 43 +++++++++++++++++++++++++++++++++++---- 2 files changed, 40 insertions(+), 21 deletions(-) diff --git a/coordinator/src/admin.rs b/coordinator/src/admin.rs index fd8de733b..6c86e6476 100644 --- a/coordinator/src/admin.rs +++ b/coordinator/src/admin.rs @@ -1,6 +1,7 @@ use crate::collaborative_revert; use crate::db; use crate::parse_dlc_channel_id; +use crate::routes::empty_string_as_none; use crate::routes::AppState; use crate::AppError; use anyhow::Context; @@ -22,14 +23,10 @@ use ln_dlc_node::node::NodeInfo; use rust_decimal::prelude::FromPrimitive; use rust_decimal::prelude::ToPrimitive; use rust_decimal::Decimal; -use serde::de; use serde::Deserialize; -use serde::Deserializer; use serde::Serialize; use std::cmp::Ordering; -use std::fmt; use std::num::NonZeroU32; -use std::str::FromStr; use std::sync::Arc; use time::OffsetDateTime; use tokio::task::spawn_blocking; @@ -370,19 +367,6 @@ pub struct CloseChannelParams { force: Option, } -fn empty_string_as_none<'de, D, T>(de: D) -> Result, D::Error> -where - D: Deserializer<'de>, - T: FromStr, - T::Err: fmt::Display, -{ - let opt = Option::::deserialize(de)?; - match opt.as_deref() { - None | Some("") => Ok(None), - Some(s) => FromStr::from_str(s).map_err(de::Error::custom).map(Some), - } -} - #[instrument(skip_all, err(Debug))] pub async fn close_channel( Path(channel_id_string): Path, diff --git a/coordinator/src/routes.rs b/coordinator/src/routes.rs index 27c5e109b..d828a0835 100644 --- a/coordinator/src/routes.rs +++ b/coordinator/src/routes.rs @@ -75,8 +75,11 @@ use ln_dlc_node::node::NodeInfo; use opentelemetry_prometheus::PrometheusExporter; use prometheus::Encoder; use prometheus::TextEncoder; +use serde::de; use serde::Deserialize; +use serde::Deserializer; use serde::Serialize; +use std::fmt; use std::net::SocketAddr; use std::str::FromStr; use std::sync::Arc; @@ -305,12 +308,31 @@ pub async fn rollover( Ok(()) } +#[derive(Debug, Deserialize)] +pub struct SyncParams { + #[serde(default, deserialize_with = "empty_string_as_none")] + full: Option, + #[serde(default, deserialize_with = "empty_string_as_none")] + gap: Option, +} + /// Internal API for syncing the on-chain wallet and the DLC channels. #[instrument(skip_all, err(Debug))] -pub async fn post_sync(State(state): State>) -> Result<(), AppError> { - state.node.inner.sync_on_chain_wallet().await.map_err(|e| { - AppError::InternalServerError(format!("Could not sync on-chain wallet: {e:#}")) - })?; +pub async fn post_sync( + State(state): State>, + Query(params): Query, +) -> Result<(), AppError> { + if params.full.unwrap_or(false) { + let stop_gap = params.gap.unwrap_or(20); + + state.node.inner.full_sync(stop_gap).await.map_err(|e| { + AppError::InternalServerError(format!("Could not full-sync on-chain wallet: {e:#}")) + })?; + } else { + state.node.inner.sync_on_chain_wallet().await.map_err(|e| { + AppError::InternalServerError(format!("Could not sync on-chain wallet: {e:#}")) + })?; + } spawn_blocking(move || { if let Err(e) = state.node.inner.dlc_manager.periodic_chain_monitor() { @@ -667,3 +689,16 @@ pub async fn get_leaderboard( entries: leader_board, })) } + +pub fn empty_string_as_none<'de, D, T>(de: D) -> Result, D::Error> +where + D: Deserializer<'de>, + T: FromStr, + T::Err: fmt::Display, +{ + let opt = Option::::deserialize(de)?; + match opt.as_deref() { + None | Some("") => Ok(None), + Some(s) => FromStr::from_str(s).map_err(de::Error::custom).map(Some), + } +}