Skip to content

Initial implementation of LDK Node - #11

Merged
tnull merged 1 commit into
lightningdevkit:mainfrom
tnull:2022-09-initial-setup-and-api
Mar 16, 2023
Merged

Initial implementation of LDK Node#11
tnull merged 1 commit into
lightningdevkit:mainfrom
tnull:2022-09-initial-setup-and-api

Conversation

@tnull

@tnulltnull commented Sep 1, 2022

Copy link
Copy Markdown
Collaborator

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
tnullforce-pushed the 2022-09-initial-setup-and-api branch 6 times, most recently from fe1e326 to 55966e7CompareSeptember 6, 2022 10:27
@tnull
tnullforce-pushed the 2022-09-initial-setup-and-api branch 7 times, most recently from fdabd21 to c0425ddCompareSeptember 8, 2022 12:30
@tnulltnull mentioned this pull request Sep 9, 2022
@tnull
tnullforce-pushed the 2022-09-initial-setup-and-api branch 6 times, most recently from 4c62cd8 to 9f7085dCompareSeptember 14, 2022 16:52
@tnull
tnullforce-pushed the 2022-09-initial-setup-and-api branch from 9f7085d to 37bf53bCompareSeptember 19, 2022 16:52
@tnull

Copy link
Copy Markdown
CollaboratorAuthor

Rebased on #9/#10.

@tnull
tnullforce-pushed the 2022-09-initial-setup-and-api branch from 37bf53b to 8d8955dCompareSeptember 22, 2022 13:53
@tnull
tnullforce-pushed the 2022-09-initial-setup-and-api branch 4 times, most recently from f52524e to 54a25b7CompareSeptember 30, 2022 08:25
@tnull
tnullforce-pushed the 2022-09-initial-setup-and-api branch 6 times, most recently from a68fa60 to 20f8f47CompareDecember 15, 2022 11:32
@tnull

Copy link
Copy Markdown
CollaboratorAuthor

Rebased after now using a custom KeysInterface.

@tnull
tnullforce-pushed the 2022-09-initial-setup-and-api branch 6 times, most recently from 3d770e0 to 36e59e4CompareDecember 19, 2022 10:57
@tnulltnull changed the title Initial implementation of LdkLiteInitial implementation of LDK NodeJan 4, 2023
Comment threadCargo.toml Outdated
Comment threadsrc/wallet.rs Outdated
@tnull

tnull commented Jan 27, 2023

Copy link
Copy Markdown
CollaboratorAuthor

Squashed fixup commits and rebased on main after merge of #33.

@jkczyzjkczyz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Only partway through.

Comment threadsrc/io_utils.rs Outdated
Comment threadsrc/lib.rs Outdated
Comment threadsrc/lib.rs Outdated
Comment threadsrc/lib.rs Outdated
Comment threadsrc/lib.rs
Comment threadsrc/lib.rs Outdated
Comment threadsrc/lib.rs Outdated
Comment threadsrc/lib.rs Outdated
Comment threadsrc/lib.rs Outdated
Comment threadsrc/lib.rs
Comment threadsrc/error.rs Outdated
Comment threadsrc/peer_store.rs Outdated
Comment threadsrc/peer_store.rs Outdated
Comment threadsrc/peer_store.rs Outdated
Comment threadsrc/lib.rs Outdated
Comment threadsrc/lib.rs Outdated
Comment threadsrc/lib.rs Outdated
Comment threadsrc/tests/functional_tests.rs Outdated
@tnulltnull mentioned this pull request Mar 13, 2023
47 tasks

@jkczyzjkczyz left a comment

Copy link
Copy Markdown
Contributor

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.

Comment threadsrc/peer_store.rs
Comment threadCargo.toml Outdated
Comment threadsrc/io_utils.rs
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
Copy Markdown
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
Copy Markdown
CollaboratorAuthor

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
Copy Markdown
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
Copy Markdown
CollaboratorAuthor

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

@tnulltnullMar 15, 2023

Copy link
Copy Markdown
CollaboratorAuthor

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.

Comment threadsrc/lib.rs
Comment threadsrc/lib.rs
Ok(())
}

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

Copy link
Copy Markdown
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.

@tnulltnullMar 14, 2023

Copy link
Copy Markdown
CollaboratorAuthor

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.

Comment threadsrc/lib.rs Outdated
Comment threadsrc/lib.rs Outdated
Comment threadsrc/lib.rs Outdated
Comment threadsrc/lib.rs

@jkczyzjkczyz left a comment

Copy link
Copy Markdown
Contributor

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.

Comment threadsrc/lib.rs Outdated
Comment threadsrc/lib.rs Outdated
Comment threadsrc/lib.rs Outdated
Comment threadsrc/lib.rs
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
Copy Markdown
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
Copy Markdown
CollaboratorAuthor

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 threadsrc/lib.rs
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
Copy Markdown
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
Copy Markdown
CollaboratorAuthor

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.

Comment threadsrc/lib.rs Outdated
Comment threadsrc/peer_store.rs
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
Copy Markdown
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
Copy Markdown
CollaboratorAuthor

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 threadsrc/peer_store.rs
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
Copy Markdown
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
Copy Markdown
CollaboratorAuthor

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.

Comment threadsrc/tests/functional_tests.rs Outdated
@tnulltnull mentioned this pull request Mar 16, 2023
Comment threadsrc/lib.rs Outdated
Comment threadsrc/tests/functional_tests.rs
@tnulltnull mentioned this pull request Mar 24, 2023
Sign up for freeto 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

@tnull@TheBlueMatt@jkczyz@MaxFangX