Skip to content

Commit 3814b8b

Browse files
committed
Move to corestore-only + add bootstrap opts
1 parent eae1cb5 commit 3814b8b

File tree

4 files changed

+54
-40
lines changed

4 files changed

+54
-40
lines changed

bin/start.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ exports.builder = {
2222
description: 'The log level',
2323
type: 'string',
2424
default: 'info'
25+
},
26+
'bootstrap': {
27+
description: 'Comma-separated bootstrap servers to use.',
28+
type: 'array',
29+
default: []
2530
}
2631
}
2732
exports.handler = async function (argv) {
@@ -51,7 +56,7 @@ async function start (argv) {
5156
logFile: './hyperdrive.log',
5257
outFile: './hyperdrive.log',
5358
errFile: './hyperdrive.log',
54-
args: ['--port', argv.port, '--storage', argv.storage, '--log-level', argv['log-level']]
59+
args: ['--port', argv.port, '--storage', argv.storage, '--log-level', argv['log-level'], '--bootstrap', argv.bootstrap.join(',')]
5560
})
5661
console.log(chalk.green(`Daemon started at ${endpoint}`))
5762
}

index.js

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@ const mkdirp = require('mkdirp')
55
const raf = require('random-access-file')
66
const level = require('level')
77
const sub = require('subleveldown')
8-
const argv = require('yargs').argv
98
const grpc = require('grpc')
10-
const { rpc, loadMetadata } = require('hyperdrive-daemon-client')
119

12-
const Megastore = require('mini-megastore')
10+
const { rpc, loadMetadata } = require('hyperdrive-daemon-client')
11+
const corestore = require('random-access-corestore')
1312
const SwarmNetworker = require('megastore-swarm-networking')
1413

1514
const { DriveManager, createDriveHandlers } = require('./lib/drives')
@@ -23,6 +22,8 @@ try {
2322
}
2423
const log = require('./lib/log').child({ component: 'server' })
2524

