Skip to content

Commit 98e5c5e

Browse files
authored
Merge pull request #35 from TheBlueMatt/2018-06-post-32
Some cleanups after #32
2 parents b65aa86 + 844097e commit 98e5c5e

File tree

2 files changed

+126
-163
lines changed

2 files changed

+126
-163
lines changed

src/ln/chan_utils.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -140,15 +140,15 @@ impl TxCreationKeys {
140140
/// the revocation key
141141
pub fn get_revokeable_redeemscript(revocation_key: &PublicKey, to_self_delay: u16, delayed_payment_key: &PublicKey) -> Script {
142142
Builder::new().push_opcode(opcodes::All::OP_IF)
143-
.push_slice(&revocation_key.serialize())
144-
.push_opcode(opcodes::All::OP_ELSE)
145-
.push_int(to_self_delay as i64)
146-
.push_opcode(opcodes::OP_CSV)
147-
.push_opcode(opcodes::All::OP_DROP)
148-
.push_slice(&delayed_payment_key.serialize())
149-
.push_opcode(opcodes::All::OP_ENDIF)
150-
.push_opcode(opcodes::All::OP_CHECKSIG)
151-
.into_script()
143+
.push_slice(&revocation_key.serialize())
144+
.push_opcode(opcodes::All::OP_ELSE)
145+
.push_int(to_self_delay as i64)
146+
.push_opcode(opcodes::OP_CSV)
147+
.push_opcode(opcodes::All::OP_DROP)
148+
.push_slice(&delayed_payment_key.serialize())
149+
.push_opcode(opcodes::All::OP_ENDIF)
150+
.push_opcode(opcodes::All::OP_CHECKSIG)
151+
.into_script()
152152
}
153153

154154
#[derive(Clone)]

src/ln/channelmonitor.rs

Lines changed: 117 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -295,28 +295,36 @@ impl ChannelMonitor {
295295
}
296296
}
297297

