Skip to content

Commit 7079d06

Browse files
committed
Test mock justice tx formation
1 parent a132fdc commit 7079d06

File tree

2 files changed

+64
-4
lines changed

2 files changed

+64
-4
lines changed

lightning/src/ln/functional_test_utils.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//! A bunch of useful utilities for building networks of nodes and exchanging messages between
1111
//! nodes for functional tests.
1212
13-
use crate::chain::{BestBlock, ChannelMonitorUpdateStatus, Confirm, Listen, Watch};
13+
use crate::chain::{BestBlock, ChannelMonitorUpdateStatus, Confirm, Listen, Watch, chainmonitor::Persist};
1414
use crate::sign::EntropySource;
1515
use crate::chain::channelmonitor::ChannelMonitor;
1616
use crate::chain::transaction::OutPoint;
@@ -2493,10 +2493,14 @@ pub fn create_chanmon_cfgs(node_count: usize) -> Vec<TestChanMonCfg> {
24932493
}
24942494

24952495
pub fn create_node_cfgs<'a>(node_count: usize, chanmon_cfgs: &'a Vec<TestChanMonCfg>) -> Vec<NodeCfg<'a>> {
2496+
create_node_cfgs_with_persisters(node_count, chanmon_cfgs, chanmon_cfgs.iter().map(|c| &c.persister).collect())
2497+
}
2498+
2499+
pub fn create_node_cfgs_with_persisters<'a>(node_count: usize, chanmon_cfgs: &'a Vec<TestChanMonCfg>, persisters: Vec<&'a impl Persist<EnforcingSigner>>) -> Vec<NodeCfg<'a>> {
24962500
let mut nodes = Vec::new();
24972501

24982502
for i in 0..node_count {
2499-
let chain_monitor = test_utils::TestChainMonitor::new(Some(&chanmon_cfgs[i].chain_source), &chanmon_cfgs[i].tx_broadcaster, &chanmon_cfgs[i].logger, &chanmon_cfgs[i].fee_estimator, &chanmon_cfgs[i].persister, &chanmon_cfgs[i].keys_manager);
2503+
let chain_monitor = test_utils::TestChainMonitor::new(Some(&chanmon_cfgs[i].chain_source), &chanmon_cfgs[i].tx_broadcaster, &chanmon_cfgs[i].logger, &chanmon_cfgs[i].fee_estimator, persisters[i], &chanmon_cfgs[i].keys_manager);
25002504
let network_graph = Arc::new(NetworkGraph::new(Network::Testnet, &chanmon_cfgs[i].logger));
25012505
let seed = [i as u8; 32];
25022506
nodes.push(NodeCfg {

lightning/src/ln/functional_tests.rs

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::chain::chaininterface::LowerBoundedFeeEstimator;
1717
use crate::chain::channelmonitor;
1818
use crate::chain::channelmonitor::{CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ANTI_REORG_DELAY};
1919
use crate::chain::transaction::OutPoint;
20-
use crate::sign::{ChannelSigner, EcdsaChannelSigner, EntropySource};
20+
use crate::sign::{ChannelSigner, EcdsaChannelSigner, EntropySource, SignerProvider};
2121
use crate::events::{Event, MessageSendEvent, MessageSendEventsProvider, PathFailure, PaymentPurpose, ClosureReason, HTLCDestination, PaymentFailureReason};
2222
use crate::ln::{PaymentPreimage, PaymentSecret, PaymentHash};
2323
use crate::ln::channel::{commitment_tx_base_weight, COMMITMENT_TX_WEIGHT_PER_HTLC, CONCURRENT_INBOUND_HTLC_FEE_BUFFER, FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE, MIN_AFFORDABLE_HTLC_COUNT};
@@ -31,7 +31,7 @@ use crate::ln::features::{ChannelFeatures, NodeFeatures};
3131
use crate::ln::msgs;
3232
use crate::ln::msgs::{ChannelMessageHandler, RoutingMessageHandler, ErrorAction};
3333
use crate::util::enforcing_trait_impls::EnforcingSigner;
34-
use crate::util::test_utils;
34+
use crate::util::test_utils::{self, WatchtowerPersister, WatchtowerState};
3535
use crate::util::errors::APIError;
3636
use crate::util::ser::{Writeable, ReadableArgs};
3737
use crate::util::string::UntrustedString;
@@ -2538,6 +2538,62 @@ fn revoked_output_claim() {
25382538
check_closed_event!(nodes[0], 1, ClosureReason::CommitmentTxConfirmed);
25392539
}
25402540

2541+
#[test]
2542+
fn test_forming_justice_tx_from_monitor_updates() {
2543+
// Simple test to make sure that the justice tx formed in WatchtowerPersister
2544+
// is properly formed and can be broadcasted/confirmed successfully in the event
2545+
// that a revoked commitment transaction is broadcasted
2546+
// (Similar to `revoked_output_claim` test but we get the justice tx + broadcast manually)
2547+
let chanmon_cfgs = create_chanmon_cfgs(2);
2548+
let persisters = vec![
2549+
WatchtowerPersister::new(chanmon_cfgs[0].keys_manager.get_destination_script().unwrap()),
2550+
WatchtowerPersister::new(chanmon_cfgs[1].keys_manager.get_destination_script().unwrap()),
2551+
];
2552+
let node_cfgs = create_node_cfgs_with_persisters(2, &chanmon_cfgs, persisters.iter().collect());
2553+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
2554+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
2555+
let (_, _, channel_id, funding_tx) = create_announced_chan_between_nodes(&nodes, 0, 1);
2556+
let funding_txo = OutPoint { txid: funding_tx.txid(), index: 0 };
2557+
// node[0] is gonna to revoke an old state thus node[1] should be able to claim the revoked output
2558+
let revoked_local_txn = get_local_commitment_txn!(nodes[0], channel_id);
2559+
assert_eq!(revoked_local_txn.len(), 1);
2560+
let starting_commitment_number = get_monitor!(nodes[0], channel_id).get_cur_holder_commitment_number();
2561+
// Only output is the full channel value back to nodes[0]:
2562+
assert_eq!(revoked_local_txn[0].output.len(), 1);
2563+
// Send a payment through, updating everyone's latest commitment txn
2564+
send_payment(&nodes[0], &vec!(&nodes[1])[..], 5_000_000);
2565+
2566+
let justice_tx = {
2567+
let state = persisters[1].channel_watchtower_state.lock().unwrap();
2568+
let tx = match state.get(&funding_txo).unwrap().get(&starting_commitment_number).unwrap() {
2569+
WatchtowerState::JusticeTxFormed(justice_tx) => justice_tx,
2570+
_ => panic!("Expected justice tx to be formed!"),
2571+
};
2572+
tx.clone()
2573+
};
2574+
check_spends!(justice_tx, revoked_local_txn[0]);
2575+
2576+
mine_transactions(&nodes[1], &[&revoked_local_txn[0], &justice_tx]);
2577+
mine_transactions(&nodes[0], &[&revoked_local_txn[0], &justice_tx]);
2578+
2579+
check_added_monitors!(nodes[1], 1);
2580+
check_closed_event!(nodes[1], 1, ClosureReason::CommitmentTxConfirmed);
2581+
get_announce_close_broadcast_events(&nodes, 1, 0);
2582+
2583+
check_added_monitors!(nodes[0], 1);
2584+
check_closed_event!(nodes[0], 1, ClosureReason::CommitmentTxConfirmed);
2585+
2586+
// Check that the justice tx has sent the revoked output value to nodes[1]
2587+
let monitor = get_monitor!(nodes[1], channel_id);
2588+
match monitor.get_claimable_balances()[0] {
2589+
channelmonitor::Balance::ClaimableAwaitingConfirmations { claimable_amount_satoshis, .. } => {
2590+
assert!(claimable_amount_satoshis >= 99_000);
2591+
},
2592+
_ => panic!("Unexpected balance type"),
2593+
}
2594+
}
2595+
2596+
25412597
#[test]
25422598
fn claim_htlc_outputs_shared_tx() {
25432599
// Node revoked old state, htlcs haven't time out yet, claim them in shared justice tx

0 commit comments

Comments
 (0)