25+
const argv = extractArguments()
26+
2627
class HyperdriveDaemon extends EventEmitter {
2728
constructor (storage, opts = {}) {
2829
super()
@@ -35,14 +36,16 @@ class HyperdriveDaemon extends EventEmitter {
3536
drives: sub(this.db, 'drives', { valueEncoding: 'json' })
3637
}
3738

38-
const megastoreOpts = {
39+
const corestoreOpts = {
3940
storage: path => raf(`${storage}/cores/${path}`),
4041
sparse: true
4142
}
43+
this.corestore = corestore(corestoreOpts.storage, corestoreOpts)
44+
// The root corestore should be bootstrapped with an empty default feed.
45+
this.corestore.default()
4246

43-
this.megastore = new Megastore(megastoreOpts.storage, megastoreOpts)
44-
this.networking = new SwarmNetworker(this.megastore, opts.network)
45-
this.drives = new DriveManager(this.megastore, this.networking, dbs.drives, this.opts)
47+
this.networking = new SwarmNetworker(this.corestore, opts.network)
48+
this.drives = new DriveManager(this.corestore, this.networking, dbs.drives, this.opts)
4649
this.fuse = hyperfuse ? new FuseManager(this.megastore, this.drives, dbs.fuse, this.opts) : null
4750

4851
this.drives.on('error', err => this.emit('error', err))
@@ -97,7 +100,13 @@ async function start () {
97100
const storageRoot = argv.storage
98101
await ensureStorage()
99102

100-
const daemon = new HyperdriveDaemon(storageRoot)
103+
const daemonOpts = {}
104+
if (argv.bootstrap.length) {
105+
daemonOpts.network = {
106+
bootstrap: argv.bootstrap
107+
}
108+
}
109+
const daemon = new HyperdriveDaemon(storageRoot, daemonOpts)
101110
await daemon.ready()
102111

103112
const server = new grpc.Server();
@@ -137,6 +146,23 @@ async function start () {
137146
}
138147
}
139148

149+
function extractArguments () {
150+
return require('yargs')
151+
.options({
152+
bootstrap: {
153+
array: true,
154+
default: []
155+
},
156+
storage: {
157+
string: true
158+
},
159+
port: {
160+
number: true
161+
}
162+
})
163+
.argv
164+
}
165+
140166
function wrap (metadata, methods) {
141167
const promisified = promisify(methods)
142168
let authenticated = authenticate(metadata, methods)

lib/drives/index.js

Lines changed: 13 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,23 @@ const { EventEmitter } = require('events')
44
const hyperdrive = require('hyperdrive')
55
const sub = require('subleveldown')
66
const collectStream = require('stream-collector')
7+
const bjson = require('buffer-json-encoding')
78
const datEncoding = require('dat-encoding')
89

910
const { fromHyperdriveOptions, toHyperdriveOptions } = require('hyperdrive-daemon-client/lib/common')
1011
const log = require('../log').child({ component: 'drive-manager' })
1112

1213
class DriveManager extends EventEmitter {
13-
constructor (megastore, networking, db, opts) {
14+
constructor (corestore, networking, db, opts) {
1415
super()
1516

16-
this.megastore = megastore
17+
this.corestore = corestore
1718
this.networking = networking
1819
this.db = db
1920
this.opts = opts || {}
2021

21-
this._driveIndex = sub(this.db, 'drives', { valueEncoding: 'json' })
22+
this._driveIndex = sub(this.db, 'drives', { valueEncoding: bjson })
2223
this._seedIndex = sub(this.db, 'seeding', { valueEncoding: 'utf8' })
23-
this._nameIndex = sub(this.db, 'names', { valueEncoding: 'utf8' })
2424

2525
if (this.opts.stats) {
2626
this._statsIndex = sub(this.db, 'stats', { valueEncoding: 'json' })
@@ -29,6 +29,8 @@ class DriveManager extends EventEmitter {
2929

3030
// TODO: Replace with an LRU cache.
3131
this._drives = new Map()
32+
this._sessions = new Map()
33+
3234
this._ready = new Promise(async resolve => {
3335
await this._reseed()
3436
return resolve()
@@ -56,14 +58,13 @@ class DriveManager extends EventEmitter {
5658
drive.writeFile('.key', drive.key.toString('hex'), err => {
5759
if (err) return reject(err)
5860
if (opts && opts.rootDrive) {
59-
drive.mkdir('/home', { uid: process.getuid(), gid: process.getgid() }, err => {
61+
return drive.mkdir('/home', { uid: process.getuid(), gid: process.getgid() }, err => {
6062
if (err) return reject(err)
6163
return resolve(err)
6264
})
6365
} else {
6466
return resolve()
6567
}
66-
6768
})
6869
}
6970
})
@@ -89,12 +90,6 @@ class DriveManager extends EventEmitter {
8990
}, this.opts.statsInterval || 2000)
9091
}
9192

92-
_generateName (key) {
93-
if (key) return key.toString('hex')
94-
// TODO: check collisions
95-
return crypto.randomBytes(64).toString('hex')
96-
}
97-
9893
_generateKeyString (key, opts) {
9994
var keyString = (key instanceof Buffer) ? key.toString('hex') : key
10095
if (opts && opts.version) keyString = keyString + '+' + opts.version
@@ -104,53 +99,40 @@ class DriveManager extends EventEmitter {
10499

105100
async get (key, opts) {
106101
key = (key instanceof Buffer) ? datEncoding.decode(key) : key
107-
const keyString = this._generateKeyString(key, opts)
108-
var newDrive = false
102+
var keyString = this._generateKeyString(key, opts)
109103

110104
if (key) {
111105
// TODO: cache checkouts
112106
const existing = this._drives.get(keyString)
113107
if (existing) return existing
114-
try {
115-
var name = await this._nameIndex.get(key)
116-
} catch (err) {
117-
if (!err.notFound) throw err
118-
// If a name was not found for this key, then the drive is not writable and must be synced.
119-
name = this._generateName(key)
120-
newDrive = true
121-
}
122-
} else {
123-
name = this._generateName()
124-
newDrive = true
125108
}
126109

127-
console.error('GETTING CORESTORE WITH OPTS:', { ...this.opts, ...opts })
128-
const corestore = this.megastore.get(name, { ...this.opts, ...opts })
129110
const driveOpts = {
130111
...opts,
131112
sparse: opts.sparse !== false,
132113
sparseMetadata: opts.sparseMetadata !== false
133114
}
134-
const drive = hyperdrive(corestore, key, driveOpts)
135-
115+
const drive = hyperdrive(this.corestore, key, driveOpts)
136116
await new Promise((resolve, reject) => {
137117
drive.ready(err => {
138118
if (err) return reject(err)
139119
return resolve()
140120
})
141121
})
122+
142123
key = datEncoding.encode(drive.key)
124+
keyString = this._generateKeystring(key, opts)
125+
143126

144127
if (drive.writable) {
145128
await this._configureDrive(drive, opts && opts.configure)
146129
}
147-
if (newDrive && this.opts.stats) {
130+
if (this.opts.stats) {
148131
this._collectStats(drive)
149132
}
150133

151134
// TODO: This should all be in one batch.
152135
await Promise.all([
153-
this._nameIndex.put(key, name),
154136
this._driveIndex.put(key, driveOpts)
155137
])
156138
this._drives.set(key, drive)

lib/fuse/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ class FuseManager extends EventEmitter {
249249
async _driveForPath (path, opts = {}) {
250250
const self = this
251251
console.error('GETTING DRIVE FOR PATH:', path)
252+
if (!this._rootDrive && path !== '/hyperdrive') throw new Error('You can only mount the root hyperdrive at /hyperdrive')
252253

253254
if (!this._rootDrive) {
254255
console.log('NO ROOT DRIVE')

0 commit comments

Comments
 (0)