Skip to content

Commit b61e132

Browse files
EvanHahngmaclennan
andauthored
fix: sync should only happen when both sides are enabled (#764)
This change: - Fixes core unreplication, closing issue [#762]. - Adds "fuzz testing" for sync, which tries a bunch of random actions and makes sure things work as expected. [#762]: #762 Co-Authored-By: Gregor MacLennan <[email protected]>
1 parent 770a8dc commit b61e132

File tree

7 files changed

+577
-85
lines changed

7 files changed

+577
-85
lines changed

src/lib/hypercore-helpers.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { assert } from '../utils.js'
2+
3+
/**
4+
* @param {import('hypercore')<'binary', any>} core Core to unreplicate. Must be ready.
5+
* @param {import('protomux')} protomux
6+
*/
7+
export function unreplicate(core, protomux) {
8+
assert(core.discoveryKey, 'Core should have a discovery key')
9+
protomux.unpair({
10+
protocol: 'hypercore/alpha',
11+
id: core.discoveryKey,
12+
})
13+
for (const channel of protomux) {
14+
if (channel.protocol !== 'hypercore/alpha') continue
15+
if (!channel.id.equals(core.discoveryKey)) continue
16+
channel.close()
17+
}
18+
}

src/sync/peer-sync-controller.js

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import mapObject from 'map-obj'
22
import { NAMESPACES, PRESYNC_NAMESPACES } from '../constants.js'
33
import { Logger } from '../logger.js'
44
import { ExhaustivenessError, createMap } from '../utils.js'
5+
import { unreplicate } from '../lib/hypercore-helpers.js'
56
/** @import { CoreRecord } from '../core-manager/index.js' */
67
/** @import { Role } from '../roles.js' */
78
/** @import { SyncEnabledState } from './sync-api.js' */
@@ -255,16 +256,22 @@ export class PeerSyncController {
255256

256257
/**
257258
* @param {import('hypercore')<'binary', any>} core
259+
* @returns {Promise<void>}
258260
*/
259-
#unreplicateCore(core) {
261+
async #unreplicateCore(core) {
260262
if (core === this.#coreManager.creatorCore) return
261-
const peerToUnreplicate = core.peers.find(
262-
(peer) => peer.protomux === this.#protomux
263-
)
264-
if (!peerToUnreplicate) return
265-
this.#log('unreplicating core %k', core.key)
266-
peerToUnreplicate.channel.close()
263+
267264
this.#replicatingCores.delete(core)
265+
266+
const isCoreReady = Boolean(core.discoveryKey)
267+
if (!isCoreReady) {
268+
await core.ready()
269+
const wasReEnabledWhileWaiting = this.#replicatingCores.has(core)
270+
if (wasReEnabledWhileWaiting) return
271+
}
272+
273+
unreplicate(core, this.#protomux)
274+
this.#log('unreplicated core %k', core.key)
268275
}
269276

270277
/**

0 commit comments

Comments
 (0)