-
Notifications
You must be signed in to change notification settings - Fork 85
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
Initial implementation of LDK Node #11
Initial implementation of LDK Node #11
Conversation
fe1e326
to
55966e7
Compare
fdabd21
to
c0425dd
Compare
4c62cd8
to
9f7085d
Compare
9f7085d
to
37bf53b
Compare
37bf53b
to
8d8955d
Compare
f52524e
to
54a25b7
Compare
abce308
to
83e3325
Compare
b52e1fb
to
2e0ec29
Compare
6e14b5c
to
8314dbb
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.
Feel fee to squash fixups.
let ldk_data_dir = format!("{}/ldk", config.storage_dir_path); | ||
let network_graph_path = format!("{}/network_graph", ldk_data_dir); | ||
|
||
if let Ok(file) = fs::File::open(network_graph_path) { |
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.
What if we don't yet have a NetworkGraph
?
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 I'm understanding the question? In case we don't have a persisted network graph at the given location, the results won't be Ok
and hence we'll return an empty one via NetworkGraph::new
below?
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.
Ah, I missed that. Why do we need to use a Result
then?
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.
Good point, removed the Result
, will likely need to touch this anyways again when integrating RGS though.
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 this logic robust enough? For instance, if we get PermissionDenied
, we'll create a new NetworkGraph
and then presumably fail to write it later.
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, was thinking about this, too, but I'll have to rework all this anyways in the upcoming switch to SQLite and trait-based persistence remodel.
Currently all of this follows the assumption is just lying around somewhere on disk where we have access to it and we can read out-of-bounds it before we feed it into LDK. After the remodel all of these operations need to go through a trait-based interface that probably will extend KVStorePersister
(already implementing a KVStoreUnpersister
in #13), a KVStoreAccess
trait or similar is still missing.
Also, even asserting that we can open the file in write mode at this point doesn't ensure we won't fail persistence to it in the future, e.g., because permissions changed.
Ok(()) | ||
} | ||
|
||
/// Disconnects all peers, stops all running background tasks, and shuts down [`Node`]. |
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.
Perhaps specify if operations are no longer valid once called, to reflect the start
docs.
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.
Now included a corresponding note in the docs.
I'm however a bit split on the API design here for the exposed methods that don't require the runtime loaded. Previously all methods returned Error::NotRunning
when no runtime was loaded which gave a clear API-level distinction between started and stopped states. Currently I however opted to not do this for any methods that don't require the runtime, e.g., node_id()
or new_funding_address()
would work, whether the Node
is started or not.
On the one hand I think being able to access some of Node
's methods in a stopped state could come in handy (e.g., if users want to keep many nodes in a Vec
and could therefore query which node is which without the need to start them), on the other drawing a clear line could be beneficial too in order to avoid confusion, and it would allow us to change to some runtime-dependant behavior under the hood without breaking API going forward.
8314dbb
to
9fa0d70
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.
Feel free to punt on anything that requires a large change.
running, | ||
config, | ||
wallet, | ||
tx_sync, | ||
event_queue, | ||
channel_manager, | ||
chain_monitor, | ||
peer_manager, | ||
keys_manager, | ||
network_graph, | ||
gossip_sync, | ||
persister, | ||
logger, | ||
scorer, | ||
inbound_payments, | ||
outbound_payments, | ||
peer_store, | ||
} |
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.
Consider packing these on a few lines if rustfmt supports that. Probably worth doing in a follow-up later if it will result in a lot of churn.
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.
No, rustfmt doesn't allow manually changing this. I can experiment and see if any config knob allows to change this, but I doubt it, as this is one of the behaviors why Matt is NACK on introducing rustfmt it in LDK?
let _background_processor = BackgroundProcessor::start( | ||
Arc::clone(&self.persister), | ||
Arc::clone(&event_handler), | ||
Arc::clone(&self.chain_monitor), | ||
Arc::clone(&self.channel_manager), | ||
BPGossipSync::p2p(Arc::clone(&self.gossip_sync)), | ||
Arc::clone(&self.peer_manager), | ||
Arc::clone(&self.logger), | ||
Some(Arc::clone(&self.scorer)), | ||
); |
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 we use the async interface now?
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.
We can't unfortunately due to lightningdevkit/rust-lightning#2003. Will hopefully include a fix in 0.0.115.
pub(crate) fn add_peer(&self, peer_info: PeerInfo) -> Result<(), Error> { | ||
let mut locked_peers = self.peers.write().unwrap(); | ||
|
||
locked_peers.insert(peer_info.pubkey, peer_info); |
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 it intended to override an existing peer if present?
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, we may want to do that a bit more fine-grained if we'd ever add additional data, but currently we just override the whole struct to allow for address changes.
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), lightning::io::Error> { | ||
self.pubkey.write(writer)?; | ||
|
||
match self.address.ip() { | ||
IpAddr::V4(v4addr) => { | ||
0u8.write(writer)?; | ||
u32::from(v4addr).write(writer)?; | ||
} | ||
IpAddr::V6(v6addr) => { | ||
1u8.write(writer)?; | ||
u128::from(v6addr).write(writer)?; | ||
} | ||
} | ||
|
||
self.address.port().write(writer)?; | ||
|
||
Ok(()) | ||
} |
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 we use TLV encoding in case we add more fields?
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.
Generally yes, currently holding off since I still hope to simply be able to reuse NetAddress
here (cf. lightningdevkit/rust-lightning#2056). If said issue doesn't land I'll probably just newtype it and impl the FromStr
here.
72f9eb3
to
39d33f1
Compare
25f4106
to
f896eef
Compare
f896eef
to
3dee645
Compare
Based on
#8,#9,#10,#33.This PR wraps the previously mentioned PRs and provides initial implementations of
Node
,Builder
, as well as basic API methods.