-
Notifications
You must be signed in to change notification settings - Fork 406
Check channel_announcement is on Bitcoin Mainnet or Testnet + test_invalid_channel_announcement #134
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
src/ln/router.rs
Outdated
@@ -624,6 +624,17 @@ impl Router { | |||
|
|||
Err(HandleError{err: "Failed to find a path to the given destination", action: None}) | |||
} | |||
|
|||
/// Drop entry from network map | |||
pub fn remove_channel_info(&self, short_channel_id: u64, chain_hash: Sha256dHash) -> Result<bool, HandleError> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implemented for the need of plumbing in test_invalid_channel_announcement but I think we're gonna to need it in future, specially if we follow BOLT 7 on "once its funding output has been spent OR reorganized out : SHOULD forget a channel", not implemented yet but I think we need to implement a ChainListener for Router for this one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why cant this be handled via HTLCFailChannelUpdate::ChannelClosed?
src/ln/channel.rs
Outdated
@@ -2000,6 +2000,16 @@ impl Channel { | |||
self.channel_value_satoshis | |||
} | |||
|
|||
#[cfg(test)] | |||
pub fn get_local_keys(&self) -> &ChannelKeys { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, I found this utilities useful if we want to test messages field by field without exposing field in API but maybe we don't want a proliferation of these ones..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think its fine for test-only for now, the need should go away once we have a more robust solution for #81 (ie where users get to specify how to generate the keys, meaning a ChannelManager-driver can easily re-derive the same keys). Maybe leave a TODO to that effect?
@@ -3239,4 +3240,90 @@ mod tests { | |||
assert_eq!(channel_state.by_id.len(), 0); | |||
assert_eq!(channel_state.short_to_id.len(), 0); | |||
} | |||
|
|||
#[test] | |||
fn test_invalid_channel_announcement() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a little bit plumbing but I needed to separate msg content from its signatures to tweak fields freely so can't reuse create_announced_chan_between_nodes here
src/ln/router.rs
Outdated
if msg.contents.features.requires_unknown_bits() { | ||
return Err(HandleError{err: "Channel announcement required unknown feature flags", action: None}); | ||
} | ||
|
||
//TODO: Call blockchain thing to ask if the short_channel_id is valid |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try to get this one done as described in the rfc at first but I think we need rust-blockchain-store API before. We're gonna need to access to UTXO set, built with rust-blockchain-store.
src/ln/channel.rs
Outdated
|
||
#[cfg(test)] | ||
pub fn get_secp_ctx(&self) -> &Secp256k1<secp256k1::All> { | ||
&self.secp_ctx |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If its just for testing why not just create a new context?
src/ln/msgs.rs
Outdated
@@ -120,6 +120,13 @@ impl GlobalFeatures { | |||
} | |||
} | |||
|
|||
#[cfg(test)] | |||
pub fn dummy_new(v: Vec<u8>) -> GlobalFeatures { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe new_with_flags or something?
src/ln/router.rs
Outdated
if msg.contents.features.requires_unknown_bits() { | ||
return Err(HandleError{err: "Channel announcement required unknown feature flags", action: None}); | ||
} | ||
|
||
//TODO: Call blockchain thing to ask if the short_channel_id is valid | ||
if msg.contents.chain_hash != genesis_block(Network::Bitcoin).header.bitcoin_hash() && msg.contents.chain_hash != genesis_block(Network::Testnet).header.bitcoin_hash() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should probably let the client specify which network we're working on, maybe via ChainInterface or just as an arg like in ChannelManager.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add ChainWatchInterface in Router to get access to network config.
src/ln/channel.rs
Outdated
@@ -2000,6 +2000,16 @@ impl Channel { | |||
self.channel_value_satoshis | |||
} | |||
|
|||
#[cfg(test)] | |||
pub fn get_local_keys(&self) -> &ChannelKeys { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think its fine for test-only for now, the need should go away once we have a more robust solution for #81 (ie where users get to specify how to generate the keys, meaning a ChannelManager-driver can easily re-derive the same keys). Maybe leave a TODO to that effect?
src/ln/router.rs
Outdated
@@ -624,6 +624,17 @@ impl Router { | |||
|
|||
Err(HandleError{err: "Failed to find a path to the given destination", action: None}) | |||
} | |||
|
|||
/// Drop entry from network map | |||
pub fn remove_channel_info(&self, short_channel_id: u64, chain_hash: Sha256dHash) -> Result<bool, HandleError> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why cant this be handled via HTLCFailChannelUpdate::ChannelClosed?
updated at 103d62d without effectively useless remove_channel_info stuff |
19cc555
to
19e02c4
Compare
src/chain/chaininterface.rs
Outdated
@@ -24,6 +25,9 @@ pub trait ChainWatchInterface: Sync + Send { | |||
|
|||
fn register_listener(&self, listener: Weak<ChainListener>); | |||
//TODO: unregister | |||
|
|||
/// Gets the chain currently watched | |||
fn get_network(&self) -> Network; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually while you're at it, why not just impelement the other TODO and make this
fn get_chain_txo(genesis_hash, txid, output_index) -> Result<(Script, Value), enum { IDontImplementThat, ItsNotThere, DontKnowThatChain })>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm on it
9d7b961
to
f3c4e4a
Compare
src/chain/chaininterface.rs
Outdated
fn get_chain_txo(&self, genesis_hash: Sha256dHash, txid: Sha256dHash, output_index: u16) -> Result<(Script, u64), ChainError>; | ||
|
||
/// Gets if outpoint is among UTXO | ||
fn get_spendable_outpoint(&self, genesis_hash: Sha256dHash, txid: Sha256dHash, output_index: u16) -> Result<bool, ChainError>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure about the name, what is the quality of an outpoint in the set of UTXO?
src/chain/chaininterface.rs
Outdated
fn get_chain_txo(&self, genesis_hash: Sha256dHash, _txid: Sha256dHash, _output_index: u16) -> Result<(Script, u64), ChainError> { | ||
watched_chain!(self, genesis_hash); | ||
|
||
//TODO: self.BlockchainStore.get_txo(txid, output_index) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add chain_store: Arc in ChainWatchInterface? Need to have a look on rust-blockchain-store
Hmm, I had a somewhat simpler API in mind - see https://github.com/TheBlueMatt/rust-lightning/commits/2018-08-134-proposed-changes |
src/chain/chaininterface.rs
Outdated
@@ -11,14 +11,12 @@ use std::sync::atomic::{AtomicUsize, Ordering}; | |||
|
|||
/// Used to give chain error details upstream | |||
pub enum ChainError { | |||
/// Chain isn't supported | |||
/// Client doesn't support UTXO lookup (but the chain hash matches our genesis block hash) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I think we can have cases where the chain hash is really unknown and don't match our genesis block hash. Or maybe we want to filter channel_MSG to router by chain downstream ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not entirely sure what you're suggesting here? If a client is eg an SPV client they may not want to support arbitrary UTXO lookup, but we still want to check the genesis block hash is correct before we handle the message, hence the distinction here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok got it!
rebased at 28d025a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. If you dont feel like refactoring the router_target I can do that post-merge. Either way please squash the fixup! commit and then looks good.
fuzz/fuzz_targets/router_target.rs
Outdated
@@ -107,9 +110,10 @@ pub fn do_test(data: &[u8]) { | |||
} | |||
|
|||
let logger: Arc<Logger> = Arc::new(test_logger::TestLogger{}); | |||
let chain_monitor = Arc::new(chaininterface::ChainWatchInterfaceUtil::new(Network::Bitcoin, Arc::clone(&logger))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, to keep the fuzzer from choking on the complication can you create a dummy chain watcher that reads from a byte from the input and just returns something based on that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've it written but can't pass InputData to chain_monitor due to lifetime conflicting requirements, hmmm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You have to do something like the InputData struct in full_stack_target, but should be able to do so without the Vec input copy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, fixup squash at 2d87bad
src/ln/channelmanager.rs
Outdated
dummy_unsigned_msg!(); | ||
unsigned_msg.chain_hash = genesis_block(Network::Bitcoin).header.bitcoin_hash(); | ||
sign_msg!(); | ||
match nodes[0].router.handle_channel_announcement(&chan_announcement) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can assert!(.....is_ok()).
src/ln/channelmanager.rs
Outdated
let mut unsigned_msg; | ||
let mut chan_announcement; | ||
|
||
macro_rules! dummy_unsigned_msg { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can just return an UnsignedChannelAnnouncement instead of assigning to a local variable? That could be a bit cleaner, no?
updated with comments at 86b8596 |
last commit doesn't compile, working on avoiding lifetime requirements without performance hit |
ChainWatchInterface to Router check on channel_announcement Needed for BOLT 7
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will take as #145 with these few nits fixed.
src/ln/channelmanager.rs
Outdated
let router = Router::new(PublicKey::from_secret_key(&secp_ctx, &node_id), Arc::clone(&logger)); | ||
nodes.push(Node { chain_monitor, tx_broadcaster, chan_monitor, node, router }); | ||
let router = Router::new(PublicKey::from_secret_key(&secp_ctx, &node_id), chain_monitor.clone(), Arc::clone(&logger)); | ||
nodes.push(Node { feeest, chain_monitor, tx_broadcaster, chan_monitor, node, router }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that you have a rebase error here - you re-add the feest to the Node obejct (making the first commit not compile), but then you remove it again in "Add test_invalid_channel_announcemnt + test utilities".
} | ||
|
||
fn get_chain_utxo(&self, _genesis_hash: Sha256dHash, _unspent_tx_output_identifier: u64) -> Result<(Script, u64), ChainError> { | ||
match self.input.get_slice(1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't generate full coverage of possible return values, best to expand the return set.
fuzz/fuzz_targets/router_target.rs
Outdated
@@ -110,7 +153,13 @@ pub fn do_test(data: &[u8]) { | |||
} | |||
|
|||
let logger: Arc<Logger> = Arc::new(test_logger::TestLogger{}); | |||
let chain_monitor = Arc::new(chaininterface::ChainWatchInterfaceUtil::new(Network::Bitcoin, Arc::clone(&logger))); | |||
let input = Arc::new(InputData { | |||
data: data.to_vec(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since you don't change the existing calls you end up using elements in data twice, potentially reducing coverage of get_chain_utxo even more.
Also remove_channel_info stuff