Skip to content

Commit

Permalink
Merge pull request #1169 from get10101/fix/invalid-commitment-tx-sign…
Browse files Browse the repository at this point in the history
…ature-from-peer

fix: Invalid commitment tx signature from peer after processing pending Accept or CloseAccept message
  • Loading branch information
holzeis authored Aug 28, 2023
2 parents c3aaedf + 5ec59d2 commit 9fa60e0
Show file tree
Hide file tree
Showing 3 changed files with 220 additions and 14 deletions.
14 changes: 7 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 7 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ resolver = "2"

[patch.crates-io]
# We should usually track the `feature/ln-dlc-channels[-10101]` branch
dlc-manager = { git = "https://github.com/p2pderivatives/rust-dlc", rev = "22b7052" }
dlc-messages = { git = "https://github.com/p2pderivatives/rust-dlc", rev = "22b7052" }
dlc = { git = "https://github.com/p2pderivatives/rust-dlc", rev = "22b7052" }
dlc-sled-storage-provider = { git = "https://github.com/p2pderivatives/rust-dlc", rev = "22b7052" }
p2pd-oracle-client = { git = "https://github.com/p2pderivatives/rust-dlc", rev = "22b7052" }
dlc-trie = { git = "https://github.com/p2pderivatives/rust-dlc", rev = "22b7052" }
simple-wallet = { git = "https://github.com/p2pderivatives/rust-dlc", rev = "22b7052" }
dlc-manager = { git = "https://github.com/p2pderivatives/rust-dlc", rev = "fe7cfa3d2de7d3414b21c1bbd58932d2d83191c5" }
dlc-messages = { git = "https://github.com/p2pderivatives/rust-dlc", rev = "fe7cfa3d2de7d3414b21c1bbd58932d2d83191c5" }
dlc = { git = "https://github.com/p2pderivatives/rust-dlc", rev = "fe7cfa3d2de7d3414b21c1bbd58932d2d83191c5" }
dlc-sled-storage-provider = { git = "https://github.com/p2pderivatives/rust-dlc", rev = "fe7cfa3d2de7d3414b21c1bbd58932d2d83191c5" }
p2pd-oracle-client = { git = "https://github.com/p2pderivatives/rust-dlc", rev = "fe7cfa3d2de7d3414b21c1bbd58932d2d83191c5" }
dlc-trie = { git = "https://github.com/p2pderivatives/rust-dlc", rev = "fe7cfa3d2de7d3414b21c1bbd58932d2d83191c5" }
simple-wallet = { git = "https://github.com/p2pderivatives/rust-dlc", rev = "fe7cfa3d2de7d3414b21c1bbd58932d2d83191c5" }

# We should usually track the `split-tx-experiment[-10101]` branch
lightning = { git = "https://github.com/p2pderivatives/rust-lightning/", rev = "420d961d" }
Expand Down
206 changes: 206 additions & 0 deletions crates/ln-dlc-node/src/tests/dlc/dlc_setup_with_reconnects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -470,3 +470,209 @@ async fn reconnecting_during_dlc_channel_setup_reversed() {
.await
.unwrap();
}

