-
Notifications
You must be signed in to change notification settings - Fork 39
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
CLI Host, port, and token can be set at runtime #62
base: main
Are you sure you want to change the base?
Conversation
* Host, port, and token can be set at runtime * Default host has the protocol specified (http)
Getting closer! You shouldn't need (or require) the admin access token for accessing the individual node apis as those are completely authenticated by the macaroon. Happy to merge this since it's completely broken in main at the moment but I still think the better path forward is to probably write out the 'admin access token' to filesystem in It can try to read it from that path if it's not provided as a cli arg. Once the database work I'm doing lands I don't think there will even be these node directories anymore since there'll be a single database for all the nodes. Will probably make this simpler so maybe we don't take the cli too far until that lands. |
Yes! I was looking at segmenting off the AdminClient api calls (init, start, create_node, list_nodes, to “want” separate data). |
Ok, I've done a bit of restructuring, and thinking, and going to do a bit more restructuring - [ ] - The ListNodes command should list the nodes |
This turned into a bit of a mess. Sorry. I may re-do it once I have a better feel for what I'm actually trying to accomplish. I've discovered several error states I could put my system into, and trying to help them recover. Trying to add some instrumentation and such to help with debugging. Not sure that it's all totally appropriate in a "repair the CLI" bit of work, and almost certainly not worth doing if I'm just trying to get a few methods looking better. So probably worth making a decision about "smallest mergable/usable" piece of work and go from there. |
use crate::sensei::{ | ||
CloseChannelRequest, ConnectPeerRequest, CreateAdminRequest, CreateInvoiceRequest, | ||
CreateNodeRequest, GetUnusedAddressRequest, InfoRequest, KeysendRequest, ListChannelsRequest, | ||
ListNodesRequest, ListPaymentsRequest, ListPeersRequest, OpenChannelRequest, PayInvoiceRequest, | ||
SignMessageRequest, StartAdminRequest, StartNodeRequest, | ||
SignMessageRequest, StartAdminRequest, StartNodeRequest, PaginationRequest |
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.
This is needed (I think) in order to make the CLI actually be able to send paginated requests (which allows, the list of nodes to be more than 0 items long).
@@ -35,14 +39,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> { | |||
.version("1.0") | |||
.author("John Cantrell <[email protected]>") | |||
.about("Control your sensei node from a cli") | |||
.arg( |
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 removed all the CLI knowing about the node data directory.
@@ -51,6 +47,37 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> { | |||
.help("Sets the node to issue commands to") | |||
.takes_value(true), | |||
) | |||
.arg( | |||
Arg::new("token") |
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.
The token is now passed in on the CLI, along with host and port.
@@ -83,6 +110,13 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> { | |||
.required(true) | |||
.index(2) | |||
.help("alias to use for this lightning node"), | |||
) | |||
.arg( | |||
Arg::new("start") |
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.
This allows the create child node to pass the start value as well.
.connect() | ||
.await?; | ||
// This is only needed for a couple of queries. Disabling pagination effectively by large get | ||
let pagination = PaginationRequest { |
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 generally prefer pull request documentation/explanation for potentially surprising things, rather than comments, since comments tend to be lies waiting to happen, but put the explanatory comment there just in case. LMK if you'd like it out.
|
||
let message = response.into_inner(); | ||
|
||
let mut config = NodeConfig { |
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.
After we get the node created back from senseid, save that data to the local (to the CLI) filesystem for future use. I'm not exactly sure the best place to put this data_dir
and would appreciate some input.
} | ||
} | ||
|
||
// I could not figure out how to improt this from the database/admin |
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.
It may be easy to import this Role from the database::admin but for whatever reason I just couldn't make it happen.
src/database/admin.rs
Outdated
@@ -360,10 +361,21 @@ impl AdminDatabase { | |||
":pubkey": node.pubkey, | |||
":status": node.status | |||
})?; | |||
|
|||
dbg!("Wrote node to the database"); |
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'll remove some of these dbg!
s. I went a little crazy with them trying to understand why the code was failing.
Ok(self.connection.last_insert_rowid()) | ||
} | ||
|
||
pub fn clear_pending_node(&mut self) -> Result<(), 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.
So this is an error state I could pretty reliably put my system into.
Basically it goes
- Create node in the sensei sqlite DB (empty string pubkey)
- Create the actual lightning node (gets a pubkey)
- Update the sensei sqlite record with the pubkey
If there was ever a problem creating the node in the lightning node or updating the sqlite record, then there is an existing empty-string-for-a-pubkey "node" that's basically WIP for the system, but a new node can never be created because it can't write any more "new node with empty string pubkey". So I made this to be able to "clean up after itself."
I actually think that's probably a wrong approach, and we should have a different table for like, "nodes to create" and then a "nodes created" and it's not just, "update the node record in place with a pubkey", but that's a bit larger scope.
src/database/admin.rs
Outdated
statement.execute(named_params! { | ||
":blank": "", | ||
})?; | ||
dbg!("I deleted the node with no pubkey because it sucks!"); |
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.
Ooops, will pull this.
src/database/admin.rs
Outdated
@@ -376,7 +388,7 @@ impl AdminDatabase { | |||
":pubkey": node.pubkey, | |||
":status": node.status | |||
})?; | |||
|
|||
dbg!("Ok now I just wrote a node update. It probably has a pubkey"); |
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.
TODO remove
src/grpc/admin.rs
Outdated
@@ -8,6 +8,7 @@ | |||
// licenses. | |||
|
|||
use std::sync::Arc; | |||
use tracing::{instrument, info, error, debug}; |
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 know how you feel about tracing/logging, but it seems like we need to get some kind of structured something in here. This library feels pretty fantastic for doing it. We can pull it back out for something better, but it felt good to me to use.
src/services/admin.rs
Outdated
node.id = database.create_node(node.clone()) | ||
.map_err(|err| { | ||
error!("Unable to create node in Sensei Database"); | ||
database.clear_pending_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.
This is a "Cleaning up after myself" I mentioned before. I got pretty good at putting my instance in this broken state.
src/services/admin.rs
Outdated
|
||
let lightning_node = self.get_node(node.clone(), passphrase).await?; | ||
let lightning_node = self.get_node(node.clone(), passphrase).await.unwrap(); |
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 have the explicit unwrap here because it felt like a panic at this stage, if it failed, is pretty acceptable. Not sure - the previous behavior was, "Fail silently" and this seems better but not necessarily optimal.
src/services/admin.rs
Outdated
node.pubkey = lightning_node.node_info()?.node_pubkey; | ||
|
||
dbg!("I have a pubkey even {:?}", node.pubkey.clone()); |
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.
Todo remove
* Host, port, and token can be set at runtime * Default host has the protocol specified (http)
Ok, this is my re-attempt at making the CLI work again
It feels pretty verbose to put all that on the CLI, but this actually gets the CLI back to a working state. I'm seeing unrelated errors it looks with listchannels returning an empty set, but the other node can see my channel, and the nodeinfo command shows an active channel (as above). But this gets it to working