Skip to content

Commit

Permalink
chore(emergency kit): Add option to rollback channel to last stable s…
Browse files Browse the repository at this point in the history
…tate
  • Loading branch information
holzeis committed Mar 4, 2024
1 parent 6a27e8e commit ed4a072
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 0 deletions.
44 changes: 44 additions & 0 deletions coordinator/src/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,50 @@ pub async fn delete_dlc_channel(
Ok(())
}

/// This function attempts to roll back a DLC channel to the last stable state!
/// The action is irreversible, only use if you know what you are doing!
#[instrument(skip_all, err(Debug))]
pub async fn roll_back_dlc_channel(
Path(channel_id_string): Path<String>,
State(state): State<Arc<AppState>>,
Query(params): Query<Confirmation>,
) -> Result<(), AppError> {
if !params.i_know_what_i_am_doing.unwrap_or_default() {
let error_message =
"Looks like you don't know what you are doing! Go and ask your supervisor for help!";
tracing::warn!(error_message);
return Err(AppError::BadRequest(error_message.to_string()));
}

let channel_id = parse_dlc_channel_id(&channel_id_string)
.map_err(|_| AppError::BadRequest("Provided channel ID was invalid".to_string()))?;

tracing::info!(channel_id = %channel_id_string, "Attempting to roll back dlc channel to last stable state");

let channel = state
.node
.inner
.get_dlc_channel_by_id(&channel_id)
.map_err(|e| AppError::BadRequest(format!("Couldn't find channel. {e:#}")))?;
if let Channel::Signed(signed_channel) = channel {
state
.node
.inner
.roll_back_channel(&signed_channel)
.map_err(|e| {
AppError::InternalServerError(format!("Failed to roll back channel. {e:#}"))
})?
} else {
return Err(AppError::BadRequest(
"It's only possible to rollback a channel in state signed".to_string(),
));
}

tracing::info!(channel_id = %channel_id_string, "Rolled back dlc channel");

Ok(())
}

#[instrument(skip_all, err(Debug))]
pub async fn sign_message(
Path(msg): Path<String>,
Expand Down
5 changes: 5 additions & 0 deletions coordinator/src/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::admin::is_connected;
use crate::admin::list_dlc_channels;
use crate::admin::list_on_chain_transactions;
use crate::admin::list_peers;
use crate::admin::roll_back_dlc_channel;
use crate::admin::sign_message;
use crate::backup::SledBackup;
use crate::campaign::post_push_campaign;
Expand Down Expand Up @@ -172,6 +173,10 @@ pub fn router(
"/api/admin/dlc_channels/:channel_id",
delete(delete_dlc_channel),
)
.route(
"/api/admin/dlc_channels/rollback/:channel_id",
post(roll_back_dlc_channel),
)
.route("/api/admin/transactions", get(list_on_chain_transactions))
.route("/api/admin/sign/:msg", get(sign_message))
.route("/api/admin/connect", post(connect_to_peer))
Expand Down
19 changes: 19 additions & 0 deletions mobile/lib/common/settings/emergency_kit_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,25 @@ class _EmergencyKitScreenState extends State<EmergencyKitScreen> {
goRouter.pop();
}),
const SizedBox(height: 30),
EmergencyKitButton(
icon: const Icon(FontAwesomeIcons.backwardStep),
title: "Rollback channel state",
onPressed: () async {
final messenger = ScaffoldMessenger.of(context);
final orderChangeNotifier = context.read<OrderChangeNotifier>();
final goRouter = GoRouter.of(context);

try {
await rust.api.rollBackChannelState();
await orderChangeNotifier.initialize();
showSnackBar(messenger, "Successfully rolled back channel state");
} catch (e) {
showSnackBar(messenger, "Failed to rollback channel state. Error: $e");
}

goRouter.pop();
}),
const SizedBox(height: 30),
Visibility(
visible: config.network == "regtest",
child: EmergencyKitButton(
Expand Down
7 changes: 7 additions & 0 deletions mobile/native/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -819,3 +819,10 @@ pub fn get_new_random_name() -> SyncReturn<String> {
pub async fn update_nickname(nickname: String) -> Result<()> {
users::update_username(nickname).await
}

pub fn roll_back_channel_state() -> Result<()> {
tracing::warn!(
"Executing emergency kit! Attempting to rollback channel state to last stable state"
);
ln_dlc::roll_back_channel_state()
}
11 changes: 11 additions & 0 deletions mobile/native/src/ln_dlc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1057,3 +1057,14 @@ fn confirmation_status_to_status_and_timestamp(

(status, timestamp.unix_timestamp() as u64)
}

pub fn roll_back_channel_state() -> Result<()> {
let node = state::get_node();

let counterparty_pubkey = config::get_coordinator_info().pubkey;
let signed_channel = node
.inner
.get_signed_channel_by_trader_id(counterparty_pubkey)?;

node.inner.roll_back_channel(&signed_channel)
}

0 comments on commit ed4a072

Please sign in to comment.