Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
28cdd5e
Move `core.bitfield` to `core.replicator.localBitfield`
lejeunerenard Sep 24, 2025
0f5f6ba
Move skipBitfield to replicator
lejeunerenard Sep 24, 2025
95d0999
Update bitfield & contiguousLength in `replicator.onhave`
lejeunerenard Sep 24, 2025
c4cd05c
Rely on replicator to update in memory bitfield in `_verifyShared()`
lejeunerenard Sep 25, 2025
a039a17
Remove vestigial `flushed` arg from `state._updateBitfield()`
lejeunerenard Sep 25, 2025
96248b4
Rely on replicator to update mem bitfield while copying prologue
lejeunerenard Sep 25, 2025
5713481
Update `lib/audit.js` to use `replicator.localBitfield`
lejeunerenard Sep 25, 2025
9052e51
Use `BitInterlude`'s ranges when broadcasting to peers in `_verifySha…
lejeunerenard Sep 25, 2025
90f49f1
add prettier
mafintosh Oct 7, 2025
debb1e6
(Re)Apply prettier formatting
lejeunerenard Oct 7, 2025
3378a5e
Back bitfield w/ storage instead of memory
lejeunerenard Sep 29, 2025
96462f3
Reapply formatting
lejeunerenard Oct 7, 2025
74061d8
Add missing await in replicate test for bitfield
lejeunerenard Oct 7, 2025
2500e2d
Await `_resetMissingBlock` & `_unmarkInflight` where async available
lejeunerenard Oct 8, 2025
bee8c2c
Await `replicator._updateNonPrimary()` to ensure read is at single state
lejeunerenard Oct 8, 2025
03be77c
Add missing awaits in bitfield test
lejeunerenard Oct 8, 2025
258080f
Add internal & external locks for bitfield operations
lejeunerenard Oct 8, 2025
177ff53
Apply external locks to `peer.ondata`
lejeunerenard Oct 8, 2025
a9186a9
Add missing `scope-lock` dependency
lejeunerenard Oct 8, 2025
c3b5bff
Update formatting w/ prettier
lejeunerenard Oct 8, 2025
636d43b
Await _updateCanUpgradeAndSync() for timing `sync` sent from `ondata`
lejeunerenard Oct 13, 2025
7520bfa
Add `bitfield.getMaybe()` & `bitfield.ensurePage()` for sync access
lejeunerenard Oct 13, 2025
afa41fb
Add bitfield lock for `_onwant` call
lejeunerenard Oct 13, 2025
2aa10a2
Await all `replicator.onupgrade()` calls
lejeunerenard Oct 13, 2025
7eea070
Convert `_setManifest` to async & await where called
lejeunerenard Oct 13, 2025
b4d64d0
Fix linting in `test/replicate.js`
lejeunerenard Oct 13, 2025
68a1b78
Lint `lib/replicator.js`
lejeunerenard Oct 13, 2025
1381aa8
Lock on bitfield in `onsync` to ensure remote bitfield is updated
lejeunerenard Oct 14, 2025
ff690f8
Add `.remoteFullyOpening` for guarding closing peer
lejeunerenard Oct 15, 2025
4d15a74
Merge branch 'main' into refact-bitfield-to-replicator
lejeunerenard Oct 16, 2025
5d01e1e
Remove completed TODO comment
lejeunerenard Oct 16, 2025
d08cba7
Lint `lib/replicator.js`
lejeunerenard Oct 16, 2025
dcdcea2
Increase timeout for `big download range` test to account for bitfield
lejeunerenard Oct 16, 2025
6e33751
Expand timeout time for `big download range` to 2 min max
lejeunerenard Oct 16, 2025
4a9e5e0
Add missing await for `_resolveBlocksLocally()`
lejeunerenard Oct 16, 2025
422ca31
Prevent undefined ranges reqs in `_updateNonPrimary()`
lejeunerenard Oct 16, 2025
8b9fb0e
Wait for localBitfield locks to flush before closing session/core
lejeunerenard Oct 22, 2025
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,7 @@ class Hypercore extends EventEmitter {
this.core.replicator.findingPeers -= this._findingPeers
this.core.replicator.clearRequests(this.activeRequests, error)
this.core.replicator.updateActivity(this._active ? -1 : 0)
await this.core.replicator.localBitfield.flush()

this._findingPeers = 0

Expand Down Expand Up @@ -818,9 +819,9 @@ class Hypercore extends EventEmitter {
throw ASSERTION('has range is invalid', this.discoveryKey)

if (this.state.isDefault()) {
if (end === start + 1) return this.core.bitfield.get(start)
if (end === start + 1) return this.core.replicator.localBitfield.get(start)

const i = this.core.bitfield.firstUnset(start)
const i = await this.core.replicator.localBitfield.firstUnset(start)
return i === -1 || i >= end
}

Expand Down Expand Up @@ -919,7 +920,7 @@ class Hypercore extends EventEmitter {

// lets check the bitfield to see if we got it during the above async calls
// this is the last resort before replication, so always safe.
if (this.core.bitfield.get(index)) {
if (await this.core.replicator.localBitfield.get(index)) {
const coreBlock = await readBlock(this.state.storage.read(), index)
// TODO: this should not be needed, only needed atm in case we are doing a moveTo during this (we should fix)
if (coreBlock !== null) return coreBlock
Expand Down
17 changes: 9 additions & 8 deletions lib/audit.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ module.exports = async function auditCore(
let tx = null

for await (const block of core.state.storage.createBlockStream()) {
if (!core.bitfield.get(block.index)) {
if (!(await core.replicator.localBitfield.get(block.index))) {
if (!tx && !stats.corrupt) tx = core.state.storage.write()
tx.deleteBlock(block.index)
stats.droppedBlocks++
Expand Down Expand Up @@ -107,7 +107,7 @@ module.exports = async function auditCore(
if (bitfield) {
let tx = null

for (const index of allBits(core.bitfield)) {
for await (const index of allBits(core.replicator.localBitfield)) {
const rx = core.state.storage.read()
const blockPromise = rx.getBlock(index)

Expand All @@ -120,10 +120,11 @@ module.exports = async function auditCore(

if (!tx && !stats.corrupt) tx = core.state.storage.write()

core.bitfield.set(index, false)
await core.replicator.localBitfield.set(index, false)

const page = core.bitfield.getBitfield(index)
if (page.bitfield) tx.putBitfieldPage(page.index, page.bitfield)
const page = core.replicator.localBitfield.getBitfield(index)
const bitfield = await page.getBuffer()
if (bitfield) tx.putBitfieldPage(page.index, bitfield)
else tx.deleteBitfieldPage(page.index)
continue
}
Expand All @@ -150,11 +151,11 @@ function isBadTree(parent, left, right) {
return !b4a.equals(hash, parent.hash) || parent.size !== left.size + right.size
}

function* allBits(bitfield) {
async function* allBits(bitfield) {
let i = 0
if (bitfield.get(0)) yield 0
if (await bitfield.get(0)) yield 0
while (true) {
i = bitfield.findFirst(true, i + 1)
i = await bitfield.findFirst(true, i + 1)
if (i === -1) break
yield i
}
Expand Down
4 changes: 2 additions & 2 deletions lib/bit-interlude.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ module.exports = class BitInterlude {
this.ranges.push({ start, end, value })
}

flush(tx, bitfield) {
async flush(tx, bitfield) {
if (!this.ranges.length) return []

let index = this.ranges[0].start
Expand All @@ -134,7 +134,7 @@ module.exports = class BitInterlude {
const buf = b4a.allocUnsafe(bitfield.getPageByteLength())

if (page) {
const src = page.bitfield // Uint32Array
const src = await page.getBuffer() // Uint32Array
buf.set(b4a.from(src.buffer, src.byteOffset, src.byteLength), 0)
} else {
b4a.fill(buf, 0)
Expand Down
Loading