use secp256k1;
use bitcoin::util::hash::Sha256dHash;
+use bitcoin::blockdata::script::Builder;
+use bitcoin::blockdata::opcodes;
use chain::chaininterface::{ChainError, ChainWatchInterface};
use ln::channelmanager;
}
fn handle_channel_announcement(&self, msg: &msgs::ChannelAnnouncement) -> Result<bool, HandleError> {
+ if msg.contents.node_id_1 == msg.contents.node_id_2 || msg.contents.bitcoin_key_1 == msg.contents.bitcoin_key_2 {
+ return Err(HandleError{err: "Channel announcement node had a channel with itself", action: Some(ErrorAction::IgnoreError)});
+ }
+
let msg_hash = Message::from_slice(&Sha256dHash::from_data(&msg.contents.encode()[..])[..]).unwrap();
secp_verify_sig!(self.secp_ctx, &msg_hash, &msg.node_signature_1, &msg.contents.node_id_1);
secp_verify_sig!(self.secp_ctx, &msg_hash, &msg.node_signature_2, &msg.contents.node_id_2);
match self.chain_monitor.get_chain_utxo(msg.contents.chain_hash, msg.contents.short_channel_id) {
Ok((script_pubkey, _value)) => {
- //TODO: Check if script_pubkey matches bitcoin_key_1 and bitcoin_key_2
+ let expected_script = Builder::new().push_opcode(opcodes::All::OP_PUSHNUM_2)
+ .push_slice(&msg.contents.bitcoin_key_1.serialize())
+ .push_slice(&msg.contents.bitcoin_key_2.serialize())
+ .push_opcode(opcodes::All::OP_PUSHNUM_2).push_opcode(opcodes::All::OP_CHECKMULTISIG).into_script().to_v0_p2wsh();
+ if script_pubkey != expected_script {
+ return Err(HandleError{err: "Channel announcement keys didn't match on-chain script", action: Some(ErrorAction::IgnoreError)});
+ }
+ //TODO: Check if value is worth storing, use it to inform routing, and compare it
+ //to the new HTLC max field in channel_update
},
Err(ChainError::NotSupported) => {
- // Tenatively accept, potentially exposing us to DoS attacks
+ // Tentatively accept, potentially exposing us to DoS attacks
},
Err(ChainError::NotWatched) => {
return Err(HandleError{err: "Channel announced on an unknown chain", action: Some(ErrorAction::IgnoreError)});