Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions lib/announcer.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ const Persistent = require('./persistent')
const { COMMANDS } = require('./constants')

const MIN_ACTIVE = 3
const MAX_ANNOUNCE_RELAYS = 3
const RTT_CANDIDATE_WINDOW = 8

module.exports = class Announcer {
constructor(dht, keyPair, target, opts = {}) {
Expand Down Expand Up @@ -296,8 +298,12 @@ function resolved(ps) {
}

function pickBest(replies) {
// TODO: pick the ones closest to us RTT wise
return replies.slice(0, 3)
return replies
.slice(0, RTT_CANDIDATE_WINDOW)
.map((reply, index) => ({ reply, index }))
.sort((a, b) => a.reply.rtt - b.reply.rtt || a.index - b.index)
.slice(0, MAX_ANNOUNCE_RELAYS)
.map(({ reply }) => reply)
}

function noop() {}
51 changes: 51 additions & 0 deletions test/announces.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const messages = require('../lib/messages.js')
const { swarm, toArray } = require('./helpers')
const DHT = require('../')
const HyperDHT = require('../')
const Announcer = require('../lib/announcer')
const { COMMANDS } = require('../lib/constants.js')

test('server listen and findPeer', async function (t) {
Expand Down Expand Up @@ -193,6 +194,56 @@ test('server announces relay addrs', async function (t) {
}
})

test('announcer prefers lower rtt among close-enough replies', async function (t) {
const keyPair = DHT.keyPair()
const target = DHT.hash(Buffer.from('rtt-ranked-announces'))
const rtts = [80, 70, 20, 20, 40, 20, 60, 10, 1, 2]
const replies = rtts.map((rtt, i) => {
return {
token: b4a.alloc(32, i),
rtt,
from: {
id: b4a.alloc(32, i + 1),
host: '127.0.0.1',
port: 10000 + i
},
to: {
host: '127.0.0.1',
port: 20000 + i
}
}
})
const announced = []
const dht = {
firewalled: true,
destroyed: false,
findPeer() {
return {
closestReplies: replies,
closestNodes: replies.map((reply) => reply.from),
finished: () => Promise.resolve()
}
},
request(req, to) {
t.is(req.command, COMMANDS.ANNOUNCE)
announced.push(to.port)
return Promise.resolve({ error: 0 })
}
}
const announcer = new Announcer(dht, keyPair, target, {
signAnnounce: () => b4a.alloc(64)
})

await announcer._update()

t.alike(
announced,
[10007, 10002, 10003],
'announced to lowest-rtt replies and kept reply order for equal rtt'
)
t.absent(announced.includes(10008), 'ignored lower-rtt reply outside the candidate window')
})

test('connect when we relay ourself', async function (t) {
const testnet = await swarm(t)

Expand Down
Loading