This repository was archived by the owner on Dec 19, 2025. It is now read-only.

pathfinding - #192

Draft
Vib-UX wants to merge 12 commits into
node-lightning:mainfrom
Vib-UX:path_finding
Draft

pathfinding#192
Vib-UX wants to merge 12 commits into
node-lightning:mainfrom
Vib-UX:path_finding

Conversation

@Vib-UX

Copy link
Copy Markdown
Contributor

fixes#190

@Vib-UXVib-UX changed the title Work in ProgresspathfindingAug 21, 2021
@codecov-commenter

codecov-commenter commented Aug 21, 2021

Copy link
Copy Markdown

Codecov Report

Merging #192 (698cb5a) into main (eacb603) will decrease coverage by 0.90%.
The diff coverage is 45.05%.

❗ Current head 698cb5a differs from pull request most recent head 96146da. Consider uploading reports for the commit 96146da to get more accurate results
Impacted file tree graph

@@ Coverage Diff @@## main #192 +/- ##
==========================================
- Coverage 93.37% 92.47% -0.91% 
==========================================
Files 182 183 +1 Lines 4757 4848 +91 Branches 561 581 +20 ==========================================
+ Hits 4442 4483 +41 - Misses 174 214 +40 - Partials 141 151 +10 
Impacted FilesCoverage Δ
packages/graph/lib/PriorityQueue.ts34.00% <34.00%> (ø)
packages/graph/lib/graph.ts73.01% <58.53%> (-26.99%)⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update eacb603...96146da. Read the comment docs.

@bmancini55bmancini55 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

K its coming along nicely. Some nits surrounding coding style that we can go over. The biggest issues I see are:

  1. The construction of the adjacency list is only from node1 -> node2. The graph is a symmetric directed graph meaning each channel is two edges: node1->node2 and node2->node1.

  2. This would be facilitated by using the Node's channels property, which is a Map. If it helps you can create a secondary property on Node that returns a tuple containing the [Channel,ChannelSettings] for the Node's channel setting which would aid in point 1.

  3. Finding the min distance should ideally use a heap, but we can get to optimizations later.