298-
let mut waste_hash_state : Vec<[u8;32]> = Vec::new();
299-
{
300-
let local_signed_commitment_tx = &self.current_local_signed_commitment_tx;
301-
let remote_hash_commitment_number = &self.remote_hash_commitment_number;
298+
if !self.payment_preimages.is_empty() {
299+
let local_signed_commitment_tx = self.current_local_signed_commitment_tx.as_ref().expect("Channel needs at least an initial commitment tx !");
300+
let prev_local_signed_commitment_tx = self.prev_local_signed_commitment_tx.as_ref();
302301
let min_idx = self.get_min_seen_secret();
302+
let remote_hash_commitment_number = &mut self.remote_hash_commitment_number;
303+
303304
self.payment_preimages.retain(|&k, _| {
304-
for &(ref htlc, _s1, _s2) in &local_signed_commitment_tx.as_ref().expect("Channel needs at least an initial commitment tx !").htlc_outputs {
305+
for &(ref htlc, _, _) in &local_signed_commitment_tx.htlc_outputs {
306+
if k == htlc.payment_hash {
307+
return true
308+
}
309+
}
310+
if let Some(prev_local_commitment_tx) = prev_local_signed_commitment_tx {
311+
for &(ref htlc, _, _) in prev_local_commitment_tx.htlc_outputs.iter() {
305312
if k == htlc.payment_hash {
306313
return true
307314
}
308315
}
309-
if let Some(cn) = remote_hash_commitment_number.get(&k) {
310-
if *cn < min_idx {
311-
return true
312-
}
316+
}
317+
let contains = if let Some(cn) = remote_hash_commitment_number.get(&k) {
318+
if *cn < min_idx {
319+
return true
313320
}
314-
waste_hash_state.push(k);
315-
false
316-
});
317-
}
318-
for h in waste_hash_state {
319-
self.remote_hash_commitment_number.remove(&h);
321+
true
322+
} else { false };
323+
if contains {
324+
remote_hash_commitment_number.remove(&k);
325+
}
326+
false
327+
});
320328
}
321329

322330
Ok(())
@@ -830,15 +838,14 @@ impl ChannelMonitor {
830838
mod tests {
831839
use bitcoin::util::misc::hex_bytes;
832840
use bitcoin::blockdata::script::Script;
833-
use bitcoin::util::hash::{Hash160,Sha256dHash};
834841
use bitcoin::blockdata::transaction::Transaction;
842+
use crypto::digest::Digest;
835843
use ln::channelmonitor::ChannelMonitor;
836-
use ln::channelmonitor::LocalSignedTx;
837-
use ln::chan_utils::HTLCOutputInCommitment;
844+
use ln::chan_utils::{HTLCOutputInCommitment, TxCreationKeys};
845+
use util::sha2::Sha256;
838846
use secp256k1::key::{SecretKey,PublicKey};
839847
use secp256k1::{Secp256k1, Signature};
840848
use rand::{thread_rng,Rng};
841-
use std::collections::HashMap;
842849

843850
#[test]
844851
fn test_per_commitment_storage() {
@@ -1194,162 +1201,118 @@ mod tests {
11941201
}
11951202
}
11961203

1197-
macro_rules! gen_local_tx {
1198-
($hex : expr, $monitor : expr, $htlcs : expr, $rng : expr, $preimage : expr, $hash : expr) => {
1199-
{
1200-
1201-
let mut htlcs = Vec::new();
1202-
1203-
for _i in 0..$htlcs {
1204-
$rng.fill_bytes(&mut $preimage);
1205-
$hash[0..20].clone_from_slice(&Hash160::from_data(&$preimage)[0..20]);
1206-
$monitor.provide_payment_preimage(&$hash, &$preimage);
1207-
htlcs.push((HTLCOutputInCommitment {
1208-
offered : true,
1209-
amount_msat : 0,
1210-
cltv_expiry : 0,
1211-
payment_hash : $hash.clone(),
1212-
transaction_output_index : 0,
1213-
}, Signature::from_der(&Secp256k1::new(), $hex).unwrap(),
1214-
Signature::from_der(&Secp256k1::new(), $hex).unwrap()))
1215-
}
1204+
#[test]
1205+
fn test_prune_preimages() {
1206+
let secp_ctx = Secp256k1::new();
1207+
let dummy_sig = Signature::from_der(&secp_ctx, &hex_bytes("3045022100fa86fa9a36a8cd6a7bb8f06a541787d51371d067951a9461d5404de6b928782e02201c8b7c334c10aed8976a3a465be9a28abff4cb23acbf00022295b378ce1fa3cd").unwrap()[..]).unwrap();
12161208

1217-
Some(LocalSignedTx {
1218-
txid: Sha256dHash::from_data(&[]),
1219-
tx: Transaction {
1220-
version: 0,
1221-
lock_time: 0,
1222-
input: Vec::new(),
1223-
output: Vec::new(),
1224-
},
1209+
macro_rules! dummy_keys {
1210+
() => {
1211+
TxCreationKeys {
1212+
per_commitment_point: PublicKey::new(),
12251213
revocation_key: PublicKey::new(),
12261214
a_htlc_key: PublicKey::new(),
12271215
b_htlc_key: PublicKey::new(),
1228-
delayed_payment_key: PublicKey::new(),
1229-
feerate_per_kw: 0,
1230-
htlc_outputs: htlcs,
1231-
})
1216+
a_delayed_payment_key: PublicKey::new(),
1217+
b_payment_key: PublicKey::new(),
1218+
}
12321219
}
12331220
}
1234-
}
1221+
let dummy_tx = Transaction { version: 0, lock_time: 0, input: Vec::new(), output: Vec::new() };
12351222

1236-
macro_rules! gen_remote_outpoints {
1237-
($monitor : expr, $tx : expr, $htlcs : expr, $rng : expr, $preimage : expr, $hash: expr, $number : expr) => {
1238-
{
1239-
let mut commitment_number = $number;
1240-
1241-
for i in 0..$tx {
1242-
1243-
let tx_zero = Transaction {
1244-
version : 0,
1245-
lock_time : i,
1246-
input : Vec::new(),
1247-
output: Vec::new(),
1248-
};
1223+
let mut preimages = Vec::new();
1224+
{
1225+
let mut rng = thread_rng();
1226+
for _ in 0..20 {
1227+
let mut preimage = [0; 32];
1228+
rng.fill_bytes(&mut preimage);
1229+
let mut sha = Sha256::new();
1230+
sha.input(&preimage);
1231+
let mut hash = [0; 32];
1232+
sha.result(&mut hash);
1233+
preimages.push((preimage, hash));
1234+
}
1235+
}
12491236

1250-
let mut htlcs = Vec::new();
1251-
1252-
for _i in 0..$htlcs {
1253-
$rng.fill_bytes(&mut $preimage);
1254-
$hash[0..20].clone_from_slice(&Hash160::from_data(&$preimage)[0..20]);
1255-
$monitor.provide_payment_preimage(&$hash, &$preimage);
1256-
htlcs.push(HTLCOutputInCommitment {
1257-
offered : true,
1258-
amount_msat : 0,
1259-
cltv_expiry : 0,
1260-
payment_hash : $hash.clone(),
1261-
transaction_output_index : 0,
1237+
macro_rules! preimages_slice_to_htlc_outputs {
1238+
($preimages_slice: expr) => {
1239+
{
1240+
let mut res = Vec::new();
1241+
for (idx, preimage) in $preimages_slice.iter().enumerate() {
1242+
res.push(HTLCOutputInCommitment {
1243+
offered: true,
1244+
amount_msat: 0,
1245+
cltv_expiry: 0,
1246+
payment_hash: preimage.1.clone(),
1247+
transaction_output_index: idx as u32,
12621248
});
12631249
}
1264-
commitment_number -= 1;
1265-
$monitor.provide_latest_remote_commitment_tx_info(&tx_zero, htlcs, commitment_number);
1250+
res
12661251
}
12671252
}
12681253
}
1269-
}
1270-
1271-
#[test]
1272-
fn test_prune_preimages() {
1273-
1274-
let mut monitor: ChannelMonitor;
1275-
let mut secrets: Vec<[u8; 32]> = Vec::new();
1276-
let secp_ctx = Secp256k1::new();
1277-
let mut preimage: [u8;32] = [0;32];
1278-
let mut hash: [u8;32] = [0;32];
1279-
let mut rng = thread_rng();
1280-
1281-
{
1282-
// insert 30 random hash, 10 from local, 10 from remote, prune 30/50
1283-
monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
1284-
1285-
for _i in 0..30 {
1286-
rng.fill_bytes(&mut preimage);
1287-
hash[0..20].clone_from_slice(&Hash160::from_data(&preimage)[0..20]);
1288-
monitor.provide_payment_preimage(&hash, &preimage);
1254+
macro_rules! preimages_to_local_htlcs {
1255+
($preimages_slice: expr) => {
1256+
{
1257+
let mut inp = preimages_slice_to_htlc_outputs!($preimages_slice);
1258+
let res: Vec<_> = inp.drain(..).map(|e| { (e, dummy_sig.clone(), dummy_sig.clone()) }).collect();
1259+
res
1260+
}
12891261
}
1290-
monitor.current_local_signed_commitment_tx = gen_local_tx!(&hex_bytes("3045022100fa86fa9a36a8cd6a7bb8f06a541787d51371d067951a9461d5404de6b928782e02201c8b7c334c10aed8976a3a465be9a28abff4cb23acbf00022295b378ce1fa3cd").unwrap()[..], monitor, 10, rng, preimage, hash);
1291-
gen_remote_outpoints!(monitor, 1, 10, rng, preimage, hash, 281474976710654);
1292-
secrets.clear();
1293-
secrets.push([0; 32]);
1294-
secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc").unwrap());
1295-
monitor.provide_secret(281474976710655, secrets.last().unwrap().clone(), None);
1296-
assert_eq!(monitor.payment_preimages.len(), 20);
12971262
}
12981263

1299-
1300-
{
1301-
// insert 30 random hash, prune 30/30
1302-
monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
1303-
1304-
for _i in 0..30 {
1305-
rng.fill_bytes(&mut preimage);
1306-
hash[0..20].clone_from_slice(&Hash160::from_data(&preimage)[0..20]);
1307-
monitor.provide_payment_preimage(&hash, &preimage);
1264+
macro_rules! test_preimages_exist {
1265+
($preimages_slice: expr, $monitor: expr) => {
1266+
for preimage in $preimages_slice {
1267+
assert!($monitor.payment_preimages.contains_key(&preimage.1));
1268+
}
13081269
}
1309-
monitor.current_local_signed_commitment_tx = gen_local_tx!(&hex_bytes("3045022100fa86fa9a36a8cd6a7bb8f06a541787d51371d067951a9461d5404de6b928782e02201c8b7c334c10aed8976a3a465be9a28abff4cb23acbf00022295b378ce1fa3cd").unwrap()[..], monitor, 0, rng, preimage, hash);
1310-
gen_remote_outpoints!(monitor, 0, 0, rng, preimage, hash, 281474976710655);
1311-
secrets.clear();
1312-
secrets.push([0; 32]);
1313-
secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc").unwrap());
1314-
monitor.provide_secret(281474976710655, secrets.last().unwrap().clone(), None);
1315-
assert_eq!(monitor.payment_preimages.len(), 0);
13161270
}
13171271

1318-
{
1319-
// insert 30 random hash, 25 on 5 remotes, prune 30/55
1320-
monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
1321-
1322-
for _i in 0..30 {
1323-
rng.fill_bytes(&mut preimage);
1324-
hash[0..20].clone_from_slice(&Hash160::from_data(&preimage)[0..20]);
1325-
monitor.provide_payment_preimage(&hash, &preimage);
1326-
}
1327-
monitor.current_local_signed_commitment_tx = gen_local_tx!(&hex_bytes("3045022100fa86fa9a36a8cd6a7bb8f06a541787d51371d067951a9461d5404de6b928782e02201c8b7c334c10aed8976a3a465be9a28abff4cb23acbf00022295b378ce1fa3cd").unwrap()[..], monitor, 0, rng, preimage, hash);
1328-
gen_remote_outpoints!(monitor, 5, 5, rng, preimage, hash, 281474976710654);
1329-
secrets.clear();
1330-
secrets.push([0; 32]);
1331-
secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc").unwrap());
1332-
monitor.provide_secret(281474976710655, secrets.last().unwrap().clone(), None);
1333-
assert_eq!(monitor.payment_preimages.len(), 25);
1272+
// Prune with one old state and a local commitment tx holding a few overlaps with the
1273+
// old state.
1274+
let mut monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
1275+
monitor.set_their_to_self_delay(10);
1276+
1277+
monitor.provide_latest_local_commitment_tx_info(dummy_tx.clone(), dummy_keys!(), 0, preimages_to_local_htlcs!(preimages[0..10]));
1278+
monitor.provide_latest_remote_commitment_tx_info(&dummy_tx, preimages_slice_to_htlc_outputs!(preimages[5..15]), 281474976710655);
1279+
monitor.provide_latest_remote_commitment_tx_info(&dummy_tx, preimages_slice_to_htlc_outputs!(preimages[15..20]), 281474976710654);
1280+
monitor.provide_latest_remote_commitment_tx_info(&dummy_tx, preimages_slice_to_htlc_outputs!(preimages[17..20]), 281474976710653);
1281+
monitor.provide_latest_remote_commitment_tx_info(&dummy_tx, preimages_slice_to_htlc_outputs!(preimages[18..20]), 281474976710652);
1282+
for &(ref preimage, ref hash) in preimages.iter() {
1283+
monitor.provide_payment_preimage(hash, preimage);
13341284
}
13351285

1336-
{
1337-
// insert 30 random hash, 25 from local, prune 30/55
1338-
monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
1339-
1340-
for _i in 0..30 {
1341-
rng.fill_bytes(&mut preimage);
1342-
hash[0..20].clone_from_slice(&Hash160::from_data(&preimage)[0..20]);
1343-
monitor.provide_payment_preimage(&hash, &preimage);
1344-
}
1345-
monitor.current_local_signed_commitment_tx = gen_local_tx!(&hex_bytes("3045022100fa86fa9a36a8cd6a7bb8f06a541787d51371d067951a9461d5404de6b928782e02201c8b7c334c10aed8976a3a465be9a28abff4cb23acbf00022295b378ce1fa3cd").unwrap()[..], monitor, 25, rng, preimage, hash);
1346-
gen_remote_outpoints!(monitor, 0, 0, rng, preimage, hash, 281474976710655);
1347-
secrets.clear();
1348-
secrets.push([0; 32]);
1349-
secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc").unwrap());
1350-
monitor.provide_secret(281474976710655, secrets.last().unwrap().clone(), None);
1351-
assert_eq!(monitor.payment_preimages.len(), 25);
1352-
}
1286+
// Now provide a secret, pruning preimages 10-15
1287+
let mut secret = [0; 32];
1288+
secret[0..32].clone_from_slice(&hex_bytes("7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc").unwrap());
1289+
monitor.provide_secret(281474976710655, secret.clone(), None).unwrap();
1290+
assert_eq!(monitor.payment_preimages.len(), 15);
1291+
test_preimages_exist!(&preimages[0..10], monitor);
1292+
test_preimages_exist!(&preimages[15..20], monitor);
1293+
1294+
// Now provide a further secret, pruning preimages 15-17
1295+
secret[0..32].clone_from_slice(&hex_bytes("c7518c8ae4660ed02894df8976fa1a3659c1a8b4b5bec0c4b872abeba4cb8964").unwrap());
1296+
monitor.provide_secret(281474976710654, secret.clone(), None).unwrap();
1297+
assert_eq!(monitor.payment_preimages.len(), 13);
1298+
test_preimages_exist!(&preimages[0..10], monitor);
1299+
test_preimages_exist!(&preimages[17..20], monitor);
1300+
1301+
// Now update local commitment tx info, pruning only element 18 as we still care about the
1302+
// previous commitment tx's preimages too
1303+
monitor.provide_latest_local_commitment_tx_info(dummy_tx.clone(), dummy_keys!(), 0, preimages_to_local_htlcs!(preimages[0..5]));
1304+
secret[0..32].clone_from_slice(&hex_bytes("2273e227a5b7449b6e70f1fb4652864038b1cbf9cd7c043a7d6456b7fc275ad8").unwrap());
1305+
monitor.provide_secret(281474976710653, secret.clone(), None).unwrap();
1306+
assert_eq!(monitor.payment_preimages.len(), 12);
1307+
test_preimages_exist!(&preimages[0..10], monitor);
1308+
test_preimages_exist!(&preimages[18..20], monitor);
1309+
1310+
// But if we do it again, we'll prune 5-10
1311+
monitor.provide_latest_local_commitment_tx_info(dummy_tx.clone(), dummy_keys!(), 0, preimages_to_local_htlcs!(preimages[0..3]));
1312+
secret[0..32].clone_from_slice(&hex_bytes("27cddaa5624534cb6cb9d7da077cf2b22ab21e9b506fd4998a51d54502e99116").unwrap());
1313+
monitor.provide_secret(281474976710652, secret.clone(), None).unwrap();
1314+
assert_eq!(monitor.payment_preimages.len(), 5);
1315+
test_preimages_exist!(&preimages[0..5], monitor);
13531316
}
13541317

13551318
// Further testing is done in the ChannelManager integration tests.

0 commit comments

Comments
 (0)