-
Notifications
You must be signed in to change notification settings - Fork 411
Impl Clone and PartialEq for ChannelMonitor #2331
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -284,7 +284,7 @@ impl HolderSignedTx { | |
|
||
/// We use this to track static counterparty commitment transaction data and to generate any | ||
/// justice or 2nd-stage preimage/timeout transactions. | ||
#[derive(PartialEq, Eq)] | ||
#[derive(Clone, PartialEq, Eq)] | ||
struct CounterpartyCommitmentParameters { | ||
counterparty_delayed_payment_base_key: PublicKey, | ||
counterparty_htlc_base_key: PublicKey, | ||
|
@@ -338,7 +338,7 @@ impl Readable for CounterpartyCommitmentParameters { | |
/// observed, as well as the transaction causing it. | ||
/// | ||
/// Used to determine when the on-chain event can be considered safe from a chain reorganization. | ||
#[derive(PartialEq, Eq)] | ||
#[derive(Clone, PartialEq, Eq)] | ||
struct OnchainEventEntry { | ||
txid: Txid, | ||
height: u32, | ||
|
@@ -381,7 +381,7 @@ type CommitmentTxCounterpartyOutputInfo = Option<(u32, u64)>; | |
|
||
/// Upon discovering of some classes of onchain tx by ChannelMonitor, we may have to take actions on it | ||
/// once they mature to enough confirmations (ANTI_REORG_DELAY) | ||
#[derive(PartialEq, Eq)] | ||
#[derive(Clone, PartialEq, Eq)] | ||
enum OnchainEvent { | ||
/// An outbound HTLC failing after a transaction is confirmed. Used | ||
/// * when an outbound HTLC output is spent by us after the HTLC timed out | ||
|
@@ -652,7 +652,7 @@ pub enum Balance { | |
} | ||
|
||
/// An HTLC which has been irrevocably resolved on-chain, and has reached ANTI_REORG_DELAY. | ||
#[derive(PartialEq, Eq)] | ||
#[derive(Clone, PartialEq, Eq)] | ||
struct IrrevocablyResolvedHTLC { | ||
commitment_tx_output_idx: Option<u32>, | ||
/// The txid of the transaction which resolved the HTLC, this may be a commitment (if the HTLC | ||
|
@@ -725,7 +725,14 @@ pub struct ChannelMonitor<Signer: WriteableEcdsaChannelSigner> { | |
inner: Mutex<ChannelMonitorImpl<Signer>>, | ||
} | ||
|
||
#[derive(PartialEq)] | ||
impl<Signer: WriteableEcdsaChannelSigner> Clone for ChannelMonitor<Signer> where Signer: Clone { | ||
fn clone(&self) -> Self { | ||
let inner = self.inner.lock().unwrap().clone(); | ||
ChannelMonitor { inner: Mutex::new(inner) } | ||
} | ||
} | ||
|
||
#[derive(Clone, PartialEq)] | ||
pub(crate) struct ChannelMonitorImpl<Signer: WriteableEcdsaChannelSigner> { | ||
latest_update_id: u64, | ||
commitment_transaction_number_obscure_factor: u64, | ||
|
@@ -879,6 +886,18 @@ impl<Signer: WriteableEcdsaChannelSigner> PartialEq for ChannelMonitor<Signer> w | |
} | ||
} | ||
|
||
impl<Signer: WriteableEcdsaChannelSigner> PartialOrd for ChannelMonitor<Signer> where Signer: PartialEq { | ||
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a super strange API to me - given Instead, we could have a specific method that has a name that makes clear what the behavior here is. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah I can see this being a bastardization of |
||
let inner = self.inner.lock().unwrap(); | ||
let other_inner = other.inner.lock().unwrap(); | ||
if inner.get_funding_txo() != other_inner.get_funding_txo() { | ||
return None; | ||
} | ||
|
||
inner.latest_update_id.partial_cmp(&other_inner.latest_update_id) | ||
} | ||
} | ||
|
||
impl<Signer: WriteableEcdsaChannelSigner> Writeable for ChannelMonitor<Signer> { | ||
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), Error> { | ||
self.inner.lock().unwrap().write(writer) | ||
|
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, what's the expected use-case here? I'm not convinced a full clone of each monitor in a HashMap is the right API - if a user wants to look up a monitor by the funding txo, they should use the existing
get_monitor
fn. If they're looking to serialize a copy of each monitor this will result in unnecessary clones and a hashmap just to iterate over it. Instead, we could either return animpl Iterator
or a vec of the funding outpoints?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's already a
list_monitors
that gives aVec<Outpoint>
andget_mointor(outpoint)
but these require doing a bunch of locks. this replaces so we can get them all in one lock. The idea for this is to be able to get all of our monitors so we can create a backup without having to iterate over each one ourself.Doing an iterator might be better than the hashmap 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.
Hmm, I think the repeated mutexes is probably faster than cloning the full set of monitors, at least if they're not contested :). Plus it avoids potential heap fragmentation. I'd definitely prefer an iterator.
Uh oh!
There was an error while loading. Please reload this page.
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 don't think this can be an iterator because of the RwLock, maybe I'm doing something wrong but always getting
returns a value referencing data owned by the current function
error that seems to only be solved by doing an allocationThere 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.
Mmm, right, we can't do a straight iterator, we can get the list of keys and build an iterator over those, but we'd have to do map lookups for each key as a part of the
next
iteration (or in some iterator deref, alaLockedChannelMonitor
, which could be adapted to hold a reference to theRwLockReadGuard
). Honestly given monitors are pretty big that may well be more efficient, at least for your use-case of just iterating them all and serializing them.