Comment threadpackages/graph/lib/graph.ts Outdated
* Graph represents a
*/
export class Graph {
public nodes_list: string[] = [];

@bmancini55bmancini55Sep 8, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Probably don't need nodes_list. Can easily iterate over a Map type:

constmap=newMap();map.set(1,'a');map.set(2,'b');map.set(3,'c');// iterate over key-values since Map is an iteratorfor(const[key,val]ofmap){console.log(key,val);}// iterate over keys as an iteratorfor(constkeyofmap.keys()){console.log(key);}// iterate over vals as an iteratorfor(constvalofmap.values()){console.log(val);}

Lastly you can covert any iterator into an Array with Array.from:

console.log(Array.from(map));console.log(Array.from(map.keys()));console.log(Array.from(map.values()));

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Sure thing will work with maps (;

Comment threadpackages/graph/lib/graph.ts Outdated
*/
export class Graph {
public nodes_list: string[] = [];
public adjacencyList = {};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same for adjacency list. The Node type includes a Channels Map that contains all of the Channels the Node is a member of.

Comment threadpackages/graph/lib/graph.ts Outdated
const str_id = dest.nodeId.toString("hex");

// Distances will store the base_fee required to traverse from the src
let distances = {},

@bmancini55bmancini55Sep 8, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Language nit: use maps over objects. Even though JS/TS allows object mutation, memory management is most effective when types remain static. As such the Set/Map types are better suited for that type of stuff.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

K its coming along nicely. Some nits surrounding coding style that we can go over. The biggest issues I see are:

  1. The construction of the adjacency list is only from node1 -> node2. The graph is a symmetric directed graph meaning each channel is two edges: node1->node2 and node2->node1.
  2. This would be facilitated by using the Node's channels property, which is a Map. If it helps you can create a secondary property on Node that returns a tuple containing the [Channel,ChannelSettings] for the Node's channel setting which would aid in point 1.
  3. Finding the min distance should ideally use a heap, but we can get to optimizations later.

Yes, I made a mistake it should behave like an undirected graph. Nice Catch 😓

@bmancini55

Copy link
Copy Markdown
Member

Yes, I made a mistake it should behave like an undirected graph. Nice Catch sweat

Conceptually yes, channels are similar to undirected/symmetric directed graph. So both directions or every node pair where a channel exists are theoretically possible and need to be considered. For routing purposes that symmetry may break when:

  1. A channel only has settings on one side (meaning it only received a channel_update from one of the nodes)
  2. A node may disable it's side of the channel in the update message
  3. The min/max settings may prevent an HTLC from being routeable.

@bmancini55

Copy link
Copy Markdown
Member

Also just for edification, node1/node2 in the channel are just the lexicographical ordering of the identifiers. When I first starting learning this stuff I thought node1 was the opener or had some larger meaning. But it's just the node with the lower ordered nodeId.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

Also just for edification, node1/node2 in the channel are just the lexicographical ordering of the identifiers. When I first starting learning this stuff I thought node1 was the opener or had some larger meaning. But it's just the node with the lower ordered nodeId.

That's really insightful 💡 , I actually thought that node1 is probably the one who opened the channel.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

K its coming along nicely. Some nits surrounding coding style that we can go over. The biggest issues I see are:

  1. The construction of the adjacency list is only from node1 -> node2. The graph is a symmetric directed graph meaning each channel is two edges: node1->node2 and node2->node1.
  2. This would be facilitated by using the Node's channels property, which is a Map. If it helps you can create a secondary property on Node that returns a tuple containing the [Channel,ChannelSettings] for the Node's channel setting which would aid in point 1.
  3. Finding the min distance should ideally use a heap, but we can get to optimizations later.

For Heap optimization, I found this package related to priority queues we can import that and workaround with it or should I build it from scratch?

@bmancini55

Copy link
Copy Markdown
Member

For Heap optimization, I found this package related to priority queues we can import that and workaround with it or should I build it from scratch?

* https://www.npmjs.com/package/priorityqueuejs

Scratch, we try to avoid external packages where possible.

We'll most likely put it in the Core package but feel free to add it to this project first so we don't have to deal with deps issues while prototyping.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

For Heap optimization, I found this package related to priority queues we can import that and workaround with it or should I build it from scratch?

* https://www.npmjs.com/package/priorityqueuejs

Scratch, we try to avoid external packages where possible.

We'll most likely put it in the Core package but feel free to add it to this project first so we don't have to deal with deps issues while prototyping.

Sure 🤝

Comment threadpackages/graph/lib/graph.ts Outdated
// from dest --> src and return route from src --> dest

// Convert it to corresponding node_id
const str_id = dest.nodeId.toString("hex");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Consider calling this variable dest_str_id or dest_id

@bmancini55bmancini55 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

min-heap looks good with a couple minors. If you want to split that into a separate PR and add tests we can merge it in.

I still need to review dijkstras using the heap.

Comment threadpackages/graph/lib/PriorityQueue.ts Outdated
this._queue.push(value);
let pos = this._queue.length - 1;

while (pos !== 0 && this._compare(this._queue[this._parentOf(pos)], this._queue[pos])) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

micro optimization but cache the call to _parentOf since we call it 3 times. will require refactor to a do/while loop.

Comment threadpackages/graph/lib/PriorityQueue.ts Outdated
}

private _compare(item1: T, item2: T) {
if (this._comparator) {

@bmancini55bmancini55Sep 15, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we can make the _comparator compulsory in the constructor, then we dont' need this check and can drop this whole function.

Comment threadpackages/graph/lib/PriorityQueue.ts Outdated
this._queue = [];
}

public contains(value: T, comparator?: (item: T) => boolean) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we need this operation? If not then lets drop it since its extra code

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

min-heap looks good with a couple minors. If you want to split that into a separate PR and add tests we can merge it in.

I still need to review dijkstras using the heap.

separate PR would make it look neat

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

graph: path finding

4 participants

@Vib-UX@codecov-commenter@bmancini55@Randy808
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
This repository was archived by the owner on Dec 19, 2025. It is now read-only.

pathfinding - #192

Draft
Vib-UX wants to merge 12 commits into
node-lightning:mainfrom
Vib-UX:path_finding
Draft

pathfinding#192
Vib-UX wants to merge 12 commits into
node-lightning:mainfrom
Vib-UX:path_finding

Conversation

@Vib-UX

Copy link
Copy Markdown
Contributor

fixes#190

@Vib-UXVib-UX changed the title Work in ProgresspathfindingAug 21, 2021
@codecov-commenter

codecov-commenter commented Aug 21, 2021

Copy link
Copy Markdown

Codecov Report

Merging #192 (698cb5a) into main (eacb603) will decrease coverage by 0.90%.
The diff coverage is 45.05%.

❗ Current head 698cb5a differs from pull request most recent head 96146da. Consider uploading reports for the commit 96146da to get more accurate results
Impacted file tree graph

@@ Coverage Diff @@## main #192 +/- ##
==========================================
- Coverage 93.37% 92.47% -0.91% 
==========================================
Files 182 183 +1 Lines 4757 4848 +91 Branches 561 581 +20 ==========================================
+ Hits 4442 4483 +41 - Misses 174 214 +40 - Partials 141 151 +10 
Impacted FilesCoverage Δ
packages/graph/lib/PriorityQueue.ts34.00% <34.00%> (ø)
packages/graph/lib/graph.ts73.01% <58.53%> (-26.99%)⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update eacb603...96146da. Read the comment docs.

@bmancini55bmancini55 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

K its coming along nicely. Some nits surrounding coding style that we can go over. The biggest issues I see are:

  1. The construction of the adjacency list is only from node1 -> node2. The graph is a symmetric directed graph meaning each channel is two edges: node1->node2 and node2->node1.

  2. This would be facilitated by using the Node's channels property, which is a Map. If it helps you can create a secondary property on Node that returns a tuple containing the [Channel,ChannelSettings] for the Node's channel setting which would aid in point 1.

  3. Finding the min distance should ideally use a heap, but we can get to optimizations later.

Comment threadpackages/graph/lib/graph.ts Outdated
* Graph represents a
*/
export class Graph {
public nodes_list: string[] = [];

@bmancini55bmancini55Sep 8, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Probably don't need nodes_list. Can easily iterate over a Map type:

constmap=newMap();map.set(1,'a');map.set(2,'b');map.set(3,'c');// iterate over key-values since Map is an iteratorfor(const[key,val]ofmap){console.log(key,val);}// iterate over keys as an iteratorfor(constkeyofmap.keys()){console.log(key);}// iterate over vals as an iteratorfor(constvalofmap.values()){console.log(val);}

Lastly you can covert any iterator into an Array with Array.from:

console.log(Array.from(map));console.log(Array.from(map.keys()));console.log(Array.from(map.values()));

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Sure thing will work with maps (;

Comment threadpackages/graph/lib/graph.ts Outdated
*/
export class Graph {
public nodes_list: string[] = [];
public adjacencyList = {};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same for adjacency list. The Node type includes a Channels Map that contains all of the Channels the Node is a member of.

Comment threadpackages/graph/lib/graph.ts Outdated
const str_id = dest.nodeId.toString("hex");

// Distances will store the base_fee required to traverse from the src
let distances = {},

@bmancini55bmancini55Sep 8, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Language nit: use maps over objects. Even though JS/TS allows object mutation, memory management is most effective when types remain static. As such the Set/Map types are better suited for that type of stuff.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

K its coming along nicely. Some nits surrounding coding style that we can go over. The biggest issues I see are:

  1. The construction of the adjacency list is only from node1 -> node2. The graph is a symmetric directed graph meaning each channel is two edges: node1->node2 and node2->node1.
  2. This would be facilitated by using the Node's channels property, which is a Map. If it helps you can create a secondary property on Node that returns a tuple containing the [Channel,ChannelSettings] for the Node's channel setting which would aid in point 1.
  3. Finding the min distance should ideally use a heap, but we can get to optimizations later.

Yes, I made a mistake it should behave like an undirected graph. Nice Catch 😓

@bmancini55

Copy link
Copy Markdown
Member

Yes, I made a mistake it should behave like an undirected graph. Nice Catch sweat

Conceptually yes, channels are similar to undirected/symmetric directed graph. So both directions or every node pair where a channel exists are theoretically possible and need to be considered. For routing purposes that symmetry may break when:

  1. A channel only has settings on one side (meaning it only received a channel_update from one of the nodes)
  2. A node may disable it's side of the channel in the update message
  3. The min/max settings may prevent an HTLC from being routeable.

@bmancini55

Copy link
Copy Markdown
Member

Also just for edification, node1/node2 in the channel are just the lexicographical ordering of the identifiers. When I first starting learning this stuff I thought node1 was the opener or had some larger meaning. But it's just the node with the lower ordered nodeId.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

Also just for edification, node1/node2 in the channel are just the lexicographical ordering of the identifiers. When I first starting learning this stuff I thought node1 was the opener or had some larger meaning. But it's just the node with the lower ordered nodeId.

That's really insightful 💡 , I actually thought that node1 is probably the one who opened the channel.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

K its coming along nicely. Some nits surrounding coding style that we can go over. The biggest issues I see are:

  1. The construction of the adjacency list is only from node1 -> node2. The graph is a symmetric directed graph meaning each channel is two edges: node1->node2 and node2->node1.
  2. This would be facilitated by using the Node's channels property, which is a Map. If it helps you can create a secondary property on Node that returns a tuple containing the [Channel,ChannelSettings] for the Node's channel setting which would aid in point 1.
  3. Finding the min distance should ideally use a heap, but we can get to optimizations later.

For Heap optimization, I found this package related to priority queues we can import that and workaround with it or should I build it from scratch?

@bmancini55

Copy link
Copy Markdown
Member

For Heap optimization, I found this package related to priority queues we can import that and workaround with it or should I build it from scratch?

* https://www.npmjs.com/package/priorityqueuejs

Scratch, we try to avoid external packages where possible.

We'll most likely put it in the Core package but feel free to add it to this project first so we don't have to deal with deps issues while prototyping.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

For Heap optimization, I found this package related to priority queues we can import that and workaround with it or should I build it from scratch?

* https://www.npmjs.com/package/priorityqueuejs

Scratch, we try to avoid external packages where possible.

We'll most likely put it in the Core package but feel free to add it to this project first so we don't have to deal with deps issues while prototyping.

Sure 🤝

Comment threadpackages/graph/lib/graph.ts Outdated
// from dest --> src and return route from src --> dest

// Convert it to corresponding node_id
const str_id = dest.nodeId.toString("hex");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Consider calling this variable dest_str_id or dest_id

@bmancini55bmancini55 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

min-heap looks good with a couple minors. If you want to split that into a separate PR and add tests we can merge it in.

I still need to review dijkstras using the heap.

Comment threadpackages/graph/lib/PriorityQueue.ts Outdated
this._queue.push(value);
let pos = this._queue.length - 1;

while (pos !== 0 && this._compare(this._queue[this._parentOf(pos)], this._queue[pos])) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

micro optimization but cache the call to _parentOf since we call it 3 times. will require refactor to a do/while loop.

Comment threadpackages/graph/lib/PriorityQueue.ts Outdated
}

private _compare(item1: T, item2: T) {
if (this._comparator) {

@bmancini55bmancini55Sep 15, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we can make the _comparator compulsory in the constructor, then we dont' need this check and can drop this whole function.

Comment threadpackages/graph/lib/PriorityQueue.ts Outdated
this._queue = [];
}

public contains(value: T, comparator?: (item: T) => boolean) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we need this operation? If not then lets drop it since its extra code

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

min-heap looks good with a couple minors. If you want to split that into a separate PR and add tests we can merge it in.

I still need to review dijkstras using the heap.

separate PR would make it look neat

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

graph: path finding

4 participants

@Vib-UX@codecov-commenter@bmancini55@Randy808
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Dec 19, 2025. It is now read-only.

pathfinding - #192

Draft
Vib-UX wants to merge 12 commits into
node-lightning:mainfrom
Vib-UX:path_finding
Draft

pathfinding#192
Vib-UX wants to merge 12 commits into
node-lightning:mainfrom
Vib-UX:path_finding

Conversation

@Vib-UX

Copy link
Copy Markdown
Contributor

fixes#190

@Vib-UXVib-UX changed the title Work in ProgresspathfindingAug 21, 2021
@codecov-commenter

codecov-commenter commented Aug 21, 2021

Copy link
Copy Markdown

Codecov Report

Merging #192 (698cb5a) into main (eacb603) will decrease coverage by 0.90%.
The diff coverage is 45.05%.

❗ Current head 698cb5a differs from pull request most recent head 96146da. Consider uploading reports for the commit 96146da to get more accurate results
Impacted file tree graph

@@ Coverage Diff @@## main #192 +/- ##
==========================================
- Coverage 93.37% 92.47% -0.91% 
==========================================
Files 182 183 +1 Lines 4757 4848 +91 Branches 561 581 +20 ==========================================
+ Hits 4442 4483 +41 - Misses 174 214 +40 - Partials 141 151 +10 
Impacted FilesCoverage Δ
packages/graph/lib/PriorityQueue.ts34.00% <34.00%> (ø)
packages/graph/lib/graph.ts73.01% <58.53%> (-26.99%)⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update eacb603...96146da. Read the comment docs.

@bmancini55bmancini55 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

K its coming along nicely. Some nits surrounding coding style that we can go over. The biggest issues I see are:

  1. The construction of the adjacency list is only from node1 -> node2. The graph is a symmetric directed graph meaning each channel is two edges: node1->node2 and node2->node1.

  2. This would be facilitated by using the Node's channels property, which is a Map. If it helps you can create a secondary property on Node that returns a tuple containing the [Channel,ChannelSettings] for the Node's channel setting which would aid in point 1.

  3. Finding the min distance should ideally use a heap, but we can get to optimizations later.

Comment threadpackages/graph/lib/graph.ts Outdated
* Graph represents a
*/
export class Graph {
public nodes_list: string[] = [];

@bmancini55bmancini55Sep 8, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Probably don't need nodes_list. Can easily iterate over a Map type:

constmap=newMap();map.set(1,'a');map.set(2,'b');map.set(3,'c');// iterate over key-values since Map is an iteratorfor(const[key,val]ofmap){console.log(key,val);}// iterate over keys as an iteratorfor(constkeyofmap.keys()){console.log(key);}// iterate over vals as an iteratorfor(constvalofmap.values()){console.log(val);}

Lastly you can covert any iterator into an Array with Array.from:

console.log(Array.from(map));console.log(Array.from(map.keys()));console.log(Array.from(map.values()));

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Sure thing will work with maps (;

Comment threadpackages/graph/lib/graph.ts Outdated
*/
export class Graph {
public nodes_list: string[] = [];
public adjacencyList = {};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same for adjacency list. The Node type includes a Channels Map that contains all of the Channels the Node is a member of.

Comment threadpackages/graph/lib/graph.ts Outdated
const str_id = dest.nodeId.toString("hex");

// Distances will store the base_fee required to traverse from the src
let distances = {},

@bmancini55bmancini55Sep 8, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Language nit: use maps over objects. Even though JS/TS allows object mutation, memory management is most effective when types remain static. As such the Set/Map types are better suited for that type of stuff.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

K its coming along nicely. Some nits surrounding coding style that we can go over. The biggest issues I see are:

  1. The construction of the adjacency list is only from node1 -> node2. The graph is a symmetric directed graph meaning each channel is two edges: node1->node2 and node2->node1.
  2. This would be facilitated by using the Node's channels property, which is a Map. If it helps you can create a secondary property on Node that returns a tuple containing the [Channel,ChannelSettings] for the Node's channel setting which would aid in point 1.
  3. Finding the min distance should ideally use a heap, but we can get to optimizations later.

Yes, I made a mistake it should behave like an undirected graph. Nice Catch 😓

@bmancini55

Copy link
Copy Markdown
Member

Yes, I made a mistake it should behave like an undirected graph. Nice Catch sweat

Conceptually yes, channels are similar to undirected/symmetric directed graph. So both directions or every node pair where a channel exists are theoretically possible and need to be considered. For routing purposes that symmetry may break when:

  1. A channel only has settings on one side (meaning it only received a channel_update from one of the nodes)
  2. A node may disable it's side of the channel in the update message
  3. The min/max settings may prevent an HTLC from being routeable.

@bmancini55

Copy link
Copy Markdown
Member

Also just for edification, node1/node2 in the channel are just the lexicographical ordering of the identifiers. When I first starting learning this stuff I thought node1 was the opener or had some larger meaning. But it's just the node with the lower ordered nodeId.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

Also just for edification, node1/node2 in the channel are just the lexicographical ordering of the identifiers. When I first starting learning this stuff I thought node1 was the opener or had some larger meaning. But it's just the node with the lower ordered nodeId.

That's really insightful 💡 , I actually thought that node1 is probably the one who opened the channel.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

K its coming along nicely. Some nits surrounding coding style that we can go over. The biggest issues I see are:

  1. The construction of the adjacency list is only from node1 -> node2. The graph is a symmetric directed graph meaning each channel is two edges: node1->node2 and node2->node1.
  2. This would be facilitated by using the Node's channels property, which is a Map. If it helps you can create a secondary property on Node that returns a tuple containing the [Channel,ChannelSettings] for the Node's channel setting which would aid in point 1.
  3. Finding the min distance should ideally use a heap, but we can get to optimizations later.

For Heap optimization, I found this package related to priority queues we can import that and workaround with it or should I build it from scratch?

@bmancini55

Copy link
Copy Markdown
Member

For Heap optimization, I found this package related to priority queues we can import that and workaround with it or should I build it from scratch?

* https://www.npmjs.com/package/priorityqueuejs

Scratch, we try to avoid external packages where possible.

We'll most likely put it in the Core package but feel free to add it to this project first so we don't have to deal with deps issues while prototyping.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

For Heap optimization, I found this package related to priority queues we can import that and workaround with it or should I build it from scratch?

* https://www.npmjs.com/package/priorityqueuejs

Scratch, we try to avoid external packages where possible.

We'll most likely put it in the Core package but feel free to add it to this project first so we don't have to deal with deps issues while prototyping.

Sure 🤝

Comment threadpackages/graph/lib/graph.ts Outdated
// from dest --> src and return route from src --> dest

// Convert it to corresponding node_id
const str_id = dest.nodeId.toString("hex");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Consider calling this variable dest_str_id or dest_id

@bmancini55bmancini55 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

min-heap looks good with a couple minors. If you want to split that into a separate PR and add tests we can merge it in.

I still need to review dijkstras using the heap.

Comment threadpackages/graph/lib/PriorityQueue.ts Outdated
this._queue.push(value);
let pos = this._queue.length - 1;

while (pos !== 0 && this._compare(this._queue[this._parentOf(pos)], this._queue[pos])) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

micro optimization but cache the call to _parentOf since we call it 3 times. will require refactor to a do/while loop.

Comment threadpackages/graph/lib/PriorityQueue.ts Outdated
}

private _compare(item1: T, item2: T) {
if (this._comparator) {

@bmancini55bmancini55Sep 15, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we can make the _comparator compulsory in the constructor, then we dont' need this check and can drop this whole function.

Comment threadpackages/graph/lib/PriorityQueue.ts Outdated
this._queue = [];
}

public contains(value: T, comparator?: (item: T) => boolean) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we need this operation? If not then lets drop it since its extra code

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

min-heap looks good with a couple minors. If you want to split that into a separate PR and add tests we can merge it in.

I still need to review dijkstras using the heap.

separate PR would make it look neat

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

graph: path finding

4 participants

@Vib-UX@codecov-commenter@bmancini55@Randy808
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Dec 19, 2025. It is now read-only.

pathfinding - #192

Draft
Vib-UX wants to merge 12 commits into
node-lightning:mainfrom
Vib-UX:path_finding
Draft

pathfinding#192
Vib-UX wants to merge 12 commits into
node-lightning:mainfrom
Vib-UX:path_finding

Conversation

@Vib-UX

Copy link
Copy Markdown
Contributor

fixes#190

@Vib-UXVib-UX changed the title Work in ProgresspathfindingAug 21, 2021
@codecov-commenter

codecov-commenter commented Aug 21, 2021

Copy link
Copy Markdown

Codecov Report

Merging #192 (698cb5a) into main (eacb603) will decrease coverage by 0.90%.
The diff coverage is 45.05%.

❗ Current head 698cb5a differs from pull request most recent head 96146da. Consider uploading reports for the commit 96146da to get more accurate results
Impacted file tree graph

@@ Coverage Diff @@## main #192 +/- ##
==========================================
- Coverage 93.37% 92.47% -0.91% 
==========================================
Files 182 183 +1 Lines 4757 4848 +91 Branches 561 581 +20 ==========================================
+ Hits 4442 4483 +41 - Misses 174 214 +40 - Partials 141 151 +10 
Impacted FilesCoverage Δ
packages/graph/lib/PriorityQueue.ts34.00% <34.00%> (ø)
packages/graph/lib/graph.ts73.01% <58.53%> (-26.99%)⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update eacb603...96146da. Read the comment docs.

@bmancini55bmancini55 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

K its coming along nicely. Some nits surrounding coding style that we can go over. The biggest issues I see are:

  1. The construction of the adjacency list is only from node1 -> node2. The graph is a symmetric directed graph meaning each channel is two edges: node1->node2 and node2->node1.

  2. This would be facilitated by using the Node's channels property, which is a Map. If it helps you can create a secondary property on Node that returns a tuple containing the [Channel,ChannelSettings] for the Node's channel setting which would aid in point 1.

  3. Finding the min distance should ideally use a heap, but we can get to optimizations later.

Comment threadpackages/graph/lib/graph.ts Outdated
* Graph represents a
*/
export class Graph {
public nodes_list: string[] = [];

@bmancini55bmancini55Sep 8, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Probably don't need nodes_list. Can easily iterate over a Map type:

constmap=newMap();map.set(1,'a');map.set(2,'b');map.set(3,'c');// iterate over key-values since Map is an iteratorfor(const[key,val]ofmap){console.log(key,val);}// iterate over keys as an iteratorfor(constkeyofmap.keys()){console.log(key);}// iterate over vals as an iteratorfor(constvalofmap.values()){console.log(val);}

Lastly you can covert any iterator into an Array with Array.from:

console.log(Array.from(map));console.log(Array.from(map.keys()));console.log(Array.from(map.values()));

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Sure thing will work with maps (;

Comment threadpackages/graph/lib/graph.ts Outdated
*/
export class Graph {
public nodes_list: string[] = [];
public adjacencyList = {};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same for adjacency list. The Node type includes a Channels Map that contains all of the Channels the Node is a member of.

Comment threadpackages/graph/lib/graph.ts Outdated
const str_id = dest.nodeId.toString("hex");

// Distances will store the base_fee required to traverse from the src
let distances = {},

@bmancini55bmancini55Sep 8, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Language nit: use maps over objects. Even though JS/TS allows object mutation, memory management is most effective when types remain static. As such the Set/Map types are better suited for that type of stuff.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

K its coming along nicely. Some nits surrounding coding style that we can go over. The biggest issues I see are:

  1. The construction of the adjacency list is only from node1 -> node2. The graph is a symmetric directed graph meaning each channel is two edges: node1->node2 and node2->node1.
  2. This would be facilitated by using the Node's channels property, which is a Map. If it helps you can create a secondary property on Node that returns a tuple containing the [Channel,ChannelSettings] for the Node's channel setting which would aid in point 1.
  3. Finding the min distance should ideally use a heap, but we can get to optimizations later.

Yes, I made a mistake it should behave like an undirected graph. Nice Catch 😓

@bmancini55

Copy link
Copy Markdown
Member

Yes, I made a mistake it should behave like an undirected graph. Nice Catch sweat

Conceptually yes, channels are similar to undirected/symmetric directed graph. So both directions or every node pair where a channel exists are theoretically possible and need to be considered. For routing purposes that symmetry may break when:

  1. A channel only has settings on one side (meaning it only received a channel_update from one of the nodes)
  2. A node may disable it's side of the channel in the update message
  3. The min/max settings may prevent an HTLC from being routeable.

@bmancini55

Copy link
Copy Markdown
Member

Also just for edification, node1/node2 in the channel are just the lexicographical ordering of the identifiers. When I first starting learning this stuff I thought node1 was the opener or had some larger meaning. But it's just the node with the lower ordered nodeId.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

Also just for edification, node1/node2 in the channel are just the lexicographical ordering of the identifiers. When I first starting learning this stuff I thought node1 was the opener or had some larger meaning. But it's just the node with the lower ordered nodeId.

That's really insightful 💡 , I actually thought that node1 is probably the one who opened the channel.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

K its coming along nicely. Some nits surrounding coding style that we can go over. The biggest issues I see are:

  1. The construction of the adjacency list is only from node1 -> node2. The graph is a symmetric directed graph meaning each channel is two edges: node1->node2 and node2->node1.
  2. This would be facilitated by using the Node's channels property, which is a Map. If it helps you can create a secondary property on Node that returns a tuple containing the [Channel,ChannelSettings] for the Node's channel setting which would aid in point 1.
  3. Finding the min distance should ideally use a heap, but we can get to optimizations later.

For Heap optimization, I found this package related to priority queues we can import that and workaround with it or should I build it from scratch?

@bmancini55

Copy link
Copy Markdown
Member

For Heap optimization, I found this package related to priority queues we can import that and workaround with it or should I build it from scratch?

* https://www.npmjs.com/package/priorityqueuejs

Scratch, we try to avoid external packages where possible.

We'll most likely put it in the Core package but feel free to add it to this project first so we don't have to deal with deps issues while prototyping.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

For Heap optimization, I found this package related to priority queues we can import that and workaround with it or should I build it from scratch?

* https://www.npmjs.com/package/priorityqueuejs

Scratch, we try to avoid external packages where possible.

We'll most likely put it in the Core package but feel free to add it to this project first so we don't have to deal with deps issues while prototyping.

Sure 🤝

Comment threadpackages/graph/lib/graph.ts Outdated
// from dest --> src and return route from src --> dest

// Convert it to corresponding node_id
const str_id = dest.nodeId.toString("hex");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Consider calling this variable dest_str_id or dest_id

@bmancini55bmancini55 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

min-heap looks good with a couple minors. If you want to split that into a separate PR and add tests we can merge it in.

I still need to review dijkstras using the heap.

Comment threadpackages/graph/lib/PriorityQueue.ts Outdated
this._queue.push(value);
let pos = this._queue.length - 1;

while (pos !== 0 && this._compare(this._queue[this._parentOf(pos)], this._queue[pos])) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

micro optimization but cache the call to _parentOf since we call it 3 times. will require refactor to a do/while loop.

Comment threadpackages/graph/lib/PriorityQueue.ts Outdated
}

private _compare(item1: T, item2: T) {
if (this._comparator) {

@bmancini55bmancini55Sep 15, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we can make the _comparator compulsory in the constructor, then we dont' need this check and can drop this whole function.

Comment threadpackages/graph/lib/PriorityQueue.ts Outdated
this._queue = [];
}

public contains(value: T, comparator?: (item: T) => boolean) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we need this operation? If not then lets drop it since its extra code

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

min-heap looks good with a couple minors. If you want to split that into a separate PR and add tests we can merge it in.

I still need to review dijkstras using the heap.

separate PR would make it look neat

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

graph: path finding

4 participants

@Vib-UX@codecov-commenter@bmancini55@Randy808
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
This repository was archived by the owner on Dec 19, 2025. It is now read-only.

pathfinding - #192

Draft
Vib-UX wants to merge 12 commits into
node-lightning:mainfrom
Vib-UX:path_finding
Draft

pathfinding#192
Vib-UX wants to merge 12 commits into
node-lightning:mainfrom
Vib-UX:path_finding

Conversation

@Vib-UX

Copy link
Copy Markdown
Contributor

fixes#190

@Vib-UXVib-UX changed the title Work in ProgresspathfindingAug 21, 2021
@codecov-commenter

codecov-commenter commented Aug 21, 2021

Copy link
Copy Markdown

Codecov Report

Merging #192 (698cb5a) into main (eacb603) will decrease coverage by 0.90%.
The diff coverage is 45.05%.

❗ Current head 698cb5a differs from pull request most recent head 96146da. Consider uploading reports for the commit 96146da to get more accurate results
Impacted file tree graph

@@ Coverage Diff @@## main #192 +/- ##
==========================================
- Coverage 93.37% 92.47% -0.91% 
==========================================
Files 182 183 +1 Lines 4757 4848 +91 Branches 561 581 +20 ==========================================
+ Hits 4442 4483 +41 - Misses 174 214 +40 - Partials 141 151 +10 
Impacted FilesCoverage Δ
packages/graph/lib/PriorityQueue.ts34.00% <34.00%> (ø)
packages/graph/lib/graph.ts73.01% <58.53%> (-26.99%)⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update eacb603...96146da. Read the comment docs.

@bmancini55bmancini55 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

K its coming along nicely. Some nits surrounding coding style that we can go over. The biggest issues I see are:

  1. The construction of the adjacency list is only from node1 -> node2. The graph is a symmetric directed graph meaning each channel is two edges: node1->node2 and node2->node1.

  2. This would be facilitated by using the Node's channels property, which is a Map. If it helps you can create a secondary property on Node that returns a tuple containing the [Channel,ChannelSettings] for the Node's channel setting which would aid in point 1.

  3. Finding the min distance should ideally use a heap, but we can get to optimizations later.

Comment threadpackages/graph/lib/graph.ts Outdated
* Graph represents a
*/
export class Graph {
public nodes_list: string[] = [];

@bmancini55bmancini55Sep 8, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Probably don't need nodes_list. Can easily iterate over a Map type:

constmap=newMap();map.set(1,'a');map.set(2,'b');map.set(3,'c');// iterate over key-values since Map is an iteratorfor(const[key,val]ofmap){console.log(key,val);}// iterate over keys as an iteratorfor(constkeyofmap.keys()){console.log(key);}// iterate over vals as an iteratorfor(constvalofmap.values()){console.log(val);}

Lastly you can covert any iterator into an Array with Array.from:

console.log(Array.from(map));console.log(Array.from(map.keys()));console.log(Array.from(map.values()));

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Sure thing will work with maps (;

Comment threadpackages/graph/lib/graph.ts Outdated
*/
export class Graph {
public nodes_list: string[] = [];
public adjacencyList = {};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same for adjacency list. The Node type includes a Channels Map that contains all of the Channels the Node is a member of.

Comment threadpackages/graph/lib/graph.ts Outdated
const str_id = dest.nodeId.toString("hex");

// Distances will store the base_fee required to traverse from the src
let distances = {},

@bmancini55bmancini55Sep 8, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Language nit: use maps over objects. Even though JS/TS allows object mutation, memory management is most effective when types remain static. As such the Set/Map types are better suited for that type of stuff.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

K its coming along nicely. Some nits surrounding coding style that we can go over. The biggest issues I see are:

  1. The construction of the adjacency list is only from node1 -> node2. The graph is a symmetric directed graph meaning each channel is two edges: node1->node2 and node2->node1.
  2. This would be facilitated by using the Node's channels property, which is a Map. If it helps you can create a secondary property on Node that returns a tuple containing the [Channel,ChannelSettings] for the Node's channel setting which would aid in point 1.
  3. Finding the min distance should ideally use a heap, but we can get to optimizations later.

Yes, I made a mistake it should behave like an undirected graph. Nice Catch 😓

@bmancini55

Copy link
Copy Markdown
Member

Yes, I made a mistake it should behave like an undirected graph. Nice Catch sweat

Conceptually yes, channels are similar to undirected/symmetric directed graph. So both directions or every node pair where a channel exists are theoretically possible and need to be considered. For routing purposes that symmetry may break when:

  1. A channel only has settings on one side (meaning it only received a channel_update from one of the nodes)
  2. A node may disable it's side of the channel in the update message
  3. The min/max settings may prevent an HTLC from being routeable.

@bmancini55

Copy link
Copy Markdown
Member

Also just for edification, node1/node2 in the channel are just the lexicographical ordering of the identifiers. When I first starting learning this stuff I thought node1 was the opener or had some larger meaning. But it's just the node with the lower ordered nodeId.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

Also just for edification, node1/node2 in the channel are just the lexicographical ordering of the identifiers. When I first starting learning this stuff I thought node1 was the opener or had some larger meaning. But it's just the node with the lower ordered nodeId.

That's really insightful 💡 , I actually thought that node1 is probably the one who opened the channel.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

K its coming along nicely. Some nits surrounding coding style that we can go over. The biggest issues I see are:

  1. The construction of the adjacency list is only from node1 -> node2. The graph is a symmetric directed graph meaning each channel is two edges: node1->node2 and node2->node1.
  2. This would be facilitated by using the Node's channels property, which is a Map. If it helps you can create a secondary property on Node that returns a tuple containing the [Channel,ChannelSettings] for the Node's channel setting which would aid in point 1.
  3. Finding the min distance should ideally use a heap, but we can get to optimizations later.

For Heap optimization, I found this package related to priority queues we can import that and workaround with it or should I build it from scratch?

@bmancini55

Copy link
Copy Markdown
Member

For Heap optimization, I found this package related to priority queues we can import that and workaround with it or should I build it from scratch?

* https://www.npmjs.com/package/priorityqueuejs

Scratch, we try to avoid external packages where possible.

We'll most likely put it in the Core package but feel free to add it to this project first so we don't have to deal with deps issues while prototyping.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

For Heap optimization, I found this package related to priority queues we can import that and workaround with it or should I build it from scratch?

* https://www.npmjs.com/package/priorityqueuejs

Scratch, we try to avoid external packages where possible.

We'll most likely put it in the Core package but feel free to add it to this project first so we don't have to deal with deps issues while prototyping.

Sure 🤝

Comment threadpackages/graph/lib/graph.ts Outdated
// from dest --> src and return route from src --> dest

// Convert it to corresponding node_id
const str_id = dest.nodeId.toString("hex");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Consider calling this variable dest_str_id or dest_id

@bmancini55bmancini55 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

min-heap looks good with a couple minors. If you want to split that into a separate PR and add tests we can merge it in.

I still need to review dijkstras using the heap.

Comment threadpackages/graph/lib/PriorityQueue.ts Outdated
this._queue.push(value);
let pos = this._queue.length - 1;

while (pos !== 0 && this._compare(this._queue[this._parentOf(pos)], this._queue[pos])) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

micro optimization but cache the call to _parentOf since we call it 3 times. will require refactor to a do/while loop.

Comment threadpackages/graph/lib/PriorityQueue.ts Outdated
}

private _compare(item1: T, item2: T) {
if (this._comparator) {

@bmancini55bmancini55Sep 15, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we can make the _comparator compulsory in the constructor, then we dont' need this check and can drop this whole function.

Comment threadpackages/graph/lib/PriorityQueue.ts Outdated
this._queue = [];
}

public contains(value: T, comparator?: (item: T) => boolean) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we need this operation? If not then lets drop it since its extra code

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

min-heap looks good with a couple minors. If you want to split that into a separate PR and add tests we can merge it in.

I still need to review dijkstras using the heap.

separate PR would make it look neat

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

graph: path finding

4 participants

@Vib-UX@codecov-commenter@bmancini55@Randy808
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Dec 19, 2025. It is now read-only.

pathfinding - #192

Draft
Vib-UX wants to merge 12 commits into
node-lightning:mainfrom
Vib-UX:path_finding
Draft

pathfinding#192
Vib-UX wants to merge 12 commits into
node-lightning:mainfrom
Vib-UX:path_finding

Conversation

@Vib-UX

Copy link
Copy Markdown
Contributor

fixes#190

@Vib-UXVib-UX changed the title Work in ProgresspathfindingAug 21, 2021
@codecov-commenter

codecov-commenter commented Aug 21, 2021

Copy link
Copy Markdown

Codecov Report

Merging #192 (698cb5a) into main (eacb603) will decrease coverage by 0.90%.
The diff coverage is 45.05%.

❗ Current head 698cb5a differs from pull request most recent head 96146da. Consider uploading reports for the commit 96146da to get more accurate results
Impacted file tree graph

@@ Coverage Diff @@## main #192 +/- ##
==========================================
- Coverage 93.37% 92.47% -0.91% 
==========================================
Files 182 183 +1 Lines 4757 4848 +91 Branches 561 581 +20 ==========================================
+ Hits 4442 4483 +41 - Misses 174 214 +40 - Partials 141 151 +10 
Impacted FilesCoverage Δ
packages/graph/lib/PriorityQueue.ts34.00% <34.00%> (ø)
packages/graph/lib/graph.ts73.01% <58.53%> (-26.99%)⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update eacb603...96146da. Read the comment docs.

@bmancini55bmancini55 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

K its coming along nicely. Some nits surrounding coding style that we can go over. The biggest issues I see are:

  1. The construction of the adjacency list is only from node1 -> node2. The graph is a symmetric directed graph meaning each channel is two edges: node1->node2 and node2->node1.

  2. This would be facilitated by using the Node's channels property, which is a Map. If it helps you can create a secondary property on Node that returns a tuple containing the [Channel,ChannelSettings] for the Node's channel setting which would aid in point 1.

  3. Finding the min distance should ideally use a heap, but we can get to optimizations later.

Comment threadpackages/graph/lib/graph.ts Outdated
* Graph represents a
*/
export class Graph {
public nodes_list: string[] = [];

@bmancini55bmancini55Sep 8, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Probably don't need nodes_list. Can easily iterate over a Map type:

constmap=newMap();map.set(1,'a');map.set(2,'b');map.set(3,'c');// iterate over key-values since Map is an iteratorfor(const[key,val]ofmap){console.log(key,val);}// iterate over keys as an iteratorfor(constkeyofmap.keys()){console.log(key);}// iterate over vals as an iteratorfor(constvalofmap.values()){console.log(val);}

Lastly you can covert any iterator into an Array with Array.from:

console.log(Array.from(map));console.log(Array.from(map.keys()));console.log(Array.from(map.values()));

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Sure thing will work with maps (;

Comment threadpackages/graph/lib/graph.ts Outdated
*/
export class Graph {
public nodes_list: string[] = [];
public adjacencyList = {};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same for adjacency list. The Node type includes a Channels Map that contains all of the Channels the Node is a member of.

Comment threadpackages/graph/lib/graph.ts Outdated
const str_id = dest.nodeId.toString("hex");

// Distances will store the base_fee required to traverse from the src
let distances = {},

@bmancini55bmancini55Sep 8, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Language nit: use maps over objects. Even though JS/TS allows object mutation, memory management is most effective when types remain static. As such the Set/Map types are better suited for that type of stuff.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

K its coming along nicely. Some nits surrounding coding style that we can go over. The biggest issues I see are:

  1. The construction of the adjacency list is only from node1 -> node2. The graph is a symmetric directed graph meaning each channel is two edges: node1->node2 and node2->node1.
  2. This would be facilitated by using the Node's channels property, which is a Map. If it helps you can create a secondary property on Node that returns a tuple containing the [Channel,ChannelSettings] for the Node's channel setting which would aid in point 1.
  3. Finding the min distance should ideally use a heap, but we can get to optimizations later.

Yes, I made a mistake it should behave like an undirected graph. Nice Catch 😓

@bmancini55

Copy link
Copy Markdown
Member

Yes, I made a mistake it should behave like an undirected graph. Nice Catch sweat

Conceptually yes, channels are similar to undirected/symmetric directed graph. So both directions or every node pair where a channel exists are theoretically possible and need to be considered. For routing purposes that symmetry may break when:

  1. A channel only has settings on one side (meaning it only received a channel_update from one of the nodes)
  2. A node may disable it's side of the channel in the update message
  3. The min/max settings may prevent an HTLC from being routeable.

@bmancini55

Copy link
Copy Markdown
Member

Also just for edification, node1/node2 in the channel are just the lexicographical ordering of the identifiers. When I first starting learning this stuff I thought node1 was the opener or had some larger meaning. But it's just the node with the lower ordered nodeId.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

Also just for edification, node1/node2 in the channel are just the lexicographical ordering of the identifiers. When I first starting learning this stuff I thought node1 was the opener or had some larger meaning. But it's just the node with the lower ordered nodeId.

That's really insightful 💡 , I actually thought that node1 is probably the one who opened the channel.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

K its coming along nicely. Some nits surrounding coding style that we can go over. The biggest issues I see are:

  1. The construction of the adjacency list is only from node1 -> node2. The graph is a symmetric directed graph meaning each channel is two edges: node1->node2 and node2->node1.
  2. This would be facilitated by using the Node's channels property, which is a Map. If it helps you can create a secondary property on Node that returns a tuple containing the [Channel,ChannelSettings] for the Node's channel setting which would aid in point 1.
  3. Finding the min distance should ideally use a heap, but we can get to optimizations later.

For Heap optimization, I found this package related to priority queues we can import that and workaround with it or should I build it from scratch?

@bmancini55

Copy link
Copy Markdown
Member

For Heap optimization, I found this package related to priority queues we can import that and workaround with it or should I build it from scratch?

* https://www.npmjs.com/package/priorityqueuejs

Scratch, we try to avoid external packages where possible.

We'll most likely put it in the Core package but feel free to add it to this project first so we don't have to deal with deps issues while prototyping.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

For Heap optimization, I found this package related to priority queues we can import that and workaround with it or should I build it from scratch?

* https://www.npmjs.com/package/priorityqueuejs

Scratch, we try to avoid external packages where possible.

We'll most likely put it in the Core package but feel free to add it to this project first so we don't have to deal with deps issues while prototyping.

Sure 🤝

Comment threadpackages/graph/lib/graph.ts Outdated
// from dest --> src and return route from src --> dest

// Convert it to corresponding node_id
const str_id = dest.nodeId.toString("hex");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Consider calling this variable dest_str_id or dest_id

@bmancini55bmancini55 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

min-heap looks good with a couple minors. If you want to split that into a separate PR and add tests we can merge it in.

I still need to review dijkstras using the heap.

Comment threadpackages/graph/lib/PriorityQueue.ts Outdated
this._queue.push(value);
let pos = this._queue.length - 1;

while (pos !== 0 && this._compare(this._queue[this._parentOf(pos)], this._queue[pos])) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

micro optimization but cache the call to _parentOf since we call it 3 times. will require refactor to a do/while loop.

Comment threadpackages/graph/lib/PriorityQueue.ts Outdated
}

private _compare(item1: T, item2: T) {
if (this._comparator) {

@bmancini55bmancini55Sep 15, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we can make the _comparator compulsory in the constructor, then we dont' need this check and can drop this whole function.

Comment threadpackages/graph/lib/PriorityQueue.ts Outdated
this._queue = [];
}

public contains(value: T, comparator?: (item: T) => boolean) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we need this operation? If not then lets drop it since its extra code

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

min-heap looks good with a couple minors. If you want to split that into a separate PR and add tests we can merge it in.

I still need to review dijkstras using the heap.

separate PR would make it look neat

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

graph: path finding

4 participants

@Vib-UX@codecov-commenter@bmancini55@Randy808
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Dec 19, 2025. It is now read-only.

pathfinding - #192

Draft
Vib-UX wants to merge 12 commits into
node-lightning:mainfrom
Vib-UX:path_finding
Draft

pathfinding#192
Vib-UX wants to merge 12 commits into
node-lightning:mainfrom
Vib-UX:path_finding

Conversation

@Vib-UX

Copy link
Copy Markdown
Contributor

fixes#190

@Vib-UXVib-UX changed the title Work in ProgresspathfindingAug 21, 2021
@codecov-commenter

codecov-commenter commented Aug 21, 2021

Copy link
Copy Markdown

Codecov Report

Merging #192 (698cb5a) into main (eacb603) will decrease coverage by 0.90%.
The diff coverage is 45.05%.

❗ Current head 698cb5a differs from pull request most recent head 96146da. Consider uploading reports for the commit 96146da to get more accurate results
Impacted file tree graph

@@ Coverage Diff @@## main #192 +/- ##
==========================================
- Coverage 93.37% 92.47% -0.91% 
==========================================
Files 182 183 +1 Lines 4757 4848 +91 Branches 561 581 +20 ==========================================
+ Hits 4442 4483 +41 - Misses 174 214 +40 - Partials 141 151 +10 
Impacted FilesCoverage Δ
packages/graph/lib/PriorityQueue.ts34.00% <34.00%> (ø)
packages/graph/lib/graph.ts73.01% <58.53%> (-26.99%)⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update eacb603...96146da. Read the comment docs.

@bmancini55bmancini55 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

K its coming along nicely. Some nits surrounding coding style that we can go over. The biggest issues I see are:

  1. The construction of the adjacency list is only from node1 -> node2. The graph is a symmetric directed graph meaning each channel is two edges: node1->node2 and node2->node1.

  2. This would be facilitated by using the Node's channels property, which is a Map. If it helps you can create a secondary property on Node that returns a tuple containing the [Channel,ChannelSettings] for the Node's channel setting which would aid in point 1.

  3. Finding the min distance should ideally use a heap, but we can get to optimizations later.

Comment threadpackages/graph/lib/graph.ts Outdated
* Graph represents a
*/
export class Graph {
public nodes_list: string[] = [];

@bmancini55bmancini55Sep 8, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Probably don't need nodes_list. Can easily iterate over a Map type:

constmap=newMap();map.set(1,'a');map.set(2,'b');map.set(3,'c');// iterate over key-values since Map is an iteratorfor(const[key,val]ofmap){console.log(key,val);}// iterate over keys as an iteratorfor(constkeyofmap.keys()){console.log(key);}// iterate over vals as an iteratorfor(constvalofmap.values()){console.log(val);}

Lastly you can covert any iterator into an Array with Array.from:

console.log(Array.from(map));console.log(Array.from(map.keys()));console.log(Array.from(map.values()));

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Sure thing will work with maps (;

Comment threadpackages/graph/lib/graph.ts Outdated
*/
export class Graph {
public nodes_list: string[] = [];
public adjacencyList = {};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same for adjacency list. The Node type includes a Channels Map that contains all of the Channels the Node is a member of.

Comment threadpackages/graph/lib/graph.ts Outdated
const str_id = dest.nodeId.toString("hex");

// Distances will store the base_fee required to traverse from the src
let distances = {},

@bmancini55bmancini55Sep 8, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Language nit: use maps over objects. Even though JS/TS allows object mutation, memory management is most effective when types remain static. As such the Set/Map types are better suited for that type of stuff.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

K its coming along nicely. Some nits surrounding coding style that we can go over. The biggest issues I see are:

  1. The construction of the adjacency list is only from node1 -> node2. The graph is a symmetric directed graph meaning each channel is two edges: node1->node2 and node2->node1.
  2. This would be facilitated by using the Node's channels property, which is a Map. If it helps you can create a secondary property on Node that returns a tuple containing the [Channel,ChannelSettings] for the Node's channel setting which would aid in point 1.
  3. Finding the min distance should ideally use a heap, but we can get to optimizations later.

Yes, I made a mistake it should behave like an undirected graph. Nice Catch 😓

@bmancini55

Copy link
Copy Markdown
Member

Yes, I made a mistake it should behave like an undirected graph. Nice Catch sweat

Conceptually yes, channels are similar to undirected/symmetric directed graph. So both directions or every node pair where a channel exists are theoretically possible and need to be considered. For routing purposes that symmetry may break when:

  1. A channel only has settings on one side (meaning it only received a channel_update from one of the nodes)
  2. A node may disable it's side of the channel in the update message
  3. The min/max settings may prevent an HTLC from being routeable.

@bmancini55

Copy link
Copy Markdown
Member

Also just for edification, node1/node2 in the channel are just the lexicographical ordering of the identifiers. When I first starting learning this stuff I thought node1 was the opener or had some larger meaning. But it's just the node with the lower ordered nodeId.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

Also just for edification, node1/node2 in the channel are just the lexicographical ordering of the identifiers. When I first starting learning this stuff I thought node1 was the opener or had some larger meaning. But it's just the node with the lower ordered nodeId.

That's really insightful 💡 , I actually thought that node1 is probably the one who opened the channel.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

K its coming along nicely. Some nits surrounding coding style that we can go over. The biggest issues I see are:

  1. The construction of the adjacency list is only from node1 -> node2. The graph is a symmetric directed graph meaning each channel is two edges: node1->node2 and node2->node1.
  2. This would be facilitated by using the Node's channels property, which is a Map. If it helps you can create a secondary property on Node that returns a tuple containing the [Channel,ChannelSettings] for the Node's channel setting which would aid in point 1.
  3. Finding the min distance should ideally use a heap, but we can get to optimizations later.

For Heap optimization, I found this package related to priority queues we can import that and workaround with it or should I build it from scratch?

@bmancini55

Copy link
Copy Markdown
Member

For Heap optimization, I found this package related to priority queues we can import that and workaround with it or should I build it from scratch?

* https://www.npmjs.com/package/priorityqueuejs

Scratch, we try to avoid external packages where possible.

We'll most likely put it in the Core package but feel free to add it to this project first so we don't have to deal with deps issues while prototyping.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

For Heap optimization, I found this package related to priority queues we can import that and workaround with it or should I build it from scratch?

* https://www.npmjs.com/package/priorityqueuejs

Scratch, we try to avoid external packages where possible.

We'll most likely put it in the Core package but feel free to add it to this project first so we don't have to deal with deps issues while prototyping.

Sure 🤝

Comment threadpackages/graph/lib/graph.ts Outdated
// from dest --> src and return route from src --> dest

// Convert it to corresponding node_id
const str_id = dest.nodeId.toString("hex");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Consider calling this variable dest_str_id or dest_id

@bmancini55bmancini55 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

min-heap looks good with a couple minors. If you want to split that into a separate PR and add tests we can merge it in.

I still need to review dijkstras using the heap.

Comment threadpackages/graph/lib/PriorityQueue.ts Outdated
this._queue.push(value);
let pos = this._queue.length - 1;

while (pos !== 0 && this._compare(this._queue[this._parentOf(pos)], this._queue[pos])) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

micro optimization but cache the call to _parentOf since we call it 3 times. will require refactor to a do/while loop.

Comment threadpackages/graph/lib/PriorityQueue.ts Outdated
}

private _compare(item1: T, item2: T) {
if (this._comparator) {

@bmancini55bmancini55Sep 15, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we can make the _comparator compulsory in the constructor, then we dont' need this check and can drop this whole function.

Comment threadpackages/graph/lib/PriorityQueue.ts Outdated
this._queue = [];
}

public contains(value: T, comparator?: (item: T) => boolean) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we need this operation? If not then lets drop it since its extra code

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

min-heap looks good with a couple minors. If you want to split that into a separate PR and add tests we can merge it in.

I still need to review dijkstras using the heap.

separate PR would make it look neat

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

graph: path finding

4 participants

@Vib-UX@codecov-commenter@bmancini55@Randy808
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
This repository was archived by the owner on Dec 19, 2025. It is now read-only.

pathfinding - #192

Draft
Vib-UX wants to merge 12 commits into
node-lightning:mainfrom
Vib-UX:path_finding
Draft

pathfinding#192
Vib-UX wants to merge 12 commits into
node-lightning:mainfrom
Vib-UX:path_finding

Conversation

@Vib-UX

Copy link
Copy Markdown
Contributor

fixes#190

@Vib-UXVib-UX changed the title Work in ProgresspathfindingAug 21, 2021
@codecov-commenter

codecov-commenter commented Aug 21, 2021

Copy link
Copy Markdown

Codecov Report

Merging #192 (698cb5a) into main (eacb603) will decrease coverage by 0.90%.
The diff coverage is 45.05%.

❗ Current head 698cb5a differs from pull request most recent head 96146da. Consider uploading reports for the commit 96146da to get more accurate results
Impacted file tree graph

@@ Coverage Diff @@## main #192 +/- ##
==========================================
- Coverage 93.37% 92.47% -0.91% 
==========================================
Files 182 183 +1 Lines 4757 4848 +91 Branches 561 581 +20 ==========================================
+ Hits 4442 4483 +41 - Misses 174 214 +40 - Partials 141 151 +10 
Impacted FilesCoverage Δ
packages/graph/lib/PriorityQueue.ts34.00% <34.00%> (ø)
packages/graph/lib/graph.ts73.01% <58.53%> (-26.99%)⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update eacb603...96146da. Read the comment docs.

@bmancini55bmancini55 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

K its coming along nicely. Some nits surrounding coding style that we can go over. The biggest issues I see are:

  1. The construction of the adjacency list is only from node1 -> node2. The graph is a symmetric directed graph meaning each channel is two edges: node1->node2 and node2->node1.

  2. This would be facilitated by using the Node's channels property, which is a Map. If it helps you can create a secondary property on Node that returns a tuple containing the [Channel,ChannelSettings] for the Node's channel setting which would aid in point 1.

  3. Finding the min distance should ideally use a heap, but we can get to optimizations later.

Comment threadpackages/graph/lib/graph.ts Outdated
* Graph represents a
*/
export class Graph {
public nodes_list: string[] = [];

@bmancini55bmancini55Sep 8, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Probably don't need nodes_list. Can easily iterate over a Map type:

constmap=newMap();map.set(1,'a');map.set(2,'b');map.set(3,'c');// iterate over key-values since Map is an iteratorfor(const[key,val]ofmap){console.log(key,val);}// iterate over keys as an iteratorfor(constkeyofmap.keys()){console.log(key);}// iterate over vals as an iteratorfor(constvalofmap.values()){console.log(val);}

Lastly you can covert any iterator into an Array with Array.from:

console.log(Array.from(map));console.log(Array.from(map.keys()));console.log(Array.from(map.values()));

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Sure thing will work with maps (;

Comment threadpackages/graph/lib/graph.ts Outdated
*/
export class Graph {
public nodes_list: string[] = [];
public adjacencyList = {};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same for adjacency list. The Node type includes a Channels Map that contains all of the Channels the Node is a member of.

Comment threadpackages/graph/lib/graph.ts Outdated
const str_id = dest.nodeId.toString("hex");

// Distances will store the base_fee required to traverse from the src
let distances = {},

@bmancini55bmancini55Sep 8, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Language nit: use maps over objects. Even though JS/TS allows object mutation, memory management is most effective when types remain static. As such the Set/Map types are better suited for that type of stuff.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

K its coming along nicely. Some nits surrounding coding style that we can go over. The biggest issues I see are:

  1. The construction of the adjacency list is only from node1 -> node2. The graph is a symmetric directed graph meaning each channel is two edges: node1->node2 and node2->node1.
  2. This would be facilitated by using the Node's channels property, which is a Map. If it helps you can create a secondary property on Node that returns a tuple containing the [Channel,ChannelSettings] for the Node's channel setting which would aid in point 1.
  3. Finding the min distance should ideally use a heap, but we can get to optimizations later.

Yes, I made a mistake it should behave like an undirected graph. Nice Catch 😓

@bmancini55

Copy link
Copy Markdown
Member

Yes, I made a mistake it should behave like an undirected graph. Nice Catch sweat

Conceptually yes, channels are similar to undirected/symmetric directed graph. So both directions or every node pair where a channel exists are theoretically possible and need to be considered. For routing purposes that symmetry may break when:

  1. A channel only has settings on one side (meaning it only received a channel_update from one of the nodes)
  2. A node may disable it's side of the channel in the update message
  3. The min/max settings may prevent an HTLC from being routeable.

@bmancini55

Copy link
Copy Markdown
Member

Also just for edification, node1/node2 in the channel are just the lexicographical ordering of the identifiers. When I first starting learning this stuff I thought node1 was the opener or had some larger meaning. But it's just the node with the lower ordered nodeId.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

Also just for edification, node1/node2 in the channel are just the lexicographical ordering of the identifiers. When I first starting learning this stuff I thought node1 was the opener or had some larger meaning. But it's just the node with the lower ordered nodeId.

That's really insightful 💡 , I actually thought that node1 is probably the one who opened the channel.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

K its coming along nicely. Some nits surrounding coding style that we can go over. The biggest issues I see are:

  1. The construction of the adjacency list is only from node1 -> node2. The graph is a symmetric directed graph meaning each channel is two edges: node1->node2 and node2->node1.
  2. This would be facilitated by using the Node's channels property, which is a Map. If it helps you can create a secondary property on Node that returns a tuple containing the [Channel,ChannelSettings] for the Node's channel setting which would aid in point 1.
  3. Finding the min distance should ideally use a heap, but we can get to optimizations later.

For Heap optimization, I found this package related to priority queues we can import that and workaround with it or should I build it from scratch?

@bmancini55

Copy link
Copy Markdown
Member

For Heap optimization, I found this package related to priority queues we can import that and workaround with it or should I build it from scratch?

* https://www.npmjs.com/package/priorityqueuejs

Scratch, we try to avoid external packages where possible.

We'll most likely put it in the Core package but feel free to add it to this project first so we don't have to deal with deps issues while prototyping.

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

For Heap optimization, I found this package related to priority queues we can import that and workaround with it or should I build it from scratch?

* https://www.npmjs.com/package/priorityqueuejs

Scratch, we try to avoid external packages where possible.

We'll most likely put it in the Core package but feel free to add it to this project first so we don't have to deal with deps issues while prototyping.

Sure 🤝

Comment threadpackages/graph/lib/graph.ts Outdated
// from dest --> src and return route from src --> dest

// Convert it to corresponding node_id
const str_id = dest.nodeId.toString("hex");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Consider calling this variable dest_str_id or dest_id

@bmancini55bmancini55 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

min-heap looks good with a couple minors. If you want to split that into a separate PR and add tests we can merge it in.

I still need to review dijkstras using the heap.

Comment threadpackages/graph/lib/PriorityQueue.ts Outdated
this._queue.push(value);
let pos = this._queue.length - 1;

while (pos !== 0 && this._compare(this._queue[this._parentOf(pos)], this._queue[pos])) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

micro optimization but cache the call to _parentOf since we call it 3 times. will require refactor to a do/while loop.

Comment threadpackages/graph/lib/PriorityQueue.ts Outdated
}

private _compare(item1: T, item2: T) {
if (this._comparator) {

@bmancini55bmancini55Sep 15, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we can make the _comparator compulsory in the constructor, then we dont' need this check and can drop this whole function.

Comment threadpackages/graph/lib/PriorityQueue.ts Outdated
this._queue = [];
}

public contains(value: T, comparator?: (item: T) => boolean) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we need this operation? If not then lets drop it since its extra code

@Vib-UX

Copy link
Copy Markdown
ContributorAuthor

min-heap looks good with a couple minors. If you want to split that into a separate PR and add tests we can merge it in.

I still need to review dijkstras using the heap.

separate PR would make it look neat

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

graph: path finding

4 participants

@Vib-UX@codecov-commenter@bmancini55@Randy808