Skip to content

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

Closed
wants to merge 5 commits into from

Conversation

ariard
Copy link

@ariard ariard commented Aug 29, 2018

Also remove_channel_info stuff

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> {
Copy link
Author

@ariard ariard Aug 29, 2018

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.

Copy link
Collaborator

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?

@@ -2000,6 +2000,16 @@ impl Channel {
self.channel_value_satoshis
}

#[cfg(test)]
pub fn get_local_keys(&self) -> &ChannelKeys {
Copy link
Author

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..

Copy link
Collaborator

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() {
Copy link
Author

@ariard ariard Aug 29, 2018

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
Copy link
Author

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.


#[cfg(test)]
pub fn get_secp_ctx(&self) -> &Secp256k1<secp256k1::All> {
&self.secp_ctx
Copy link
Collaborator

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 {
Copy link
Collaborator

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() {
Copy link
Collaborator

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.

Copy link
Author

@ariard ariard Aug 29, 2018

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.

@@ -2000,6 +2000,16 @@ impl Channel {
self.channel_value_satoshis
}

#[cfg(test)]
pub fn get_local_keys(&self) -> &ChannelKeys {
Copy link
Collaborator

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> {
Copy link
Collaborator

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?

@ariard
Copy link
Author

ariard commented Aug 29, 2018

updated at 103d62d without effectively useless remove_channel_info stuff

@ariard ariard force-pushed the route_check branch 2 times, most recently from 19cc555 to 19e02c4 Compare August 29, 2018 23:37
@ariard
Copy link
Author

ariard commented Aug 29, 2018

updated at 19e02c4, delete few things to match with #136

@@ -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;
Copy link
Collaborator

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 })>

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm on it

@ariard ariard force-pushed the route_check branch 2 times, most recently from 9d7b961 to f3c4e4a Compare August 30, 2018 01:45
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>;
Copy link
Author

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?

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)
Copy link
Author

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

@TheBlueMatt
Copy link
Collaborator

Hmm, I had a somewhat simpler API in mind - see https://github.com/TheBlueMatt/rust-lightning/commits/2018-08-134-proposed-changes

@@ -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)
Copy link
Author

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 ?

Copy link
Collaborator

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.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok got it!

@ariard
Copy link
Author

ariard commented Aug 31, 2018

rebased at 28d025a

Copy link
Collaborator

@TheBlueMatt TheBlueMatt left a 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.

@@ -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)));
Copy link
Collaborator

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?

Copy link
Author

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

Copy link
Collaborator

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.

Copy link
Author

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

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) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can assert!(.....is_ok()).

let mut unsigned_msg;
let mut chan_announcement;

macro_rules! dummy_unsigned_msg {
Copy link
Collaborator

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?

@ariard
Copy link
Author

ariard commented Aug 31, 2018

updated with comments at 86b8596

@ariard
Copy link
Author

ariard commented Aug 31, 2018

last commit doesn't compile, working on avoiding lifetime requirements without performance hit

Antoine Riard and others added 3 commits August 31, 2018 23:40
Copy link
Collaborator

@TheBlueMatt TheBlueMatt left a 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.

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 });
Copy link
Collaborator

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) {
Copy link
Collaborator

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.

@@ -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(),
Copy link
Collaborator

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.

@TheBlueMatt TheBlueMatt closed this Sep 3, 2018
TheBlueMatt added a commit that referenced this pull request Sep 3, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants