use bitcoin::hash_types::{BlockHash, WPubkeyHash};
use lightning::chain;
+use lightning::chain::Confirm;
use lightning::chain::chainmonitor;
use lightning::chain::channelmonitor;
use lightning::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdateErr, MonitorEvent};
use lightning::chain::transaction::OutPoint;
use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator};
use lightning::chain::keysinterface::{KeysInterface, InMemorySigner};
-use lightning::ln::channelmanager::{ChainParameters, ChannelManager, PaymentHash, PaymentPreimage, PaymentSecret, PaymentSendFailure, ChannelManagerReadArgs};
+use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
+use lightning::ln::channelmanager::{BestBlock, ChainParameters, ChannelManager, PaymentSendFailure, ChannelManagerReadArgs};
use lightning::ln::features::{ChannelFeatures, InitFeatures, NodeFeatures};
use lightning::ln::msgs::{CommitmentUpdate, ChannelMessageHandler, DecodeError, ErrorAction, UpdateAddHTLC, Init};
use lightning::util::enforcing_trait_impls::{EnforcingSigner, INITIAL_REVOKED_COMMITMENT_NUMBER};
use utils::test_persister::TestPersister;
use bitcoin::secp256k1::key::{PublicKey,SecretKey};
+use bitcoin::secp256k1::recovery::RecoverableSignature;
use bitcoin::secp256k1::Secp256k1;
use std::mem;
disable_revocation_policy_check: false,
})
}
+
+ fn sign_invoice(&self, _invoice_preimage: Vec<u8>) -> Result<RecoverableSignature, ()> {
+ unreachable!()
+ }
}
impl KeyProvider {
type ChanMan = ChannelManager<EnforcingSigner, Arc<TestChainMonitor>, Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<FuzzEstimator>, Arc<dyn Logger>>;
+#[inline]
+fn get_payment_secret_hash(dest: &ChanMan, payment_id: &mut u8) -> Option<(PaymentSecret, PaymentHash)> {
+ let mut payment_hash;
+ for _ in 0..256 {
+ payment_hash = PaymentHash(Sha256::hash(&[*payment_id; 1]).into_inner());
+ if let Ok(payment_secret) = dest.create_inbound_payment_for_hash(payment_hash, None, 7200, 0) {
+ return Some((payment_secret, payment_hash));
+ }
+ *payment_id = payment_id.wrapping_add(1);
+ }
+ None
+}
+
#[inline]
fn send_payment(source: &ChanMan, dest: &ChanMan, dest_chan_id: u64, amt: u64, payment_id: &mut u8) -> bool {
- let payment_hash = Sha256::hash(&[*payment_id; 1]);
- *payment_id = payment_id.wrapping_add(1);
+ let (payment_secret, payment_hash) =
+ if let Some((secret, hash)) = get_payment_secret_hash(dest, payment_id) { (secret, hash) } else { return true; };
if let Err(err) = source.send_payment(&Route {
paths: vec![vec![RouteHop {
pubkey: dest.get_our_node_id(),
- node_features: NodeFeatures::empty(),
+ node_features: NodeFeatures::known(),
short_channel_id: dest_chan_id,
- channel_features: ChannelFeatures::empty(),
+ channel_features: ChannelFeatures::known(),
fee_msat: amt,
cltv_expiry_delta: 200,
}]],
- }, PaymentHash(payment_hash.into_inner()), &None) {
+ }, payment_hash, &Some(payment_secret)) {
check_payment_err(err);
false
} else { true }
}
#[inline]
fn send_hop_payment(source: &ChanMan, middle: &ChanMan, middle_chan_id: u64, dest: &ChanMan, dest_chan_id: u64, amt: u64, payment_id: &mut u8) -> bool {
- let payment_hash = Sha256::hash(&[*payment_id; 1]);
- *payment_id = payment_id.wrapping_add(1);
+ let (payment_secret, payment_hash) =
+ if let Some((secret, hash)) = get_payment_secret_hash(dest, payment_id) { (secret, hash) } else { return true; };
if let Err(err) = source.send_payment(&Route {
paths: vec![vec![RouteHop {
pubkey: middle.get_our_node_id(),
- node_features: NodeFeatures::empty(),
+ node_features: NodeFeatures::known(),
short_channel_id: middle_chan_id,
- channel_features: ChannelFeatures::empty(),
+ channel_features: ChannelFeatures::known(),
fee_msat: 50000,
cltv_expiry_delta: 100,
},RouteHop {
pubkey: dest.get_our_node_id(),
- node_features: NodeFeatures::empty(),
+ node_features: NodeFeatures::known(),
short_channel_id: dest_chan_id,
- channel_features: ChannelFeatures::empty(),
+ channel_features: ChannelFeatures::known(),
fee_msat: amt,
cltv_expiry_delta: 200,
}]],
- }, PaymentHash(payment_hash.into_inner()), &None) {
+ }, payment_hash, &Some(payment_secret)) {
check_payment_err(err);
false
} else { true }
let mut config = UserConfig::default();
config.channel_options.fee_proportional_millionths = 0;
config.channel_options.announced_channel = true;
- config.peer_channel_config_limits.min_dust_limit_satoshis = 0;
let network = Network::Bitcoin;
let params = ChainParameters {
network,
- latest_hash: genesis_block(network).block_hash(),
- latest_height: 0,
+ best_block: BestBlock::from_genesis(network),
};
(ChannelManager::new(fee_est.clone(), monitor.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config, params),
monitor, keys_manager)
let mut config = UserConfig::default();
config.channel_options.fee_proportional_millionths = 0;
config.channel_options.announced_channel = true;
- config.peer_channel_config_limits.min_dust_limit_satoshis = 0;
let mut monitors = HashMap::new();
let mut old_monitors = $old_monitors.latest_monitors.lock().unwrap();
value: *channel_value_satoshis, script_pubkey: output_script.clone(),
}]};
funding_output = OutPoint { txid: tx.txid(), index: 0 };
- $source.funding_transaction_generated(&temporary_channel_id, funding_output);
+ $source.funding_transaction_generated(&temporary_channel_id, tx.clone()).unwrap();
channel_txn.push(tx);
} else { panic!("Wrong event type"); }
}
};
$source.handle_funding_signed(&$dest.get_our_node_id(), &funding_signed);
- {
- let events = $source.get_and_clear_pending_events();
- assert_eq!(events.len(), 1);
- if let events::Event::FundingBroadcastSafe { .. } = events[0] {
- } else { panic!("Wrong event type"); }
- }
funding_output
} }
}
let chain_hash = genesis_block(Network::Bitcoin).block_hash();
let mut header = BlockHeader { version: 0x20000000, prev_blockhash: chain_hash, merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
let txdata: Vec<_> = channel_txn.iter().enumerate().map(|(i, tx)| (i + 1, tx)).collect();
- $node.transactions_confirmed(&header, 1, &txdata);
+ $node.transactions_confirmed(&header, &txdata, 1);
for _ in 2..100 {
header = BlockHeader { version: 0x20000000, prev_blockhash: header.block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
}
- $node.update_best_block(&header, 99);
+ $node.best_block_updated(&header, 99);
} }
}
}
loop {
- macro_rules! send_payment_with_secret {
- ($source: expr, $middle: expr, $dest: expr) => { {
- let payment_hash = Sha256::hash(&[payment_id; 1]);
- payment_id = payment_id.wrapping_add(1);
- let payment_secret = Sha256::hash(&[payment_id; 1]);
- payment_id = payment_id.wrapping_add(1);
- if let Err(err) = $source.send_payment(&Route {
- paths: vec![vec![RouteHop {
- pubkey: $middle.0.get_our_node_id(),
- node_features: NodeFeatures::empty(),
- short_channel_id: $middle.1,
- channel_features: ChannelFeatures::empty(),
- fee_msat: 50_000,
- cltv_expiry_delta: 100,
- },RouteHop {
- pubkey: $dest.0.get_our_node_id(),
- node_features: NodeFeatures::empty(),
- short_channel_id: $dest.1,
- channel_features: ChannelFeatures::empty(),
- fee_msat: 10_000_000,
- cltv_expiry_delta: 200,
- }],vec![RouteHop {
- pubkey: $middle.0.get_our_node_id(),
- node_features: NodeFeatures::empty(),
- short_channel_id: $middle.1,
- channel_features: ChannelFeatures::empty(),
- fee_msat: 50_000,
- cltv_expiry_delta: 100,
- },RouteHop {
- pubkey: $dest.0.get_our_node_id(),
- node_features: NodeFeatures::empty(),
- short_channel_id: $dest.1,
- channel_features: ChannelFeatures::empty(),
- fee_msat: 10_000_000,
- cltv_expiry_delta: 200,
- }]],
- }, PaymentHash(payment_hash.into_inner()), &Some(PaymentSecret(payment_secret.into_inner()))) {
- check_payment_err(err);
- }
- } }
- }
-
macro_rules! process_msg_events {
($node: expr, $corrupt_forward: expr) => { {
let events = if $node == 1 {
let had_events = !events.is_empty();
for event in events.drain(..) {
match event {
- events::Event::PaymentReceived { payment_hash, payment_secret, amt } => {
+ events::Event::PaymentReceived { payment_hash, .. } => {
if claim_set.insert(payment_hash.0) {
if $fail {
- assert!(nodes[$node].fail_htlc_backwards(&payment_hash, &payment_secret));
+ assert!(nodes[$node].fail_htlc_backwards(&payment_hash));
} else {
- assert!(nodes[$node].claim_funds(PaymentPreimage(payment_hash.0), &payment_secret, amt));
+ assert!(nodes[$node].claim_funds(PaymentPreimage(payment_hash.0)));
}
}
},
},
0x0e => {
if chan_a_disconnected {
- nodes[0].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::empty() });
- nodes[1].peer_connected(&nodes[0].get_our_node_id(), &Init { features: InitFeatures::empty() });
+ nodes[0].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::known() });
+ nodes[1].peer_connected(&nodes[0].get_our_node_id(), &Init { features: InitFeatures::known() });
chan_a_disconnected = false;
}
},
0x0f => {
if chan_b_disconnected {
- nodes[1].peer_connected(&nodes[2].get_our_node_id(), &Init { features: InitFeatures::empty() });
- nodes[2].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::empty() });
+ nodes[1].peer_connected(&nodes[2].get_our_node_id(), &Init { features: InitFeatures::known() });
+ nodes[2].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::known() });
chan_b_disconnected = false;
}
},
0x24 => { send_hop_payment(&nodes[0], &nodes[1], chan_a, &nodes[2], chan_b, 10_000_000, &mut payment_id); },
0x25 => { send_hop_payment(&nodes[2], &nodes[1], chan_b, &nodes[0], chan_a, 10_000_000, &mut payment_id); },
- 0x26 => { send_payment_with_secret!(nodes[0], (&nodes[1], chan_a), (&nodes[2], chan_b)); },
- 0x27 => { send_payment_with_secret!(nodes[2], (&nodes[1], chan_b), (&nodes[0], chan_a)); },
-
0x28 => { send_payment(&nodes[0], &nodes[1], chan_a, 1_000_000, &mut payment_id); },
0x29 => { send_payment(&nodes[1], &nodes[0], chan_a, 1_000_000, &mut payment_id); },
0x2a => { send_payment(&nodes[1], &nodes[2], chan_b, 1_000_000, &mut payment_id); },
// Next, make sure peers are all connected to each other
if chan_a_disconnected {
- nodes[0].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::empty() });
- nodes[1].peer_connected(&nodes[0].get_our_node_id(), &Init { features: InitFeatures::empty() });
+ nodes[0].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::known() });
+ nodes[1].peer_connected(&nodes[0].get_our_node_id(), &Init { features: InitFeatures::known() });
chan_a_disconnected = false;
}
if chan_b_disconnected {
- nodes[1].peer_connected(&nodes[2].get_our_node_id(), &Init { features: InitFeatures::empty() });
- nodes[2].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::empty() });
+ nodes[1].peer_connected(&nodes[2].get_our_node_id(), &Init { features: InitFeatures::known() });
+ nodes[2].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::known() });
chan_b_disconnected = false;
}