#[tokio::test(flavor = "multi_thread")]
#[ignore]
async fn can_lose_connection_before_processing_subchannel_accept() {
init_tracing();

// Arrange

let app_dlc_collateral = 25_000;
let coordinator_dlc_collateral = 50_000;

let app_ln_balance = app_dlc_collateral * 2;
let coordinator_ln_balance = coordinator_dlc_collateral * 2;

let fund_amount = (app_ln_balance + coordinator_ln_balance) * 2;

let (app, _running_app) = Node::start_test_app("app").unwrap();
let (coordinator, _running_coord) = Node::start_test_coordinator("coordinator").unwrap();

app.connect(coordinator.info).await.unwrap();

coordinator
.fund(Amount::from_sat(fund_amount))
.await
.unwrap();

coordinator
.open_private_channel(&app, coordinator_ln_balance, app_ln_balance)
.await
.unwrap();

tokio::time::sleep(Duration::from_secs(5)).await;

let oracle_pk = app.oracle_pk();
let contract_input =
dummy_contract_input(coordinator_dlc_collateral, app_dlc_collateral, oracle_pk);

let channel_details = coordinator
.channel_manager
.list_usable_channels()
.iter()
.find(|c| c.counterparty.node_id == app.info.pubkey)
.context("Could not find usable channel with peer")
.unwrap()
.clone();

coordinator
.propose_dlc_channel(channel_details.clone(), contract_input)
.await
.unwrap();

// Process the coordinator's `Offer`
let sub_channel = wait_until_dlc_channel_state(
Duration::from_secs(30),
&app,
coordinator.info.pubkey,
SubChannelStateName::Offered,
)
.await
.unwrap();

app.accept_dlc_channel_offer(&sub_channel.channel_id)
.unwrap();

// Give time to deliver the `Accept` message to the coordinator
tokio::time::sleep(Duration::from_secs(5)).await;

// Lose the connection, triggering the coordinator's rollback to the `Offered` state.
app.reconnect(coordinator.info).await.unwrap();

// Process the app's `Accept` and send `Confirm`
wait_until_dlc_channel_state(
Duration::from_secs(30),
&coordinator,
app.info.pubkey,
SubChannelStateName::Confirmed,
)
.await
.unwrap();

// Create `Accept` message from pending `ReAccept` Action
sub_channel_manager_periodic_check(app.sub_channel_manager.clone(), &app.dlc_message_handler)
.await
.unwrap();

// Process the app's `Accept` and send `Confirm`
wait_until_dlc_channel_state(
Duration::from_secs(30),
&coordinator,
app.info.pubkey,
SubChannelStateName::Confirmed,
)
.await
.unwrap();

// Process the coordinator's `Confirm` and send `Finalize`
wait_until_dlc_channel_state(
Duration::from_secs(30),
&app,
coordinator.info.pubkey,
SubChannelStateName::Finalized,
)
.await
.unwrap();

// Process the app's `Finalize` and send `Revoke`
wait_until_dlc_channel_state(
Duration::from_secs(30),
&coordinator,
app.info.pubkey,
SubChannelStateName::Signed,
)
.await
.unwrap();

// Process the coordinator's `Revoke`
wait_until_dlc_channel_state(
Duration::from_secs(30),
&app,
coordinator.info.pubkey,
SubChannelStateName::Signed,
)
.await
.unwrap();
}

#[tokio::test(flavor = "multi_thread")]
#[ignore]
async fn can_lose_connection_before_processing_subchannel_close_accept() {
init_tracing();
// Arrange

let app_dlc_collateral = 25_000;
let coordinator_dlc_collateral = 50_000;
let app_ln_balance = app_dlc_collateral * 2;
let coordinator_ln_balance = coordinator_dlc_collateral * 2;
let fund_amount = (app_ln_balance + coordinator_ln_balance) * 2;
let (app, _running_app) = Node::start_test_app("app").unwrap();
let (coordinator, _running_coord) = Node::start_test_coordinator("coordinator").unwrap();
app.connect(coordinator.info).await.unwrap();
coordinator
.fund(Amount::from_sat(fund_amount))
.await
.unwrap();
coordinator
.open_private_channel(&app, coordinator_ln_balance, app_ln_balance)
.await
.unwrap();
tokio::time::sleep(Duration::from_secs(5)).await;
create_dlc_channel(
&coordinator,
&app,
coordinator_dlc_collateral,
app_dlc_collateral,
)
.await
.unwrap();
let channel_details = coordinator
.channel_manager
.list_usable_channels()
.iter()
.find(|c| c.counterparty.node_id == app.info.pubkey)
.unwrap()
.clone();

coordinator
.propose_dlc_channel_collaborative_settlement(
channel_details.channel_id,
app_dlc_collateral / 2,
)
.await
.unwrap();

// Process `CloseOffer`
let sub_channel = wait_until_dlc_channel_state(
Duration::from_secs(30),
&app,
coordinator.info.pubkey,
SubChannelStateName::CloseOffered,
)
.await
.unwrap();
app.accept_dlc_channel_collaborative_settlement(&sub_channel.channel_id)
.unwrap();

// Give time to deliver the `CloseAccept` message to the coordinator
tokio::time::sleep(Duration::from_secs(5)).await;

// Lose the connection, triggering re-establishing the channel
app.reconnect(coordinator.info).await.unwrap();

// Create `CloseAccept` message from pending `ReCloseAccept` Action
sub_channel_manager_periodic_check(app.sub_channel_manager.clone(), &app.dlc_message_handler)
.await
.unwrap();

// Process `CloseAccept` and send `CloseConfirm`
wait_until_dlc_channel_state(
Duration::from_secs(30),
&coordinator,
app.info.pubkey,
SubChannelStateName::CloseConfirmed,
)
.await
.unwrap();
}

0 comments on commit 9fa60e0

Please sign in to comment.