Skip to content

Commit

Permalink
Add peer.remoteContiguousLength
Browse files Browse the repository at this point in the history
  • Loading branch information
LuKks committed Jul 3, 2023
1 parent ef96761 commit ab6734c
Show file tree
Hide file tree
Showing 2 changed files with 193 additions and 0 deletions.
6 changes: 6 additions & 0 deletions lib/replicator.js
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ class Peer {

this.remoteFork = 0
this.remoteLength = 0
this.remoteContiguousLength = 0
this.remoteCanUpgrade = false
this.remoteUploading = true
this.remoteDownloading = true
Expand Down Expand Up @@ -679,6 +680,11 @@ class Peer {
}

onrange ({ drop, start, length }) {
// console.log(this.stream.publicKey.slice(0, 3).toString('hex'), this.stream.remotePublicKey.slice(0, 3).toString('hex'), this.$id, 'onrange', { drop, start, length })

if (start === 0) this.remoteContiguousLength = length
if (drop) this.remoteContiguousLength = Math.min(this.remoteContiguousLength, start)

const has = drop === false

this.remoteBitfield.setRange(start, length, has)
Expand Down
187 changes: 187 additions & 0 deletions test/remote-length.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
const test = require('brittle')
const { create, replicate } = require('./helpers')

test('peer with partial remote contig length', async function (t) {
const core = await create()
const a = await create(core.key)
const b = await create(core.key)

await core.append(['a', 'b', 'c', 'd', 'e', 'f'])

replicate(core, a, t)
replicate(a, b, t)

// "A" has all the blocks
await a.download({ start: 0, end: core.length }).done()
t.is(a.contiguousLength, core.length)

// "B" gets them blocks from "A"
await b.get(0)
await b.get(1)
await b.get(2)
// await b.get(3)
// await b.get(4)
// await b.get(5)

await new Promise(resolve => setTimeout(resolve, 100))

// For example, "A" wants to know if "B" is finished syncing
const peer = a.replicator.peers.find(peer => peer.remotePublicKey.equals(b.replicator.peers[0].stream.publicKey)) // (unsure if this peers[0] is precise)
console.log('B remote contig length', peer.remoteContiguousLength) // => 1
console.log('B local contig length ', b.contiguousLength) // => 3
t.is(b.contiguousLength, peer.remoteContiguousLength)

// One of them always shows "1" which is "B"
console.log(a.replicator.peers.map(peer => peer.remoteContiguousLength))
console.log(b.replicator.peers.map(peer => peer.remoteContiguousLength))
})

test('peer with complete remote contig length', async function (t) {
const core = await create()
const a = await create(core.key)
const b = await create(core.key)

await core.append(['a', 'b', 'c', 'd', 'e', 'f'])

replicate(core, a, t)
replicate(a, b, t)

await a.download({ start: 0, end: core.length }).done()
t.is(a.contiguousLength, core.length)

await b.get(0)
await b.get(1)
await b.get(2)
await b.get(3)
await b.get(4)
await b.get(5)

await new Promise(resolve => setTimeout(resolve, 100))

const peer = a.replicator.peers.find(peer => peer.remotePublicKey.equals(b.replicator.peers[0].stream.publicKey))
t.is(b.contiguousLength, peer.remoteContiguousLength)
})

/* test.skip('basic replication', async function (t) {
const core = await create()
const a = await create(core.key)
const b = await create(core.key)
const c = await create(core.key)
await core.append(['a', 'b', 'c', 'd', 'e', 'f'])
// core.core.$id = 'w'
a.core.$id = 'a'
// b.core.$id = 'b'
// c.core.$id = 'c'
const ra = replicate(core, a, t)
const ab = replicate(a, b, t)
const bc = replicate(b, c, t)
console.log(ra[0].publicKey.slice(0, 3).toString('hex'), '=> core')
console.log(ra[1].publicKey.slice(0, 3).toString('hex'), '=> a')
console.log()
console.log(ab[0].publicKey.slice(0, 3).toString('hex'), '=> a')
console.log(ab[1].publicKey.slice(0, 3).toString('hex'), '=> b')
console.log()
console.log(bc[0].publicKey.slice(0, 3).toString('hex'), '=> b')
console.log(bc[1].publicKey.slice(0, 3).toString('hex'), '=> c')
console.log()
await a.update({ wait: true })
await b.update({ wait: true })
await c.update({ wait: true })
const peer = a.replicator.peers.find(peer => peer.remotePublicKey.equals(b.replicator.peers[0].stream.publicKey))
peer.$id = 'b'
// "A" has all the blocks
await a.download({ start: 0, end: core.length }).done()
// "B" is getting them from "A"
await b.get(1)
await b.get(2)
await b.get(0)
await new Promise(resolve => setTimeout(resolve, 100))
console.log('writer length', core.contiguousLength, core.length) // 5 / 5 ()
console.log('a core length', a.contiguousLength, a.length) // 5 / 5 ()
console.log('b core length', b.contiguousLength, b.length) // 3 / 5 ()
console.log('c core length', c.contiguousLength, c.length) // 0 / 5 ()
// console.log(core.replicator.peers[0])
// From "a" perspective, this is "b" peer which it should have a remote contig length of 3
// console.log(a.replicator.peers[0])
await new Promise(resolve => setTimeout(resolve, 100))
})
test.skip('basic replication', async function (t) {
const core = await create()
const a = await create(core.key)
const b = await create(core.key)
const c = await create(core.key)
core.core.$id = 'w'
a.core.$id = 'a'
b.core.$id = 'b'
c.core.$id = 'c'
const ra = replicate(core, a, t)
const ab = replicate(a, b, t)
const bc = replicate(b, c, t)
await a.update({ wait: true })
await b.update({ wait: true })
// const peer = a.replicator.peers.find(peer => peer.remotePublicKey.equals(b.replicator.peers[0].stream.publicKey)) // Or just peers[1]
// peer.$id = 'b'
const peer = b.replicator.peers.find(peer => peer.remotePublicKey.equals(c.replicator.peers[0].stream.publicKey)) // Or just peers[1]
peer.$id = 'c'
await core.append('a')
await a.get(0)
await b.get(0)
await core.append('b')
await a.get(1)
await b.get(1)
await core.append('c')
await a.get(2)
await b.get(2)
await core.append('d')
await a.get(3)
await b.get(3)
await c.get(3)
await core.append('e')
await a.get(4)
await core.append('f')
await a.get(5)
// await c.get(1)
await c.get(0)
await new Promise(resolve => setTimeout(resolve, 100))
console.log('writer length', core.contiguousLength, core.length) // 5 / 5 ()
console.log('a core length', a.contiguousLength, a.length) // 5 / 5 ()
console.log('b core length', b.contiguousLength, b.length) // 3 / 5 ()
console.log('c core length', c.contiguousLength, c.length) // 0 / 5 ()
// console.log(core.replicator.peers[0])
// From "a" perspective, this is "b" peer which it should have a remote contig length of 3
// console.log(a.replicator.peers[0])
await new Promise(resolve => setTimeout(resolve, 100))
}) */

0 comments on commit ab6734c

Please sign in to comment.