Skip to content
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

Merged
merged 1 commit into from
Mar 16, 2023

Conversation

tnull
Copy link
Collaborator

@tnull tnull commented Sep 1, 2022

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.

@tnull tnull force-pushed the 2022-09-initial-setup-and-api branch 6 times, most recently from fe1e326 to 55966e7 Compare September 6, 2022 10:27
@tnull tnull force-pushed the 2022-09-initial-setup-and-api branch 7 times, most recently from fdabd21 to c0425dd Compare September 8, 2022 12:30
@tnull tnull force-pushed the 2022-09-initial-setup-and-api branch 6 times, most recently from 4c62cd8 to 9f7085d Compare September 14, 2022 16:52
@tnull tnull force-pushed the 2022-09-initial-setup-and-api branch from 9f7085d to 37bf53b Compare September 19, 2022 16:52
@tnull
Copy link
Collaborator Author

tnull commented Sep 19, 2022

Rebased on #9/#10.

@tnull tnull force-pushed the 2022-09-initial-setup-and-api branch from 37bf53b to 8d8955d Compare September 22, 2022 13:53
@tnull tnull force-pushed the 2022-09-initial-setup-and-api branch 4 times, most recently from f52524e to 54a25b7 Compare September 30, 2022 08:25
@tnull tnull force-pushed the 2022-09-initial-setup-and-api branch 2 times, most recently from abce308 to 83e3325 Compare March 6, 2023 09:41
src/error.rs Outdated Show resolved Hide resolved
src/peer_store.rs Outdated Show resolved Hide resolved
src/peer_store.rs Outdated Show resolved Hide resolved
src/peer_store.rs Outdated Show resolved Hide resolved
src/lib.rs Outdated Show resolved Hide resolved
src/lib.rs Outdated Show resolved Hide resolved
src/lib.rs Outdated Show resolved Hide resolved
src/tests/functional_tests.rs Outdated Show resolved Hide resolved
@tnull tnull force-pushed the 2022-09-initial-setup-and-api branch 7 times, most recently from b52e1fb to 2e0ec29 Compare March 10, 2023 11:29
@tnull tnull requested a review from jkczyz March 10, 2023 11:29
@tnull tnull force-pushed the 2022-09-initial-setup-and-api branch 2 times, most recently from 6e14b5c to 8314dbb Compare March 12, 2023 00:20
@tnull tnull mentioned this pull request Mar 13, 2023
47 tasks
@tnull tnull added this to the 0.1 milestone Mar 13, 2023
Copy link
Contributor

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

src/peer_store.rs Show resolved Hide resolved
Cargo.toml Outdated Show resolved Hide resolved
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) {
Copy link
Contributor

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?

Copy link
Collaborator Author

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?

Copy link
Contributor

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?

Copy link
Collaborator Author

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.

Copy link
Contributor

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.

Copy link
Collaborator Author

@tnull tnull Mar 15, 2023

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.

src/lib.rs Show resolved Hide resolved
Ok(())
}

/// Disconnects all peers, stops all running background tasks, and shuts down [`Node`].
Copy link
Contributor

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.

Copy link
Collaborator Author

@tnull tnull Mar 14, 2023

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.

src/lib.rs Outdated Show resolved Hide resolved
src/lib.rs Outdated Show resolved Hide resolved
src/lib.rs Outdated Show resolved Hide resolved
src/lib.rs Show resolved Hide resolved
@tnull tnull force-pushed the 2022-09-initial-setup-and-api branch from 8314dbb to 9fa0d70 Compare March 14, 2023 12:43
@tnull tnull requested a review from jkczyz March 14, 2023 13:38
Copy link
Contributor

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

src/lib.rs Outdated Show resolved Hide resolved
src/lib.rs Outdated Show resolved Hide resolved
src/lib.rs Outdated Show resolved Hide resolved
Comment on lines +414 to +472
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,
}
Copy link
Contributor

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.

Copy link
Collaborator Author

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?

Comment on lines +661 to +711
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)),
);
Copy link
Contributor

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?

Copy link
Collaborator Author

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.

src/lib.rs Outdated Show resolved Hide resolved
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);
Copy link
Contributor

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?

Copy link
Collaborator Author

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.

Comment on lines +136 to +153
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(())
}
Copy link
Contributor

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?

Copy link
Collaborator Author

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.

src/tests/functional_tests.rs Outdated Show resolved Hide resolved
@tnull tnull requested a review from jkczyz March 15, 2023 20:49
@tnull tnull force-pushed the 2022-09-initial-setup-and-api branch from 72f9eb3 to 39d33f1 Compare March 15, 2023 20:54
src/lib.rs Outdated Show resolved Hide resolved
src/tests/functional_tests.rs Show resolved Hide resolved
@tnull tnull force-pushed the 2022-09-initial-setup-and-api branch from 25f4106 to f896eef Compare March 16, 2023 17:41
@tnull tnull force-pushed the 2022-09-initial-setup-and-api branch from f896eef to 3dee645 Compare March 16, 2023 17:47
@tnull tnull merged commit 8bc5c40 into lightningdevkit:main Mar 16, 2023
@tnull tnull mentioned this pull request Mar 24, 2023
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.

4 participants