use util::{byte_utils, events, internal_traits, rng};
use util::sha2::Sha256;
use util::chacha20poly1305rfc::ChaCha20;
-use util::logger::{Logger, Record};
+use util::logger::Logger;
+use util::errors::APIError;
use crypto;
use crypto::mac::{Mac,MacResult};
/// may wish to avoid using 0 for user_id here.
/// If successful, will generate a SendOpenChannel event, so you should probably poll
/// PeerManager::process_events afterwards.
- pub fn create_channel(&self, their_network_key: PublicKey, channel_value_satoshis: u64, user_id: u64) -> Result<(), HandleError> {
+ /// Raises APIError::APIMisuseError when channel_value_satoshis > 2**24 or push_msat being greater than channel_value_satoshis * 1k
+ pub fn create_channel(&self, their_network_key: PublicKey, channel_value_satoshis: u64, push_msat: u64, user_id: u64) -> Result<(), APIError> {
let chan_keys = if cfg!(feature = "fuzztarget") {
ChannelKeys {
funding_key: SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(),
}
};
- let channel = Channel::new_outbound(&*self.fee_estimator, chan_keys, their_network_key, channel_value_satoshis, self.announce_channels_publicly, user_id, Arc::clone(&self.logger));
+ let channel = Channel::new_outbound(&*self.fee_estimator, chan_keys, their_network_key, channel_value_satoshis, push_msat, self.announce_channels_publicly, user_id, Arc::clone(&self.logger))?;
let res = channel.get_open_channel(self.genesis_hash.clone(), &*self.fee_estimator)?;
let mut channel_state = self.channel_state.lock().unwrap();
match channel_state.by_id.insert(channel.channel_id(), channel) {
/// Call this upon creation of a funding transaction for the given channel.
/// Panics if a funding transaction has already been provided for this channel.
+ /// May panic if the funding_txo is duplicative with some other channel (note that this should
+ /// be trivially prevented by using unique funding transaction keys per-channel).
pub fn funding_transaction_generated(&self, temporary_channel_id: &[u8; 32], funding_txo: OutPoint) {
macro_rules! add_pending_event {
});
let mut channel_state = self.channel_state.lock().unwrap();
- channel_state.by_id.insert(chan.channel_id(), chan);
+ match channel_state.by_id.entry(chan.channel_id()) {
+ hash_map::Entry::Occupied(_) => {
+ panic!("Generated duplicate funding txid?");
+ },
+ hash_map::Entry::Vacant(e) => {
+ e.insert(chan);
+ }
+ }
}
fn get_announcement_sigs(&self, chan: &Channel) -> Result<Option<msgs::AnnouncementSignatures>, HandleError> {
}
fn handle_funding_created(&self, their_node_id: &PublicKey, msg: &msgs::FundingCreated) -> Result<msgs::FundingSigned, HandleError> {
- //TODO: broke this - a node shouldn't be able to get their channel removed by sending a
- //funding_created a second time, or long after the first, or whatever (note this also
- //leaves the short_to_id map in a busted state.
let (chan, funding_msg, monitor_update) = {
let mut channel_state = self.channel_state.lock().unwrap();
- match channel_state.by_id.remove(&msg.temporary_channel_id) {
- Some(mut chan) => {
- if chan.get_their_node_id() != *their_node_id {
+ match channel_state.by_id.entry(msg.temporary_channel_id.clone()) {
+ hash_map::Entry::Occupied(mut chan) => {
+ if chan.get().get_their_node_id() != *their_node_id {
return Err(HandleError{err: "Got a message for a channel from the wrong node!", action: None})
}
- match chan.funding_created(msg) {
+ match chan.get_mut().funding_created(msg) {
Ok((funding_msg, monitor_update)) => {
- (chan, funding_msg, monitor_update)
+ (chan.remove(), funding_msg, monitor_update)
},
Err(e) => {
+ //TODO: Possibly remove the channel depending on e.action
return Err(e);
}
}
},
- None => return Err(HandleError{err: "Failed to find corresponding channel", action: None})
+ hash_map::Entry::Vacant(_) => return Err(HandleError{err: "Failed to find corresponding channel", action: None})
}
}; // Release channel lock for install_watch_outpoint call,
// note that this means if the remote end is misbehaving and sends a message for the same
unimplemented!();
}
let mut channel_state = self.channel_state.lock().unwrap();
- channel_state.by_id.insert(funding_msg.channel_id, chan);
+ match channel_state.by_id.entry(funding_msg.channel_id) {
+ hash_map::Entry::Occupied(_) => {
+ return Err(HandleError {
+ err: "Duplicate channel_id!",
+ action: Some(msgs::ErrorAction::SendErrorMessage { msg: msgs::ErrorMessage { channel_id: funding_msg.channel_id, data: "Already had channel with the new channel_id".to_owned() } })
+ });
+ },
+ hash_map::Entry::Vacant(e) => {
+ e.insert(chan);
+ }
+ }
Ok(funding_msg)
}
static mut CHAN_COUNT: u32 = 0;
fn create_chan_between_nodes(node_a: &Node, node_b: &Node) -> (msgs::ChannelAnnouncement, msgs::ChannelUpdate, msgs::ChannelUpdate, [u8; 32], Transaction) {
- node_a.node.create_channel(node_b.node.get_our_node_id(), 100000, 42).unwrap();
+ node_a.node.create_channel(node_b.node.get_our_node_id(), 100000, 10001, 42).unwrap();
let events_1 = node_a.node.get_and_clear_pending_events();
assert_eq!(events_1.len(), 1);