Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: prioritize short paths during findBestHop #54

Merged
merged 2 commits into from
Jul 27, 2017

Conversation

sentientwaffle
Copy link
Contributor

* `findBestHopFor{Source,Destination}Amount()` should prioritize routes based on shortest `maxPathLength()`.
* Fix `maxPathLength()`: if `nextLedger` is not equal to `destinationLedger`, increment the path length.
* Possible fix for interledgerjs/ilp-connector#382. When two paths score the same, return the first in the Map.
@codecov-io
Copy link

codecov-io commented Jul 25, 2017

Codecov Report

Merging #54 into master will increase coverage by 0.02%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #54      +/-   ##
==========================================
+ Coverage   96.26%   96.28%   +0.02%     
==========================================
  Files           5        5              
  Lines         535      539       +4     
  Branches      111      120       +9     
==========================================
+ Hits          515      519       +4     
  Misses         20       20
Impacted Files Coverage Δ
src/lib/route.js 95.04% <100%> (ø) ⬆️
src/lib/routing-table.js 98.57% <100%> (+0.08%) ⬆️

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 c2b5eea...7bb1ebd. Read the comment docs.

if (currentHop.pathLength < otherHop.pathLength) return currentHop
if (otherHop.pathLength < currentHop.pathLength) return otherHop
if (otherHop.value !== undefined) {
return otherHop.value.gt(currentHop.value) ? otherHop : currentHop
Copy link
Contributor

Choose a reason for hiding this comment

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

this will throw an error if currentHop.value is undefined

return otherHop.value.gt(currentHop.value) ? otherHop : currentHop
}
if (otherHop.cost !== undefined) {
return otherHop.cost.lt(currentHop.cost) ? otherHop : currentHop
Copy link
Contributor

Choose a reason for hiding this comment

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

will throw an error if currentHop.cost is undefined

@@ -76,6 +77,16 @@ describe('RoutingTable', function () {
const table = new RoutingTable()
assert.strictEqual(table.findBestHopForSourceAmount(ledgerB, 10), undefined)
})

it('prefers short routes', function () {
Copy link
Contributor

Choose a reason for hiding this comment

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

can you have a test case for each of the comparisons in getBetterHop?

@@ -66,7 +66,7 @@ class Route {
// are not included in this.paths, so for instance a path:
// * localLedger -> trustLine -> destinationLedger has this.paths === [ [] ], and path length 2
// * localLedger -> trustLine -> anotherTrustLine -> destinationLedger has this.paths === [ ['anotherTrustLine'] ] and path length 3
return max + 2
return this.nextLedger === this.destinationLedger ? max + 2 : max + 3
Copy link
Contributor

Choose a reason for hiding this comment

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

This means we count a route trustLine -> localLedger as length 2, so counting the number of ledgers involved. I originally thought of it as the number of connections, so this.nextLedger === this.destinationLedger ? max + 1 : max + 2 but I guess your way of counting makes (more) sense.

bestRoute = route
}
bestHop = getBetterHop(bestHop, {
nextHop,
Copy link
Contributor

Choose a reason for hiding this comment

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

getBetterHop takes two arguments, function getBetterHop (currentHop, otherHop).
Here, you pass bestHop as the currentHop, and { nextHop, ... } as the otherHop.
Does that mean (if both arguments of getBetterHop are of the same type) that bestHop also has a field nextHop? nextHop comes from routes.forEach((route, nextHop) => {, so it's a route.
Now I no longer remember what data type a 'hop' is. Is it a ledger name string? Or a Route object?

Copy link
Contributor

Choose a reason for hiding this comment

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

Do all of currentHop, otherHop, nextHop and bestHop have the same data type? If not, then that's confusing.

})

if (bestHop) {
debug('findBestHopForSourceAmount to ' + destination + ' for ' + sourceAmount + ' found route through ' + bestHop)
debug('findBestHopForSourceAmount to ' + destination + ' for ' + sourceAmount + ' found route through ' + bestHop.nextHop)
Copy link
Contributor

Choose a reason for hiding this comment

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

See above, bestHop.nextHop - I don't know what that means, the next Hop of the best Hop. Which one is the Route object here and which one is the peer ledger name String?

Copy link
Contributor

@michielbdejong michielbdejong left a comment

Choose a reason for hiding this comment

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

With these changes, there is now confusion about what a Hop is. Maybe the best example is this line where
the return value of
findBestHopForDestinationAmount gets a field bestHop (in itself that's ok, that function just returns a bit of extra info apart from the bestHop that was asked for), but the value that's used for it is not actually the local bestHop variable; it is set to bestHop.nextHop. What's the difference between a Hop and the nextHop of that Hop?

* Rename "bestHop" to "bestPath", since "hop" generally refers to a connector address.
* Add tests for `getBetterPath()`.
* Don't throw when `currentHop.{value,cost}` is `undefined`.
@sentientwaffle sentientwaffle merged commit 55ffc58 into master Jul 27, 2017
@sentientwaffle sentientwaffle deleted the dj-find-shortest-path branch July 27, 2017 20:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants