-
Notifications
You must be signed in to change notification settings - Fork 412
Add test_claim_on_remote_revoked_sizeable_push_msat #256
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4167,6 +4167,27 @@ mod tests { | |
nodes | ||
} | ||
|
||
macro_rules! display_txn { | ||
($txn: expr, $in: expr, $out: expr) => { | ||
println!("[{}]", stringify!($txn)); | ||
for (idx, tx) in $txn.iter().enumerate() { | ||
println!("tx[{}] : {} inputs {} outputs {}", idx, tx.txid(), tx.input.len(), tx.output.len()); | ||
if $in == true { | ||
for (idx, inp) in tx.input.iter().enumerate() { | ||
println!(" input[{}] : spending output {} from tx {} with witness size {}", idx, inp.previous_output.vout, inp.previous_output.txid, inp.witness.last().unwrap().len()); | ||
} | ||
} | ||
if $out == true { | ||
for (idx, out) in tx.output.iter().enumerate() { | ||
println!(" output[{}] : output encumbered by {} with amount {}", idx, out.script_pubkey, out.value); | ||
} | ||
} | ||
println!(""); | ||
} | ||
println!(""); | ||
} | ||
} | ||
|
||
#[test] | ||
fn test_async_inbound_update_fee() { | ||
let mut nodes = create_network(2); | ||
|
@@ -7588,8 +7609,8 @@ mod tests { | |
} else { panic!("Unexpected result"); } | ||
} | ||
|
||
macro_rules! check_dynamic_output_p2wsh { | ||
($node: expr) => { | ||
macro_rules! check_spendable_outputs { | ||
($node: expr, $der_idx: expr) => { | ||
{ | ||
let events = $node.chan_monitor.simple_monitor.get_and_clear_pending_events(); | ||
let mut txn = Vec::new(); | ||
|
@@ -7598,6 +7619,33 @@ mod tests { | |
Event::SpendableOutputs { ref outputs } => { | ||
for outp in outputs { | ||
match *outp { | ||
SpendableOutputDescriptor::DynamicOutputP2WPKH { ref outpoint, ref key, ref output } => { | ||
let input = TxIn { | ||
previous_output: outpoint.clone(), | ||
script_sig: Script::new(), | ||
sequence: 0, | ||
witness: Vec::new(), | ||
}; | ||
let outp = TxOut { | ||
script_pubkey: Builder::new().push_opcode(opcodes::All::OP_RETURN).into_script(), | ||
value: output.value, | ||
}; | ||
let mut spend_tx = Transaction { | ||
version: 2, | ||
lock_time: 0, | ||
input: vec![input], | ||
output: vec![outp], | ||
}; | ||
let secp_ctx = Secp256k1::new(); | ||
let remotepubkey = PublicKey::from_secret_key(&secp_ctx, &key); | ||
let witness_script = Address::p2pkh(&remotepubkey, Network::Testnet).script_pubkey(); | ||
let sighash = Message::from_slice(&bip143::SighashComponents::new(&spend_tx).sighash_all(&spend_tx.input[0], &witness_script, output.value)[..]).unwrap(); | ||
let remotesig = secp_ctx.sign(&sighash, key); | ||
spend_tx.input[0].witness.push(remotesig.serialize_der(&secp_ctx).to_vec()); | ||
spend_tx.input[0].witness[0].push(SigHashType::All as u8); | ||
spend_tx.input[0].witness.push(remotepubkey.serialize().to_vec()); | ||
txn.push(spend_tx); | ||
}, | ||
SpendableOutputDescriptor::DynamicOutputP2WSH { ref outpoint, ref key, ref witness_script, ref to_self_delay, ref output } => { | ||
let input = TxIn { | ||
previous_output: outpoint.clone(), | ||
|
@@ -7624,29 +7672,8 @@ mod tests { | |
spend_tx.input[0].witness.push(witness_script.clone().into_bytes()); | ||
txn.push(spend_tx); | ||
}, | ||
_ => panic!("Unexpected event"), | ||
} | ||
} | ||
}, | ||
_ => panic!("Unexpected event"), | ||
}; | ||
} | ||
txn | ||
} | ||
} | ||
} | ||
|
||
macro_rules! check_dynamic_output_p2wpkh { | ||
($node: expr) => { | ||
{ | ||
let events = $node.chan_monitor.simple_monitor.get_and_clear_pending_events(); | ||
let mut txn = Vec::new(); | ||
for event in events { | ||
match event { | ||
Event::SpendableOutputs { ref outputs } => { | ||
for outp in outputs { | ||
match *outp { | ||
SpendableOutputDescriptor::DynamicOutputP2WPKH { ref outpoint, ref key, ref output } => { | ||
SpendableOutputDescriptor::StaticOutput { ref outpoint, ref output } => { | ||
let secp_ctx = Secp256k1::new(); | ||
let input = TxIn { | ||
previous_output: outpoint.clone(), | ||
script_sig: Script::new(), | ||
|
@@ -7661,19 +7688,28 @@ mod tests { | |
version: 2, | ||
lock_time: 0, | ||
input: vec![input], | ||
output: vec![outp], | ||
output: vec![outp.clone()], | ||
}; | ||
let secp_ctx = Secp256k1::new(); | ||
let remotepubkey = PublicKey::from_secret_key(&secp_ctx, &key); | ||
let witness_script = Address::p2pkh(&remotepubkey, Network::Testnet).script_pubkey(); | ||
let secret = { | ||
match ExtendedPrivKey::new_master(&secp_ctx, Network::Testnet, &$node.node_seed) { | ||
Ok(master_key) => { | ||
match master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx($der_idx)) { | ||
Ok(key) => key, | ||
Err(_) => panic!("Your RNG is busted"), | ||
} | ||
} | ||
Err(_) => panic!("Your rng is busted"), | ||
} | ||
}; | ||
let pubkey = ExtendedPubKey::from_private(&secp_ctx, &secret).public_key; | ||
let witness_script = Address::p2pkh(&pubkey, Network::Testnet).script_pubkey(); | ||
let sighash = Message::from_slice(&bip143::SighashComponents::new(&spend_tx).sighash_all(&spend_tx.input[0], &witness_script, output.value)[..]).unwrap(); | ||
let remotesig = secp_ctx.sign(&sighash, key); | ||
spend_tx.input[0].witness.push(remotesig.serialize_der(&secp_ctx).to_vec()); | ||
let sig = secp_ctx.sign(&sighash, &secret.secret_key); | ||
spend_tx.input[0].witness.push(sig.serialize_der(&secp_ctx).to_vec()); | ||
spend_tx.input[0].witness[0].push(SigHashType::All as u8); | ||
spend_tx.input[0].witness.push(remotepubkey.serialize().to_vec()); | ||
spend_tx.input[0].witness.push(pubkey.serialize().to_vec()); | ||
txn.push(spend_tx); | ||
}, | ||
_ => panic!("Unexpected event"), | ||
} | ||
} | ||
}, | ||
|
@@ -7685,57 +7721,6 @@ mod tests { | |
} | ||
} | ||
|
||
macro_rules! check_static_output { | ||
($event: expr, $node: expr, $event_idx: expr, $output_idx: expr, $der_idx: expr, $idx_node: expr) => { | ||
match $event[$event_idx] { | ||
Event::SpendableOutputs { ref outputs } => { | ||
match outputs[$output_idx] { | ||
SpendableOutputDescriptor::StaticOutput { ref outpoint, ref output } => { | ||
let secp_ctx = Secp256k1::new(); | ||
let input = TxIn { | ||
previous_output: outpoint.clone(), | ||
script_sig: Script::new(), | ||
sequence: 0, | ||
witness: Vec::new(), | ||
}; | ||
let outp = TxOut { | ||
script_pubkey: Builder::new().push_opcode(opcodes::All::OP_RETURN).into_script(), | ||
value: output.value, | ||
}; | ||
let mut spend_tx = Transaction { | ||
version: 2, | ||
lock_time: 0, | ||
input: vec![input], | ||
output: vec![outp.clone()], | ||
}; | ||
let secret = { | ||
match ExtendedPrivKey::new_master(&secp_ctx, Network::Testnet, &$node[$idx_node].node_seed) { | ||
Ok(master_key) => { | ||
match master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx($der_idx)) { | ||
Ok(key) => key, | ||
Err(_) => panic!("Your RNG is busted"), | ||
} | ||
} | ||
Err(_) => panic!("Your rng is busted"), | ||
} | ||
}; | ||
let pubkey = ExtendedPubKey::from_private(&secp_ctx, &secret).public_key; | ||
let witness_script = Address::p2pkh(&pubkey, Network::Testnet).script_pubkey(); | ||
let sighash = Message::from_slice(&bip143::SighashComponents::new(&spend_tx).sighash_all(&spend_tx.input[0], &witness_script, output.value)[..]).unwrap(); | ||
let sig = secp_ctx.sign(&sighash, &secret.secret_key); | ||
spend_tx.input[0].witness.push(sig.serialize_der(&secp_ctx).to_vec()); | ||
spend_tx.input[0].witness[0].push(SigHashType::All as u8); | ||
spend_tx.input[0].witness.push(pubkey.serialize().to_vec()); | ||
spend_tx | ||
}, | ||
_ => panic!("Unexpected event !"), | ||
} | ||
}, | ||
_ => panic!("Unexpected event !"), | ||
}; | ||
} | ||
} | ||
|
||
#[test] | ||
fn test_claim_sizeable_push_msat() { | ||
// Incidentally test SpendableOutput event generation due to detection of to_local output on commitment tx | ||
|
@@ -7755,14 +7740,14 @@ mod tests { | |
|
||
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; | ||
nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![node_txn[0].clone()] }, 0); | ||
let spend_txn = check_dynamic_output_p2wsh!(nodes[1]); | ||
let spend_txn = check_spendable_outputs!(nodes[1], 1); | ||
assert_eq!(spend_txn.len(), 1); | ||
check_spends!(spend_txn[0], node_txn[0].clone()); | ||
} | ||
|
||
#[test] | ||
fn test_claim_on_remote_sizeable_push_msat() { | ||
// Same test as precedent, just test on remote commitment tx, as per_commitment_point registration changes following you're funder/fundee and | ||
// Same test as previous, just test on remote commitment tx, as per_commitment_point registration changes following you're funder/fundee and | ||
// to_remote output is encumbered by a P2WPKH | ||
|
||
let nodes = create_network(2); | ||
|
@@ -7786,12 +7771,42 @@ mod tests { | |
MessageSendEvent::BroadcastChannelUpdate { .. } => {}, | ||
_ => panic!("Unexpected event"), | ||
} | ||
let spend_txn = check_dynamic_output_p2wpkh!(nodes[1]); | ||
let spend_txn = check_spendable_outputs!(nodes[1], 1); | ||
assert_eq!(spend_txn.len(), 2); | ||
assert_eq!(spend_txn[0], spend_txn[1]); | ||
check_spends!(spend_txn[0], node_txn[0].clone()); | ||
} | ||
|
||
#[test] | ||
fn test_claim_on_remote_revoked_sizeable_push_msat() { | ||
// Same test as previous, just test on remote revoked commitment tx, as per_commitment_point registration changes following you're funder/fundee and | ||
// to_remote output is encumbered by a P2WPKH | ||
|
||
let nodes = create_network(2); | ||
|
||
let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 59000000); | ||
let payment_preimage = route_payment(&nodes[0], &vec!(&nodes[1])[..], 3000000).0; | ||
let revoked_local_txn = nodes[0].node.channel_state.lock().unwrap().by_id.get(&chan.2).unwrap().last_local_commitment_txn.clone(); | ||
assert_eq!(revoked_local_txn[0].input.len(), 1); | ||
assert_eq!(revoked_local_txn[0].input[0].previous_output.txid, chan.3.txid()); | ||
|
||
claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage); | ||
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; | ||
nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1); | ||
let events = nodes[1].node.get_and_clear_pending_msg_events(); | ||
match events[0] { | ||
MessageSendEvent::BroadcastChannelUpdate { .. } => {}, | ||
_ => panic!("Unexpected event"), | ||
} | ||
let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); | ||
let spend_txn = check_spendable_outputs!(nodes[1], 1); | ||
assert_eq!(spend_txn.len(), 4); | ||
assert_eq!(spend_txn[0], spend_txn[2]); // to_remote output on revoked remote commitment_tx | ||
check_spends!(spend_txn[0], revoked_local_txn[0].clone()); | ||
assert_eq!(spend_txn[1], spend_txn[3]); // to_local output on local commitment tx | ||
check_spends!(spend_txn[1], node_txn[0].clone()); | ||
} | ||
|
||
#[test] | ||
fn test_static_spendable_outputs_preimage_tx() { | ||
let nodes = create_network(2); | ||
|
@@ -7827,9 +7842,10 @@ mod tests { | |
assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), 133); | ||
check_spends!(node_txn[1], chan_1.3.clone()); | ||
|
||
let events = nodes[1].chan_monitor.simple_monitor.get_and_clear_pending_events(); | ||
let spend_tx = check_static_output!(events, nodes, 0, 0, 1, 1); | ||
check_spends!(spend_tx, node_txn[0].clone()); | ||
let spend_txn = check_spendable_outputs!(nodes[1], 1); // , 0, 0, 1, 1); | ||
assert_eq!(spend_txn.len(), 2); | ||
assert_eq!(spend_txn[0], spend_txn[1]); | ||
check_spends!(spend_txn[0], node_txn[0].clone()); | ||
} | ||
|
||
#[test] | ||
|
@@ -7859,9 +7875,10 @@ mod tests { | |
assert_eq!(node_txn[0].input.len(), 2); | ||
check_spends!(node_txn[0], revoked_local_txn[0].clone()); | ||
|
||
let events = nodes[1].chan_monitor.simple_monitor.get_and_clear_pending_events(); | ||
let spend_tx = check_static_output!(events, nodes, 0, 0, 1, 1); | ||
check_spends!(spend_tx, node_txn[0].clone()); | ||
let spend_txn = check_spendable_outputs!(nodes[1], 1); | ||
assert_eq!(spend_txn.len(), 2); | ||
assert_eq!(spend_txn[0], spend_txn[1]); | ||
check_spends!(spend_txn[0], node_txn[0].clone()); | ||
} | ||
|
||
#[test] | ||
|
@@ -7905,10 +7922,12 @@ mod tests { | |
assert_eq!(node_txn[3].input.len(), 1); | ||
check_spends!(node_txn[3], revoked_htlc_txn[0].clone()); | ||
|
||
let events = nodes[1].chan_monitor.simple_monitor.get_and_clear_pending_events(); | ||
// Check B's ChannelMonitor was able to generate the right spendable output descriptor | ||
let spend_tx = check_static_output!(events, nodes, 1, 1, 1, 1); | ||
check_spends!(spend_tx, node_txn[3].clone()); | ||
let spend_txn = check_spendable_outputs!(nodes[1], 1); | ||
assert_eq!(spend_txn.len(), 3); | ||
assert_eq!(spend_txn[0], spend_txn[1]); | ||
check_spends!(spend_txn[0], node_txn[0].clone()); | ||
check_spends!(spend_txn[2], node_txn[3].clone()); | ||
} | ||
|
||
#[test] | ||
|
@@ -7953,10 +7972,13 @@ mod tests { | |
assert_eq!(node_txn[3].input.len(), 1); | ||
check_spends!(node_txn[3], revoked_htlc_txn[0].clone()); | ||
|
||
let events = nodes[0].chan_monitor.simple_monitor.get_and_clear_pending_events(); | ||
// Check A's ChannelMonitor was able to generate the right spendable output descriptor | ||
let spend_tx = check_static_output!(events, nodes, 1, 2, 1, 0); | ||
check_spends!(spend_tx, node_txn[3].clone()); | ||
let spend_txn = check_spendable_outputs!(nodes[0], 1); | ||
assert_eq!(spend_txn.len(), 5); | ||
assert_eq!(spend_txn[1], spend_txn[3]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you meant to assert spend_txn[0] == spend_txn[2] here, too. |
||
check_spends!(spend_txn[0], revoked_local_txn[0].clone()); // spending to_remote output from revoked local tx | ||
check_spends!(spend_txn[1], node_txn[2].clone()); // spending justice tx output from revoked local tx htlc received output | ||
check_spends!(spend_txn[4], node_txn[3].clone()); // spending justice tx output on htlc success tx | ||
} | ||
|
||
#[test] | ||
|
@@ -7991,7 +8013,7 @@ mod tests { | |
check_spends!(node_txn[0], local_txn[0].clone()); | ||
|
||
// Verify that B is able to spend its own HTLC-Success tx thanks to spendable output event given back by its ChannelMonitor | ||
let spend_txn = check_dynamic_output_p2wsh!(nodes[1]); | ||
let spend_txn = check_spendable_outputs!(nodes[1], 1); | ||
assert_eq!(spend_txn.len(), 1); | ||
check_spends!(spend_txn[0], node_txn[0].clone()); | ||
} | ||
|
@@ -8022,7 +8044,7 @@ mod tests { | |
check_spends!(node_txn[0], local_txn[0].clone()); | ||
|
||
// Verify that A is able to spend its own HTLC-Timeout tx thanks to spendable output event given back by its ChannelMonitor | ||
let spend_txn = check_dynamic_output_p2wsh!(nodes[0]); | ||
let spend_txn = check_spendable_outputs!(nodes[0], 1); | ||
assert_eq!(spend_txn.len(), 4); | ||
assert_eq!(spend_txn[0], spend_txn[2]); | ||
assert_eq!(spend_txn[1], spend_txn[3]); | ||
|
@@ -8041,13 +8063,13 @@ mod tests { | |
|
||
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; | ||
nodes[0].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![closing_tx.clone()] }, 1); | ||
let events = nodes[0].chan_monitor.simple_monitor.get_and_clear_pending_events(); | ||
let spend_tx = check_static_output!(events, nodes, 0, 0, 2, 0); | ||
check_spends!(spend_tx, closing_tx.clone()); | ||
let spend_txn = check_spendable_outputs!(nodes[0], 2); | ||
assert_eq!(spend_txn.len(), 1); | ||
check_spends!(spend_txn[0], closing_tx.clone()); | ||
|
||
nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![closing_tx.clone()] }, 1); | ||
let events = nodes[1].chan_monitor.simple_monitor.get_and_clear_pending_events(); | ||
let spend_tx = check_static_output!(events, nodes, 0, 0, 2, 1); | ||
check_spends!(spend_tx, closing_tx); | ||
let spend_txn = check_spendable_outputs!(nodes[1], 2); | ||
assert_eq!(spend_txn.len(), 1); | ||
check_spends!(spend_txn[0], closing_tx); | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, why bother adding this (it looks unused atm)? Can't we just "{:?}" the transaction itself, or did you write this and accidentally commit it?