use secp256k1::key::PublicKey;
use secp256k1::Signature;
use secp256k1;
-use bitcoin::util::hash::Sha256dHash;
+use bitcoin_hashes::sha256d::Hash as Sha256dHash;
use bitcoin::blockdata::script::Script;
use std::error::Error;
}
impl LocalFeatures {
- pub(crate) fn new() -> LocalFeatures {
+ /// Create a blank LocalFeatures flags (visibility extended for fuzz tests)
+ pub fn new() -> LocalFeatures {
LocalFeatures {
flags: Vec::new(),
}
}
pub(crate) fn requires_unknown_bits(&self) -> bool {
- for (idx, &byte) in self.flags.iter().enumerate() {
- if idx != 0 && (byte & 0x55) != 0 {
- return true;
- } else if idx == 0 && (byte & 0x14) != 0 {
- return true;
- }
- }
- return false;
+ self.flags.iter().enumerate().any(|(idx, &byte)| {
+ ( idx != 0 && (byte & 0x55) != 0 ) || ( idx == 0 && (byte & 0x14) != 0 )
+ })
}
pub(crate) fn supports_unknown_bits(&self) -> bool {
- for (idx, &byte) in self.flags.iter().enumerate() {
- if idx != 0 && byte != 0 {
- return true;
- } else if idx == 0 && (byte & 0xc4) != 0 {
- return true;
- }
- }
- return false;
+ self.flags.iter().enumerate().any(|(idx, &byte)| {
+ ( idx != 0 && byte != 0 ) || ( idx == 0 && (byte & 0xc4) != 0 )
+ })
}
}
pub trait ChannelMessageHandler : events::MessageSendEventsProvider + Send + Sync {
//Channel init:
/// Handle an incoming open_channel message from the given peer.
- fn handle_open_channel(&self, their_node_id: &PublicKey, msg: &OpenChannel) -> Result<(), HandleError>;
+ fn handle_open_channel(&self, their_node_id: &PublicKey, their_local_features: LocalFeatures, msg: &OpenChannel) -> Result<(), HandleError>;
/// Handle an incoming accept_channel message from the given peer.
- fn handle_accept_channel(&self, their_node_id: &PublicKey, msg: &AcceptChannel) -> Result<(), HandleError>;
+ fn handle_accept_channel(&self, their_node_id: &PublicKey, their_local_features: LocalFeatures, msg: &AcceptChannel) -> Result<(), HandleError>;
/// Handle an incoming funding_created message from the given peer.
fn handle_funding_created(&self, their_node_id: &PublicKey, msg: &FundingCreated) -> Result<(), HandleError>;
/// Handle an incoming funding_signed message from the given peer.
mod tests {
use hex;
use ln::msgs;
- use ln::msgs::{GlobalFeatures, OptionalField, OnionErrorPacket};
+ use ln::msgs::{GlobalFeatures, LocalFeatures, OptionalField, OnionErrorPacket};
use ln::channelmanager::{PaymentPreimage, PaymentHash};
use util::ser::Writeable;
- use bitcoin::util::hash::Sha256dHash;
+ use bitcoin_hashes::sha256d::Hash as Sha256dHash;
+ use bitcoin_hashes::hex::FromHex;
use bitcoin::util::address::Address;
use bitcoin::network::constants::Network;
use bitcoin::blockdata::script::Builder;
htlc_basepoint: pubkey_5,
first_per_commitment_point: pubkey_6,
channel_flags: if random_bit { 1 << 5 } else { 0 },
- shutdown_scriptpubkey: if shutdown { OptionalField::Present(Address::p2pkh(&pubkey_1, Network::Testnet).script_pubkey()) } else { OptionalField::Absent }
+ shutdown_scriptpubkey: if shutdown { OptionalField::Present(Address::p2pkh(&::bitcoin::PublicKey{compressed: true, key: pubkey_1}, Network::Testnet).script_pubkey()) } else { OptionalField::Absent }
};
let encoded_value = open_channel.encode();
let mut target_value = Vec::new();
delayed_payment_basepoint: pubkey_4,
htlc_basepoint: pubkey_5,
first_per_commitment_point: pubkey_6,
- shutdown_scriptpubkey: if shutdown { OptionalField::Present(Address::p2pkh(&pubkey_1, Network::Testnet).script_pubkey()) } else { OptionalField::Absent }
+ shutdown_scriptpubkey: if shutdown { OptionalField::Present(Address::p2pkh(&::bitcoin::PublicKey{compressed: true, key: pubkey_1}, Network::Testnet).script_pubkey()) } else { OptionalField::Absent }
};
let encoded_value = accept_channel.encode();
let mut target_value = hex::decode("020202020202020202020202020202020202020202020202020202020202020212345678901234562334032891223698321446687011447600083a840000034d000c89d4c0bcc0bc031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f024d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d076602531fe6068134503d2723133227c867ac8fa6c83c537e9a44c3c5bdbdcb1fe33703462779ad4aad39514614751a71085f2f10e1c7a593e4e030efb5b8721ce55b0b0362c0a046dacce86ddd0343c6d3c7c79c2208ba0d9c9cf24a6d046d21d21f90f703f006a18d5653c4edf5391ff23a61f03ff83d237e880ee61187fa9f379a028e0a").unwrap();
let script = Builder::new().push_opcode(opcodes::OP_TRUE).into_script();
let shutdown = msgs::Shutdown {
channel_id: [2; 32],
- scriptpubkey: if script_type == 1 { Address::p2pkh(&pubkey_1, Network::Testnet).script_pubkey() } else if script_type == 2 { Address::p2sh(&script, Network::Testnet).script_pubkey() } else if script_type == 3 { Address::p2wpkh(&pubkey_1, Network::Testnet).script_pubkey() } else { Address::p2wsh(&script, Network::Testnet).script_pubkey() },
+ scriptpubkey: if script_type == 1 { Address::p2pkh(&::bitcoin::PublicKey{compressed: true, key: pubkey_1}, Network::Testnet).script_pubkey() } else if script_type == 2 { Address::p2sh(&script, Network::Testnet).script_pubkey() } else if script_type == 3 { Address::p2wpkh(&::bitcoin::PublicKey{compressed: true, key: pubkey_1}, Network::Testnet).script_pubkey() } else { Address::p2wsh(&script, Network::Testnet).script_pubkey() },
};
let encoded_value = shutdown.encode();
let mut target_value = hex::decode("0202020202020202020202020202020202020202020202020202020202020202").unwrap();
let target_value = hex::decode("0202020202020202020202020202020202020202020202020202020202020202013413a7").unwrap();
assert_eq!(encoded_value, target_value);
}
+
+ fn do_encoding_init(unknown_global_bits: bool, initial_routing_sync: bool) {
+ let mut global = GlobalFeatures::new();
+ if unknown_global_bits {
+ global.flags = vec![0xFF, 0xFF];
+ }
+ let mut local = LocalFeatures::new();
+ if initial_routing_sync {
+ local.set_initial_routing_sync();
+ }
+ let init = msgs::Init {
+ global_features: global,
+ local_features: local,
+ };
+ let encoded_value = init.encode();
+ let mut target_value = Vec::new();
+ if unknown_global_bits {
+ target_value.append(&mut hex::decode("0002ffff").unwrap());
+ } else {
+ target_value.append(&mut hex::decode("0000").unwrap());
+ }
+ if initial_routing_sync {
+ target_value.append(&mut hex::decode("000108").unwrap());
+ } else {
+ target_value.append(&mut hex::decode("0000").unwrap());
+ }
+ assert_eq!(encoded_value, target_value);
+ }
+
+ #[test]
+ fn encoding_init() {
+ do_encoding_init(false, false);
+ do_encoding_init(true, false);
+ do_encoding_init(false, true);
+ do_encoding_init(true, true);
+ }
+
+ #[test]
+ fn encoding_error() {
+ let error = msgs::ErrorMessage {
+ channel_id: [2; 32],
+ data: String::from("rust-lightning"),
+ };
+ let encoded_value = error.encode();
+ let target_value = hex::decode("0202020202020202020202020202020202020202020202020202020202020202000e727573742d6c696768746e696e67").unwrap();
+ assert_eq!(encoded_value, target_value);
+ }
+
+ #[test]
+ fn encoding_ping() {
+ let ping = msgs::Ping {
+ ponglen: 64,
+ byteslen: 64
+ };
+ let encoded_value = ping.encode();
+ let target_value = hex::decode("0040004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap();
+ assert_eq!(encoded_value, target_value);
+ }
+
+ #[test]
+ fn encoding_pong() {
+ let pong = msgs::Pong {
+ byteslen: 64
+ };
+ let encoded_value = pong.encode();
+ let target_value = hex::decode("004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap();
+ assert_eq!(encoded_value, target_value);
+ }
}