-
Notifications
You must be signed in to change notification settings - Fork 37
Allow unspecified alias destinations #254
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
base: main
Are you sure you want to change the base?
Allow unspecified alias destinations #254
Conversation
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.
Dropped some notes. Open to suggestions.
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.
Promising start, but I think that this PR has scope crept a bit. I'd really like to keep this down to just the case where we have a destination alias that isn't in our configured set of nodes. Feel free to squash and restructure as suggested, we can start with fixups when the PR's structure is in good shape.
Also think that we need to look more carefully at the design of the graph function in the LightningNode
trait and move some of the more custom behavior into our validation function.
Thanks for the feedback. Will sort this out asap! |
Switches from an async closure to direct NetworkGraph usage for activity destination node lookup. This improves efficiency and maintainability, and enables destination aliases by validating against the graph and erroring on duplicates.
3b865f6
to
9fe6a15
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.
Moving in the right direction!
)) | ||
let graph = match clients.values().next() { | ||
Some(client) => client.lock().await.get_graph().await?, | ||
None => panic!("Graph is empty"), |
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.
Return an error rather than panicing?
@@ -5,12 +5,11 @@ use log::LevelFilter; | |||
use serde::{Deserialize, Serialize}; | |||
use simln_lib::{ | |||
cln, cln::ClnNode, eclair, eclair::EclairNode, lnd, lnd::LndNode, serializers, | |||
ActivityDefinition, Amount, Interval, LightningError, LightningNode, NodeId, NodeInfo, | |||
ActivityDefinition, Amount, Graph, Interval, LightningError, LightningNode, NodeId, NodeInfo, |
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.
Commit message still doesn't wrap at 72
@@ -215,9 +209,9 @@ async fn get_clients( | |||
/// validation. | |||
async fn add_node_to_maps( | |||
nodes: &HashMap<PublicKey, NodeInfo>, | |||
) -> Result<(HashMap<PublicKey, NodeInfo>, HashMap<String, NodeInfo>), LightningError> { | |||
) -> Result<(HashMap<PublicKey, NodeInfo>, HashMap<String, Vec<NodeInfo>>), LightningError> { |
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.
Does this need to be a vec?
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.
You are right. It doesn't have to be a vec anymore since we aren't allowing duplicates in the user-provided aliases.
// An alias can be mapped to multiple nodes because it is not a unique identifier. | ||
let mut graph_nodes_by_alias: HashMap<String, Vec<NodeInfo>> = HashMap::new(); | ||
|
||
// sort graph nodes by alias for easy lookups. |
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.
nit: unnecessary comment, can delete
alias_node_map: HashMap<String, NodeInfo>, | ||
get_node_info: impl AsyncFn(&PublicKey) -> Result<NodeInfo, LightningError>, | ||
alias_node_map: HashMap<String, Vec<NodeInfo>>, | ||
mut graph: Graph, |
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.
nit: let's pass in the hashmap that's ready for lookups here (like we do for the other maps)
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 would likely require passing in 2 hashmaps - one keyed by pk and the other by alias; we'd have 5 params in total. If this is fine by you then let's do it (or maybe use a struct?).
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.
Struct sounds good 👍
@@ -441,6 +442,8 @@ trait SimNetwork: Send + Sync { | |||
|
|||
/// Looks up a node in the simulated network and a list of its channel capacities. | |||
async fn lookup_node(&self, node: &PublicKey) -> Result<(NodeInfo, Vec<u64>), LightningError>; | |||
/// fetches all nodes in the simulated network |
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.
nit: capitals for docs, applies in a few places
pub fn get_nodes(&mut self) -> Result<HashMap<PublicKey, NodeInfo>, LightningError> { | ||
Ok(self.nodes_by_pk.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.
This seems like an unnecessary clone to me (for a data struct that could have around 16k entries in it).
I think it's okay to make nodes_by_pk
pub
and then callers can borrow rather than needing to copy all this data + have specialized getters.
if let Some(node_infos) = alias_node_map.get(a) { | ||
node_infos[0].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.
I don't see why we need to allow multiple node_infos
in our alias_node_map
when that's a map of the aliases that the user specified and we validated to make sure are unique?
graph_nodes_by_alias
makes sense as a vec, I like the impl, but we don't need to change both.
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, not making alias_node_map
structured as a vec of node_infos
will fix this.
described above). Activity sources and destinations may reference the | ||
`id` defined in `nodes`, but destinations that are not listed in `nodes` | ||
*must* provide a valid public key. | ||
Nodes can be identified by their public key or an id string (as described above). Activity sources and destinations may reference the `id` defined in `nodes`. However, if multiple destination nodes have the same id string (alias), valid public keys *must* be used to identify the nodes. |
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.
nit: line wrapping incorrect
described above). Activity sources and destinations may reference the | ||
`id` defined in `nodes`, but destinations that are not listed in `nodes` | ||
*must* provide a valid public key. | ||
Nodes can be identified by their public key or an id string (as described above). Activity sources and destinations may reference the `id` defined in `nodes`. However, if multiple destination nodes have the same id string (alias), valid public keys *must* be used to identify the nodes. |
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.
Would also like to rephrase this a bit.
Activity sources must reference an id
defined in nodes
, because the simulator can
only send payments from nodes that it controls. Destinations may reference either an
id
defined in nodes
or provide a pubkey
or alias
of a node in the public network.
If the alias
provided is not unique in the public network, a pubkey
must be used
to identify the node.
Description
This PR pulls up the network graph to make it simpler to run node lookups using public keys and aliases. This new node lookup approach is used to allow unspecified aliases in activity destinations by confirming if node(s) with unspecified alias exists in the graph.
Changes
get_graph
function toLightningNode
trait and implemented it in the different LN implementations.This PR closes #227