-
Notifications
You must be signed in to change notification settings - Fork 407
Split out BroadcastInterface, ChainWatchInterface monitors re-enter f… #11
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
…rom called listeners
4569d1c
to
c58e2d6
Compare
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.
Few API comments that need a response, but generally seems fine-enough.
src/chain/bitcoincorerpcchain.rs
Outdated
impl BitcoinCoreRPCClientChain { | ||
pub fn new() -> BitcoinCoreRPCClientChain { | ||
BitcoinCoreRPCClientChain { | ||
util: ChainWatchInterfaceUtil::new(), | ||
} | ||
} | ||
|
||
pub fn block_connected(&self, block: &Block, height: u32) { |
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 kinda envisioned this would have some polling thread (or a function to hit to make it poll) pinging the RPC and then generate the events there, not expose a pub fn which lets users call block_connected?
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.
In case of SPV this is not polling, but an incoming headers message processed and will call this.
src/chain/chaininterface.rs
Outdated
/// that peers rejected the transaction. | ||
pub trait BroadcasterInterface: Sync + Send { | ||
/// Sends a transaction out to (hopefully) be mined | ||
fn broadcast_transaction(&self, tx: &Transaction) -> Result<(), Box<Error>>; |
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 sure if its useful to return a Result here - Bitcoin transaction broadcasting is always somewhat a "fire and see if anything happens" process. In other words, there is always a high chance of undetectable failure, so trying to return failure is a bit useless, or to put it another way, is there any useful handling you can do except to try again later (which should happen anyway?). Maybe I'm just being idealistic about it?
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.
There are immediate error conditions that would better be communicated back, such as no connection to any peer or all peers rejected the message. An Ok result surely does not mean any confirmation, but without it does not even make sense to wait if anything happens as it won't.
@@ -54,44 +60,79 @@ pub enum ConfirmationTarget { | |||
/// called from inside the library in response to ChainListener events, P2P events, or timer | |||
/// events). | |||
pub trait FeeEstimator: Sync + Send { | |||
fn get_est_sat_per_vbyte(&self, ConfirmationTarget) -> u64; | |||
fn get_est_sat_per_vbyte(&self, confirmation_target: ConfirmationTarget) -> u64; |
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.
nit: Does it matter?
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.
compiler complained that anonymous arguments are deprecated.
let res = Arc::new(SimpleManyChannelMonitor { | ||
monitors: Mutex::new(HashMap::new()), | ||
chain_monitor: chain_monitor, | ||
chain_monitor, |
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.
Oh, thats cool...learn a new syntax every day, I guess :p.
} | ||
|
||
pub fn watch_all_txn(&self) { //TODO: refcnt this? |
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 believe this TODO was intended to point out that we may want to refcount the watch_all, and have something like an unwatch_all, but then you'd need to have a count of how many times it was called? Anyway, probably worth getting rid of...
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.
there is also no unregister. Let see if it is sufficient.
src/chain/chaininterface.rs
Outdated
/// notify listener that a block was connected | ||
/// notification will repeat if notified listener register new listeners | ||
pub fn block_connected(&self, block: &Block, height: u32) { | ||
let mut watch = self.reentered.load(Ordering::Relaxed); |
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.
Is relaxed actually OK here? If you have multiple threads calling fetch_add(1) are you allowed to see reentered go backwards? I assume not, but I dont think the performance hit of something stricter matters?
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.
enters are not strictly counted, the requirement is only to notice that there was a re-entry.
src/chain/chaininterface.rs
Outdated
let mut matched = Vec::new(); | ||
let mut matched_index = Vec::new(); | ||
for (index, transaction) in block.txdata.iter().enumerate() { | ||
if self.does_match_tx(transaction) { |
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, you're taking a lock inside of the tight loop here, maybe worth pulling the code into this function and out of the helper so that you dont do so?
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.
yes it would make sense to pull in the helper code. I did not here to make review easier not changing helper if not strictly needed.
src/chain/chaininterface.rs
Outdated
@@ -113,7 +155,7 @@ impl ChainWatchInterfaceUtil { | |||
} | |||
|
|||
/// Checks if a given transaction matches the current filter | |||
pub fn does_match_tx(&self, tx: &Transaction) -> bool { | |||
fn does_match_tx(&self, tx: &Transaction) -> bool { |
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 skip this from being pub? If people use some compression-like block downloads (BIP 37, the neutrino stuff, some PIR scheme, whatever) then its probably still needed?
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.
yes, you are right. I make it pub again
src/chain/chaininterface.rs
Outdated
@@ -102,7 +143,8 @@ impl ChainWatchInterfaceUtil { | |||
} | |||
} | |||
|
|||
pub fn do_call_block_disconnected(&self, header: &BlockHeader) { | |||
/// call listeners for disconnected blocks if they are still around | |||
fn do_call_block_disconnected(&self, header: &BlockHeader) { |
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 make this non-pub?
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.
block_connected and block_disconnected meant to be called not these. I would probably inline them into those if I were not trying to make review easier.
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 just delete this function and move it into block_disconnected instead of having the stub?
src/chain/bitcoincorerpcchain.rs
Outdated
fn register_listener(&self, listener: Weak<ChainListener>) { | ||
self.util.register_listener(listener) | ||
} | ||
} | ||
|
||
impl BroadcasterInterface for BitcoinCoreRPCClientChain { | ||
fn broadcast_transaction(&self, tx: &Transaction) { |
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.
New unused warning - can you use _tx?
src/chain/chaininterface.rs
Outdated
self.do_call_block_disconnected(header); | ||
} | ||
|
||
/// call listeners for connected blocks if they are still around. public only because of tests |
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 this should be public generally, and should probably do the reentry check inside of itself here. ie move the let mut watch = self.reentered.load... to above the calls, and then load it again at the end, returning true/false if the user needs to call it again. That will simplify block_connected a bit, and also enable people who havent done the full-Block download to use the API easier. Then maybe rename it from do_call to block_connected_checked and block_connected something like block_connected_with_filtering.
src/chain/chaininterface.rs
Outdated
@@ -102,7 +143,8 @@ impl ChainWatchInterfaceUtil { | |||
} | |||
} | |||
|
|||
pub fn do_call_block_disconnected(&self, header: &BlockHeader) { | |||
/// call listeners for disconnected blocks if they are still around | |||
fn do_call_block_disconnected(&self, header: &BlockHeader) { |
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 just delete this function and move it into block_disconnected instead of having the stub?
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.
Also a few new unused import warnings.
src/chain/bitcoincorerpcchain.rs
Outdated
use bitcoin::blockdata::transaction::Transaction; | ||
use bitcoin::blockdata::script::Script; | ||
use bitcoin::blockdata::block::{Block, BlockHeader}; |
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.
Unused import.
src/chain/bitcoincorerpcchain.rs
Outdated
@@ -1,8 +1,10 @@ | |||
use std::error::Error; |
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.
Unused import.
src/chain/chaininterface.rs
Outdated
@@ -1,9 +1,10 @@ | |||
use bitcoin::blockdata::block::BlockHeader; | |||
use std::error::Error; |
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.
Unused import.
renamed do_call_block_connected to bloc_connected_checked inlined do_block_disconnected. removed unused imports.
@TheBlueMatt made the requested changes plus ignored IntelliJ files in .gitingnore |
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.
Thanks.
Squashed + Merged. |
# This is the 1st commit message: test utils: refactor fail_payment_along_route for mpp # This is the commit message #2: Add MppId field to HTLCSource as a way to correlate mpp payment paths # This is the commit message #3: Implement Readable/Writeable for HashSet To be used in upcoming commits for MPP ID storage # This is the commit message #4: Add MPP ID to pending_outbound_htlcs We'll use this to correlate MPP shards in upcoming commits # This is the commit message #5: Prevent duplicate PaymentSent events by removing all pending outbound payments associated with the same MPP payment after the preimage is received # This is the commit message #6: Add all_paths_failed field to PaymentFailed see field docs for details # This is the commit message #7: Drop writer size hinting/message vec preallocation In order to avoid significant malloc traffic, messages previously explicitly stated their serialized length allowing for Vec preallocation during the message serialization pipeline. This added some amount of complexity in the serialization code, but did avoid some realloc() calls. Instead, here, we drop all the complexity in favor of a fixed 2KiB buffer for all message serialization. This should not only be simpler with a similar reduction in realloc() traffic, but also may reduce heap fragmentation by allocating identically-sized buffers more often. # This is the commit message #8: [fuzz] Swap mode on most messages to account for TLV suffix # This is the commit message #9: Add forward-compat due serialization variants of HTLCFailureMsg Going forward, all lightning messages have a TLV stream suffix, allowing new fields to be added as needed. In the P2P protocol, messages have an explicit length, so there is no implied length in the TLV stream itself. HTLCFailureMsg enum variants have messages in them, but without a size prefix or any explicit end. Thus, if a HTLCFailureMsg is read as a part of a ChannelManager, with a TLV stream at the end, there is no way to differentiate between the end of the message and the next field(s) in the ChannelManager. Here we add two new variant values for HTLCFailureMsg variants in the read path, allowing us to switch to the new values if/when we add new TLV fields in UpdateFailHTLC or UpdateFailMalformedHTLC so that older versions can still read the new TLV fields. # This is the commit message #10: Convert most P2P msg serialization to a new macro with TLV suffixes The network serialization format for all messages was changed some time ago to include a TLV suffix for all messages, however we never bothered to implement it as there isn't a lot of use validating a TLV stream with nothing to do with it. However, messages are increasingly utilizing the TLV suffix feature, and there are some compatibility concerns with messages written as a part of other structs having their format changed (see previous commit). Thus, here we go ahead and convert most message serialization to a new macro which includes a TLV suffix after a series of fields, simplifying several serialization implementations in the process. # This is the commit message #11: Update docs to specify where process events is called
# This is the 1st commit message: Update fuzz README with latest instructions # This is the commit message #2: Allow multiple monitor_update_failed calls without requiring calls to channel_monitor_updated in between. Found by the fuzzer # This is the commit message #3: Move CounterpartyForwardingInfo from channel to channelmanager CounterpartyForwardingInfo is public (previously exposed with a `pub use`), and used inside of ChannelCounterparty in channelmanager.rs. However, it is defined in channel.rs, away from where it is used. This would be fine, except that the bindings generator is somewhat confused by this - it doesn't currently support interpreting `pub use` as a struct to expose, instead ignoring it. Fixes lightningdevkit/ldk-garbagecollected#44 # This is the commit message #4: test utils: refactor fail_payment_along_route for mpp # This is the commit message #5: Add MppId field to HTLCSource as a way to correlate mpp payment paths # This is the commit message #6: Implement Readable/Writeable for HashSet To be used in upcoming commits for MPP ID storage # This is the commit message #7: Add MPP ID to pending_outbound_htlcs We'll use this to correlate MPP shards in upcoming commits # This is the commit message #8: Prevent duplicate PaymentSent events by removing all pending outbound payments associated with the same MPP payment after the preimage is received # This is the commit message #9: Add all_paths_failed field to PaymentFailed see field docs for details # This is the commit message #10: Drop writer size hinting/message vec preallocation In order to avoid significant malloc traffic, messages previously explicitly stated their serialized length allowing for Vec preallocation during the message serialization pipeline. This added some amount of complexity in the serialization code, but did avoid some realloc() calls. Instead, here, we drop all the complexity in favor of a fixed 2KiB buffer for all message serialization. This should not only be simpler with a similar reduction in realloc() traffic, but also may reduce heap fragmentation by allocating identically-sized buffers more often. # This is the commit message #11: [fuzz] Swap mode on most messages to account for TLV suffix # This is the commit message #12: Add forward-compat due serialization variants of HTLCFailureMsg Going forward, all lightning messages have a TLV stream suffix, allowing new fields to be added as needed. In the P2P protocol, messages have an explicit length, so there is no implied length in the TLV stream itself. HTLCFailureMsg enum variants have messages in them, but without a size prefix or any explicit end. Thus, if a HTLCFailureMsg is read as a part of a ChannelManager, with a TLV stream at the end, there is no way to differentiate between the end of the message and the next field(s) in the ChannelManager. Here we add two new variant values for HTLCFailureMsg variants in the read path, allowing us to switch to the new values if/when we add new TLV fields in UpdateFailHTLC or UpdateFailMalformedHTLC so that older versions can still read the new TLV fields. # This is the commit message #13: Convert most P2P msg serialization to a new macro with TLV suffixes The network serialization format for all messages was changed some time ago to include a TLV suffix for all messages, however we never bothered to implement it as there isn't a lot of use validating a TLV stream with nothing to do with it. However, messages are increasingly utilizing the TLV suffix feature, and there are some compatibility concerns with messages written as a part of other structs having their format changed (see previous commit). Thus, here we go ahead and convert most message serialization to a new macro which includes a TLV suffix after a series of fields, simplifying several serialization implementations in the process. # This is the commit message #14: Update docs to specify where process events is called
Indicate whether a channel is public in `listchannels`
@TheBlueMatt