Merge pull request #732 from orbitdb/develop

Release 0.23.0
This commit is contained in:
shamb0t 2019-12-05 09:29:34 +00:00 committed by GitHub
commit 187422e7dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
65 changed files with 25920 additions and 6254 deletions

4
API.md
View File

@ -81,10 +81,12 @@ Creates and returns an instance of OrbitDB. Use the optional `options` argument
- `keystore` (Keystore Instance) : By default creates an instance of [Keystore](https://github.com/orbitdb/orbit-db-keystore). A custom keystore instance can be used, see [this](https://github.com/orbitdb/orbit-db/blob/master/test/utils/custom-test-keystore.js) for an example.
- 'cache' (Cache Instance) : By default creates an instance of [Cache](https://github.com/orbitdb/orbit-db-cache). A custom cache instance can also be used.
- `cache` (Cache Instance) : By default creates an instance of [Cache](https://github.com/orbitdb/orbit-db-cache). A custom cache instance can also be used.
- `identity` (Identity Instance): By default it creates an instance of [Identity](https://github.com/orbitdb/orbit-db-identity-provider/blob/master/src/identity.js)
- `offline` (boolean): Start the OrbitDB instance in offline mode. Databases are not be replicated when the instance is started in offline mode. If the OrbitDB instance was started offline mode and you want to start replicating databases, the OrbitDB instance needs to be re-created. Default: `false`.
After creating an `OrbitDB` instance, you can access the different data stores. Creating a database instance, eg. with `orbitdb.keyvalue(...)`, returns a *Promise* that resolves to a [database instance](#store-api). See the [Store](#store-api) section for details of common methods and properties.
*For further details, see usage for [kvstore](https://github.com/orbitdb/orbit-db-kvstore#usage), [eventlog](https://github.com/orbitdb/orbit-db-eventstore#usage), [feed](https://github.com/orbitdb/orbit-db-feedstore#usage), [docstore](https://github.com/orbitdb/orbit-db-docstore#usage) and [counter](https://github.com/orbitdb/orbit-db-counterstore#usage).*

View File

@ -23,7 +23,8 @@ clean:
rm -rf node_modules/
clean-dependencies: clean
rm -f package-lock.json;
rm -f package-lock.json
rm -rf examples/browser/lib
rebuild: | clean-dependencies build

31322
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,7 @@
"main": "src/OrbitDB.js",
"dependencies": {
"cids": "^0.7.1",
"ipfs-pubsub-1on1": "~0.0.4",
"ipfs-pubsub-1on1": "~0.0.6",
"is-node": "^1.0.2",
"localstorage-down": "^0.6.7",
"logplease": "^1.2.14",
@ -25,15 +25,16 @@
"orbit-db-docstore": "~1.6.0",
"orbit-db-eventstore": "~1.6.0",
"orbit-db-feedstore": "~1.6.0",
"orbit-db-identity-provider": "~0.2.0",
"orbit-db-io": "^0.1.1",
"orbit-db-identity-provider": "~0.3.0",
"orbit-db-io": "~0.2.0",
"orbit-db-keystore": "~0.3.0",
"orbit-db-kvstore": "~1.6.0",
"orbit-db-pubsub": "~0.5.5",
"orbit-db-storage-adapter": "^0.5.3",
"orbit-db-store": "~2.7.0"
"orbit-db-store": "orbitdb/orbit-db-store"
},
"devDependencies": {
"adm-zip": "^0.4.13",
"babel-cli": "^6.26.0",
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
@ -45,7 +46,8 @@
"datastore-level": "0.10.0",
"fs-extra": "^7.0.1",
"go-ipfs-dep": "~0.4.20",
"ipfs": "~0.36.4",
"ipfs": "~0.40.0",
"ipfs-http-client": "~37.0.1",
"ipfs-repo": "~0.26.6",
"ipfsd-ctl": "~0.42.3",
"localstorage-level-migration": "~0.1.0",
@ -75,11 +77,11 @@
"lint:docs": "remark -qf -u validate-links .",
"test:all": "npm run test:browser-multiple-tabs && npm run test",
"test": "cross-env TEST=all mocha",
"test:browser-multiple-tabs": "npm run build:dist && cpy dist/orbitdb.min.js ./test/browser/orbitdb.js && cpy node_modules/ipfs/dist/index.js ./test/browser/ipfs.js && cpy node_modules/orbit-db-identity-provider/dist/index-browser.min.js ./test/browser/identities.js && cpy node_modules/ipfs-log/dist/ipfslog.min.js ./test/browser/ipfslog.min.js && mocha ./test/browser/concurrent.spec.js",
"test:browser-multiple-tabs": "npm run build:dist && cpy dist/orbitdb.min.js ./test/browser --rename=orbitdb.js && cpy node_modules/ipfs/dist/index.js ./test/browser --rename=ipfs.js && cpy node_modules/orbit-db-identity-provider/dist/index-browser.min.js ./test/browser --rename=identities.js && cpy node_modules/ipfs-log/dist/ipfslog.min.js ./test/browser && mocha ./test/browser/concurrent.spec.js",
"build": "npm run build:es5 && npm run build:debug && npm run build:dist && npm run build:examples && npm run build:docs/toc",
"build:examples": "webpack --config conf/webpack.example.config.js --sort-modules-by size && mkdirp examples/browser/lib && cpy node_modules/ipfs/dist/index.js examples/browser/lib/ipfs.js",
"build:dist": "webpack --config conf/webpack.config.js --sort-modules-by size && mkdirp examples/browser/lib && cpy dist/orbitdb.min.js examples/browser/lib/orbitdb.min.js",
"build:debug": "webpack --config conf/webpack.debug.config.js --sort-modules-by size && mkdirp examples/browser/lib && cpy dist/orbitdb.js examples/browser/lib/orbitdb.js && cpy dist/orbitdb.js.map examples/browser/lib/orbitdb.js.map",
"build:examples": "webpack --config conf/webpack.example.config.js --sort-modules-by size",
"build:dist": "webpack --config conf/webpack.config.js --sort-modules-by size && mkdirp examples/browser/lib && cpy dist/orbitdb.min.js examples/browser/lib",
"build:debug": "webpack --config conf/webpack.debug.config.js --sort-modules-by size && mkdirp examples/browser/lib && cpy dist/orbitdb.js examples/browser/lib && cpy dist/orbitdb.js.map examples/browser/lib",
"build:docs/toc": "markdown-toc --no-first1 -i README.md && markdown-toc --no-first1 -i API.md && markdown-toc --no-first1 -i GUIDE.md && markdown-toc --no-first1 -i CHANGELOG.md && markdown-toc --no-first1 -i FAQ.md ",
"build:es5": "babel src --out-dir ./dist/es5/ --presets babel-preset-env --plugins babel-plugin-transform-runtime"
},

View File

@ -40,9 +40,11 @@ class OrbitDB {
this._ipfs = ipfs
this.identity = identity
this.id = options.peerId
this._pubsub = options && options.broker
? new options.broker(this._ipfs) // eslint-disable-line
: new Pubsub(this._ipfs, this.id)
this._pubsub = !options.offline
? options.broker
? new options.broker(this._ipfs) // eslint-disable-line
: new Pubsub(this._ipfs, this.id)
: null
this.directory = options.directory || './orbitdb'
this.storage = options.storage
this._directConnections = {}
@ -76,7 +78,15 @@ class OrbitDB {
static async createInstance (ipfs, options = {}) {
if (!isDefined(ipfs)) { throw new Error('IPFS is a required argument. See https://github.com/orbitdb/orbit-db/blob/master/API.md#createinstance') }
const { id } = await ipfs.id()
if (options.offline === undefined) {
options.offline = false
}
if (options.offline && !options.id ) {
throw new Error('Offline mode requires passing an `id` in the options')
}
const { id } = options.offline ? ({ id: options.id }) : await ipfs.id()
if (!options.directory) { options.directory = './orbitdb' }
@ -228,7 +238,7 @@ class OrbitDB {
// Subscribe to pubsub to get updates from peers,
// this is what hooks us into the message propagation layer
// and the p2p network
if (opts.replicate && this._pubsub) { this._pubsub.subscribe(addr, this._onMessage.bind(this), this._onPeerConnected.bind(this)) }
if (opts.replicate && this._pubsub) { await this._pubsub.subscribe(addr, this._onMessage.bind(this), this._onPeerConnected.bind(this)) }
return store
}
@ -435,7 +445,7 @@ class OrbitDB {
// Make sure the type from the manifest matches the type that was given as an option
if (manifest.name !== dbAddress.path) { throw new Error(`Manifest '${manifest.name}' cannot be opened as '${dbAddress.path}'`) }
if (options.type && manifest.type !== options.type) { throw new Error(`Database '${dbAddress}' is type '${manifest.type}' but was opened as '${options.type}'`) }
// Save the database locally
await this._addManifestToCache(options.cache, dbAddress)

View File

@ -3,10 +3,10 @@
<title>Break OrbitDB</title>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<script type="text/javascript" src="orbitdb.js/orbitdb.min.js" charset="utf-8"></script>
<script type="text/javascript" src="ipfs.js/index.js" charset="utf-8"></script>
<script type="text/javascript" src="identities.js/index-browser.min.js" charset="utf-8"></script>
<script type="text/javascript" src="ipfslog.min.js/ipfslog.min.js" charset="utf-8"></script>
<script type="text/javascript" src="orbitdb.js" charset="utf-8"></script>
<script type="text/javascript" src="ipfs.js" charset="utf-8"></script>
<script type="text/javascript" src="identities.js" charset="utf-8"></script>
<script type="text/javascript" src="ipfslog.min.js" charset="utf-8"></script>
</head>
<body>
<div style="padding: 0px 0px 25px 0px;">

View File

@ -7,6 +7,7 @@ const path = require('path')
const rmrf = require('rimraf')
const levelup = require('levelup')
const leveldown = require('leveldown')
const Zip = require('adm-zip')
const OrbitDB = require('../src/OrbitDB')
const OrbitDBAddress = require('../src/orbit-db-address')
const Identities = require('orbit-db-identity-provider')
@ -20,10 +21,11 @@ const {
testAPIs,
} = require('./utils')
const dbPath = path.join(__dirname, 'orbitdb', 'tests', 'create-open')
const ipfsPath = path.join(__dirname, 'orbitdb', 'tests', 'create-open', 'ipfs')
const migrationFixturePath = path.join(__dirname, 'fixtures', 'migration', 'cache-schema-test')
const ipfsFixturesDir = path.join(__dirname, 'fixtures', 'ipfs')
const dbPath = path.join('./orbitdb', 'tests', 'create-open')
const ipfsPath = path.join('./orbitdb', 'tests', 'create-open', 'ipfs')
const migrationFixturePath = path.join('./test', 'fixtures', 'migration', 'cache-schema-test')
const ipfsFixtures = path.join('./test', 'fixtures', 'ipfs.zip')
const ipfsFixturesDir = path.join('./test', 'fixtures', 'ipfs')
Object.keys(testAPIs).forEach(API => {
describe(`orbit-db - Create & Open (${API})`, function () {
@ -45,7 +47,8 @@ Object.keys(testAPIs).forEach(API => {
rmrf.sync(dbPath)
ipfsd = await startIpfs(API, config.daemon1)
ipfs = ipfsd.api
const zip = new Zip(ipfsFixtures)
await zip.extractAllToAsync(path.join('./test', 'fixtures'), true)
await fs.copy(path.join(ipfsFixturesDir, 'blocks'), path.join(ipfsd.path, 'blocks'))
await fs.copy(path.join(ipfsFixturesDir, 'datastore'), path.join(ipfsd.path, 'datastore'), { filter: filterFunc })
orbitdb = await OrbitDB.createInstance(ipfs, { directory: dbPath })
@ -57,6 +60,8 @@ Object.keys(testAPIs).forEach(API => {
if (ipfsd)
await stopIpfs(ipfsd)
rmrf.sync(ipfsFixturesDir)
})
describe('Create', function () {
@ -153,7 +158,7 @@ Object.keys(testAPIs).forEach(API => {
it('loads cache from previous version of orbit-db', async () => {
const dbName = 'cache-schema-test'
db = await orbitdb.create(dbName, 'keyvalue')
db = await orbitdb.create(dbName, 'keyvalue', { overwrite: true })
const manifestHash = db.address.root
const migrationDataPath = path.join(dbPath, manifestHash, dbName)

View File

@ -161,7 +161,8 @@ Object.keys(testAPIs).forEach(API => {
assert.deepEqual(res.payload, expectedOperation)
assert.notEqual(res.next, undefined)
assert.equal(res.next.length, 1)
assert.equal(res.v, 1)
assert.equal(res.refs.length, 0)
assert.equal(res.v, 2)
assert.notEqual(res.clock, undefined)
assert.equal(res.clock.time, 2)
assert.notEqual(res.key, undefined)

108
test/feed-load.test.js Normal file
View File

@ -0,0 +1,108 @@
'use strict'
const assert = require('assert')
const OrbitDB = require('../src/OrbitDB')
const rmrf = require('rimraf')
const path = require('path')
// Include test utilities
const {
config,
startIpfs,
stopIpfs,
testAPIs,
} = require('./utils')
const last = arr => arr[arr.length - 1]
const dbPath = './orbitdb/tests/feed-load'
const ipfsPath = './orbitdb/tests/feed-load/ipfs'
Object.keys(testAPIs).forEach(API => {
describe(`orbit-db - Feed Load Amount (${API})`, function() {
this.timeout(config.timeout)
let ipfsd, ipfs, orbitdb1, db, address
before(async () => {
config.daemon1.repo = ipfsPath
rmrf.sync(config.daemon1.repo)
rmrf.sync(dbPath)
ipfsd = await startIpfs(API, config.daemon1)
ipfs = ipfsd.api
orbitdb1 = await OrbitDB.createInstance(ipfs, { directory: path.join(dbPath, '1') })
})
after(async () => {
if(orbitdb1)
await orbitdb1.stop()
if (ipfsd)
await stopIpfs(ipfsd)
})
describe('Feed Load Amount', function() {
it('add 10 items and verify they are in the index', async () => {
db = await orbitdb1.feed('feed database')
//All tests should retrieve these 10 items.
for (var i=0; i < 10; i++) {
await db.add({content: (i + 10).toString()})
}
assert.equal(Object.keys(db.index).length, 10)
})
it('reopen store and load 10 items', async () => {
address = db.address.toString()
await db.close()
db = await orbitdb1.open(address)
//Load 10 items
await db.load(10)
assert.equal(Object.keys(db.index).length, 10)
})
it('reopen store and load 1 item more than exists', async () => {
await db.close()
db = await orbitdb1.open(address)
//Load 11 items
await db.load(11)
assert.equal(Object.keys(db.index).length, 10)
})
it('reopen store and load 5 item more than exists', async () => {
await db.close()
db = await orbitdb1.open(address)
//Load 15 items
await db.load(15)
assert.equal(Object.keys(db.index).length, 10)
})
it('reopen store and load 20 items more than exists', async () => {
await db.close()
db = await orbitdb1.open(address)
//Load 30 items
await db.load(30)
assert.equal(Object.keys(db.index).length, 10)
})
})
})
})

BIN
test/fixtures/ipfs.zip vendored Normal file

Binary file not shown.

View File

@ -1 +0,0 @@
¢dtypedipfsfparams¡gaddressx1zdpuAuhwhxGZSjWRqPBxfKoPEyF9gZHbKXvGqNtK9TEPJtj67

View File

@ -1,2 +0,0 @@
Û{"hash":null,"id":"/orbitdb/QmWDUfC4zcWJGgc9UHn1X3qQ5KZqBv4KCiCtjnpMmBT8JC/v0-db","payload":{"op":"ADD","key":null,"value":{"thing":"1"}},"next":[],"v":0,"clock":{"id":"04b54f6ef529cd2dd2f9c6897a382c492222d42e57826269a38101ffe752aa07260ecd092a970d7eef08c4ddae2b7006ee25f07e4ab62fa5262ae3b51fdea29f78","time":1},"sig":"30460221008067ac541ab9b8ef6de41318220c6927f046188ae63620c34666d1ca00574001022100b9427217bb79b4bdad8645bb361745ffffa0bfa264778202c68aa8f2b9857ada","key":"04b54f6ef529cd2dd2f9c6897a382c492222d42e57826269a38101ffe752aa07260ecd092a970d7eef08c4ddae2b7006ee25f07e4ab62fa5262ae3b51fdea29f78"}

View File

@ -1,55 +0,0 @@
<12>
IPFS -- Inter-Planetary File system
IPFS is a global, versioned, peer-to-peer filesystem. It combines good ideas
from Git, BitTorrent, Kademlia, SFS, and the Web. It is like a single bit-
torrent swarm, exchanging git objects. IPFS provides an interface as simple
as the HTTP web, but with permanence built in. You can also mount the world
at /ipfs.
IPFS is a protocol:
- defines a content-addressed file system
- coordinates content delivery
- combines Kademlia + BitTorrent + Git
IPFS is a filesystem:
- has directories and files
- mountable filesystem (via FUSE)
IPFS is a web:
- can be used to view documents like the web
- files accessible via HTTP at `http://ipfs.io/<path>`
- browsers or extensions can learn to use `ipfs://` directly
- hash-addressed content guarantees authenticity
IPFS is modular:
- connection layer over any network protocol
- routing layer
- uses a routing layer DHT (kademlia/coral)
- uses a path-based naming service
- uses bittorrent-inspired block exchange
IPFS uses crypto:
- cryptographic-hash content addressing
- block-level deduplication
- file integrity + versioning
- filesystem-level encryption + signing support
IPFS is p2p:
- worldwide peer-to-peer file transfers
- completely decentralized architecture
- **no** central point of failure
IPFS is a cdn:
- add a file to the filesystem locally, and it's now available to the world
- caching-friendly (content-hash naming)
- bittorrent-based bandwidth distribution
IPFS has a name service:
- IPNS, an SFS inspired name system
- global namespace based on PKI
- serves to build trust chains
- compatible with other NSes
- can map DNS, .onion, .bit, etc to IPNS
<18>

View File

@ -1,2 +0,0 @@
h{"name":"v0-db","type":"feed","accessController":"/ipfs/Qmc3S7aMSmH8oGmx7Zdp8UxVWcDyCq5o2H9qYFgT3GW6nM"}

View File

@ -1,8 +0,0 @@
º{
"admin": [],
"write": [
"04b54f6ef529cd2dd2f9c6897a382c492222d42e57826269a38101ffe752aa07260ecd092a970d7eef08c4ddae2b7006ee25f07e4ab62fa5262ae3b51fdea29f78"
],
"read": []
}

View File

@ -1 +0,0 @@
£dnameqcache-schema-testdtypehkeyvaluepaccessControllerx7/ipfs/zdpuAyfbHMCJgA1fL72eAq6pz7G3qKzGgLNZpnrHRbFexR6Zw

View File

@ -1,4 +0,0 @@
/
" ĘI%Ľsć!@®<>ń'ŹŞ—ú8»đď@:µŃ<C2B5>o_÷directŤV2
" ÝełßIž\(&PD¬
<08> ô« 2ýhO.ß<> recursive¸V

View File

@ -1,2 +0,0 @@
{"hash":null,"id":"/orbitdb/QmWDUfC4zcWJGgc9UHn1X3qQ5KZqBv4KCiCtjnpMmBT8JC/v0-db","payload":{"op":"ADD","key":null,"value":{"thing":"2"}},"next":["QmPoEJkWCkgDkuNdshm6Srw9haEBtgn1e352dkF1wpEfXt"],"v":0,"clock":{"id":"04b54f6ef529cd2dd2f9c6897a382c492222d42e57826269a38101ffe752aa07260ecd092a970d7eef08c4ddae2b7006ee25f07e4ab62fa5262ae3b51fdea29f78","time":2},"sig":"30460221008067ac541ab9b8ef6de41318220c6927f046188ae63620c34666d1ca00574001022100b9427217bb79b4bdad8645bb361745ffffa0bfa264778202c68aa8f2b9857ada","key":"04b54f6ef529cd2dd2f9c6897a382c492222d42e57826269a38101ffe752aa07260ecd092a970d7eef08c4ddae2b7006ee25f07e4ab62fa5262ae3b51fdea29f78"}

View File

@ -1,8 +0,0 @@
ŽCome hang out in our IRC chat room if you have any questions.
Contact the ipfs dev team:
- Bugs: https://github.com/ipfs/go-ipfs/issues
- Help: irc.freenode.org/#ipfs
- Email: dev@ipfs.io
½

View File

@ -1,2 +0,0 @@
¼{"hash":null,"id":"/orbitdb/QmWDUfC4zcWJGgc9UHn1X3qQ5KZqBv4KCiCtjnpMmBT8JC/v0-db","payload":{"op":"ADD","key":null,"value":{"thing":"3"}},"next":["QmZvMXmv66vXQ9u2q8UTWPmH59eQUKzVb24bKv8j9zbVuN","QmPoEJkWCkgDkuNdshm6Srw9haEBtgn1e352dkF1wpEfXt"],"v":0,"clock":{"id":"04b54f6ef529cd2dd2f9c6897a382c492222d42e57826269a38101ffe752aa07260ecd092a970d7eef08c4ddae2b7006ee25f07e4ab62fa5262ae3b51fdea29f78","time":3},"sig":"30460221008067ac541ab9b8ef6de41318220c6927f046188ae63620c34666d1ca00574001022100b9427217bb79b4bdad8645bb361745ffffa0bfa264778202c68aa8f2b9857ada","key":"04b54f6ef529cd2dd2f9c6897a382c492222d42e57826269a38101ffe752aa07260ecd092a970d7eef08c4ddae2b7006ee25f07e4ab62fa5262ae3b51fdea29f78"}

View File

@ -1,3 +0,0 @@
¡ewritexJ[
"02b1a8717e8bdb12c29dae1a43ed83bc7621205c5ba3029a0ca842653c4a5a89d4"
]

View File

@ -1,9 +0,0 @@
¿·Some helpful resources for finding your way around ipfs:
- quick-start: a quick show of various ipfs features.
- ipfs commands: a list of all commands
- ipfs --help: every command describes itself
- https://github.com/ipfs/go-ipfs -- the src repository
- #ipfs on irc.freenode.org -- the community irc channel
·

View File

@ -1,115 +0,0 @@
½ µ # 0.1 - Quick Start
This is a set of short examples with minimal explanation. It is meant as
a "quick start". Soon, we'll write a longer tour :-)
Add a file to ipfs:
echo "hello world" >hello
ipfs add hello
View it:
ipfs cat <the-hash-you-got-here>
Try a directory:
mkdir foo
mkdir foo/bar
echo "baz" > foo/baz
echo "baz" > foo/bar/baz
ipfs add -r foo
View things:
ipfs ls <the-hash-here>
ipfs ls <the-hash-here>/bar
ipfs cat <the-hash-here>/baz
ipfs cat <the-hash-here>/bar/baz
ipfs cat <the-hash-here>/bar
ipfs ls <the-hash-here>/baz
References:
ipfs refs <the-hash-here>
ipfs refs -r <the-hash-here>
ipfs refs --help
Get:
ipfs get <the-hash-here> -o foo2
diff foo foo2
Objects:
ipfs object get <the-hash-here>
ipfs object get <the-hash-here>/foo2
ipfs object --help
Pin + GC:
ipfs pin add <the-hash-here>
ipfs repo gc
ipfs ls <the-hash-here>
ipfs pin rm <the-hash-here>
ipfs repo gc
Daemon:
ipfs daemon (in another terminal)
ipfs id
Network:
(must be online)
ipfs swarm peers
ipfs id
ipfs cat <hash-of-remote-object>
Mount:
(warning: fuse is finicky!)
ipfs mount
cd /ipfs/<the-hash-here>
ls
Tool:
ipfs version
ipfs update
ipfs commands
ipfs config --help
open http://localhost:5001/webui
Browse:
webui:
http://localhost:5001/webui
video:
http://localhost:8080/ipfs/QmVc6zuAneKJzicnJpfrqCH9gSy6bz54JhcypfJYhGUFQu/play#/ipfs/QmTKZgRNwDNZwHtJSjCp6r5FYefzpULfy37JvMt9DwvXse
images:
http://localhost:8080/ipfs/QmZpc3HvfjEXvLWGQPWbHk3AjD5j8NEN4gmFN8Jmrd5g83/cs
markdown renderer app:
http://localhost:8080/ipfs/QmX7M9CiYXjVeFnkfVGf3y5ixTZ2ACeSGyL1vBJY1HvQPp/mdown
µ

View File

@ -1,27 +0,0 @@
Š IPFS Alpha Security Notes
We try hard to ensure our system is safe and robust, but all software
has bugs, especially new software. This distribution is meant to be an
alpha preview, don't use it for anything mission critical.
Please note the following:
- This is alpha software and has not been audited. It is our goal
to conduct a proper security audit once we close in on a 1.0 release.
- ipfs is a networked program, and may have serious undiscovered
vulnerabilities. It is written in Go, and we do not execute any
user provided data. But please point any problems out to us in a
github issue, or email security@ipfs.io privately.
- security@ipfs.io GPG key:
- 4B9665FB 92636D17 7C7A86D3 50AAE8A9 59B13AF3
- https://pgp.mit.edu/pks/lookup?op=get&search=0x50AAE8A959B13AF3
- ipfs uses encryption for all communication, but it's NOT PROVEN SECURE
YET! It may be totally broken. For now, the code is included to make
sure we benchmark our operations with encryption in mind. In the future,
there will be an "unsafe" mode for high performance intranet apps.
If this is a blocking feature for you, please contact us.
Š

View File

@ -1,36 +0,0 @@
¤œWIP
# 0.0 - Introduction
Welcome to IPFS! This tour will guide you through a few of the
features of this tool, and the most common commands. Then, it will
immerse you into the world of merkledags and the amazing things
you can do with them.
This tour has many parts, and can be taken in different sequences.
Different people learn different ways, so choose your own adventure:
To start with the concepts, try:
- The Merkle DAG
- Data Structures on the Merkle DAG
- Representing Files with unixfs
- add, cat, ls, refs
...
To start with the examples, try:
- add, cat, ls, refs
- Representing Files with unixfs
- Data Structures on the Merkle DAG
- The Merkle DAG
...
To start with the network, try:
- IPFS Nodes
- Running the daemon
- The Swarm
- The Web
œ

View File

@ -1 +0,0 @@
©avbidxL/orbitdb/zdpuAkdtE84R9iHvk39m3qUJKP3RXD9c9EQJWVsLMXC4sYQFA/cache-schema-testckeyx040d2ae7ff5f52d41f65829f30b66eb2c85910f0c683d73ee3cead5d22c15702f32105cdfd83b031d6b2fa594d6ff725979e83bd23575dd26546ff1f30702eb507csigxŒ30440220328dedc06e17fb1a9cb9826c4daa1b5b8e9e609121d025389fccc49ce81787dc02202ea8ea8a691f8896c79bca42f5eba864daba5e920480c95cb88841d76e815308dhashödnext€eclock¢bidx040d2ae7ff5f52d41f65829f30b66eb2c85910f0c683d73ee3cead5d22c15702f32105cdfd83b031d6b2fa594d6ff725979e83bd23575dd26546ff1f30702eb507dtimegpayload£bopcPUTckeyckeyevalueevaluehidentity¤bidxB02b1a8717e8bdb12c29dae1a43ed83bc7621205c5ba3029a0ca842653c4a5a89d4dtypegorbitdbipublicKeyx040d2ae7ff5f52d41f65829f30b66eb2c85910f0c683d73ee3cead5d22c15702f32105cdfd83b031d6b2fa594d6ff725979e83bd23575dd26546ff1f30702eb507jsignatures¢bidxŒ304402200190b97ab06a0623a0fc0d9d7da60ff77515f0649a93d6a9dab3f3bd3bbfb4da02200520284db952c6f0a366b886b881ea5da5bd21a9c277f7d4d4fab1aa8e15682eipublicKeyxŽ3045022100c5e18a43dd47f915754ff964ff2c7f85dbc0a2827964553d648cf613baff6e4b02206e678964e12f8c1532b8d09116a9dc4dadf97b29e21199644b0130e39192259d

View File

@ -1,4 +0,0 @@
2
" èžsÜL`•>¾P}ãÈD
>ÚŸo_¸=¡"´u'Ò 0.0-intro§


View File

@ -1,28 +0,0 @@
ЛГHello and Welcome to IPFS!
в–€в–€в•—в–€в–€в–€в–€в–€в–€в•— в–€в–€в–€в–€в–€в–€в–€в•—в–€в–€в–€в–€в–€в–€в–€в•—
в–€в–€в•‘в–€в–€в•”в•ђв•ђв–€в–€в•—в–€в–€в•”в•ђв•ђв•ђв•ђв•ќв–€в–€в•”в•ђв•ђв•ђв•ђв•ќ
в–€в–€в•‘в–€в–€в–€в–€в–€в–€в•”в•ќв–€в–€в–€в–€в–€в•— в–€в–€в–€в–€в–€в–€в–€в•—
в–€в–€в•‘в–€в–€в•”в•ђв•ђв•ђв•ќ в–€в–€в•”в•ђв•ђв•ќ в•љв•ђв•ђв•ђв•ђв–€в–€в•‘
в–€в–€в•‘в–€в–€в•‘ в–€в–€в•‘ в–€в–€в–€в–€в–€в–€в–€в•‘
в•љв•ђв•ќв•љв•ђв•ќ в•љв•ђв•ќ в•љв•ђв•ђв•ђв•ђв•ђв•ђв•ќ
If you're seeing this, you have successfully installed
IPFS and are now interfacing with the ipfs merkledag!
-------------------------------------------------------
| Warning: |
| This is alpha software. Use at your own discretion! |
| Much is missing or lacking polish. There are bugs. |
| Not yet secure. Read the security notes for more. |
-------------------------------------------------------
Check out some of the other files in this directory:
./about
./help
./quick-start <-- usage examples
./readme <-- this file
./security-notes
Г

View File

@ -1,3 +0,0 @@
-
" õR ;<3B>—¿­ˆfq<66>aU¿õ 0 [Xè@÷8Ó·O§¦index


View File

@ -1 +0,0 @@
/repo/flatfs/shard/v1/next-to-last/2

View File

@ -1,22 +0,0 @@
This is a repository of IPLD objects. Each IPLD object is in a single file,
named <base32 encoding of cid>.data. Where <base32 encoding of cid> is the
"base32" encoding of the CID (as specified in
https://github.com/multiformats/multibase) without the 'B' prefix.
All the object files are placed in a tree of directories, based on a
function of the CID. This is a form of sharding similar to
the objects directory in git repositories. Previously, we used
prefixes, we now use the next-to-last two charters.
func NextToLast(base32cid string) {
nextToLastLen := 2
offset := len(base32cid) - nextToLastLen - 1
return str[offset : offset+nextToLastLen]
}
For example, an object with a base58 CIDv1 of
zb2rhYSxw4ZjuzgCnWSt19Q94ERaeFhu9uSqRgjSdx9bsgM6f
has a base32 CIDv1 of
BAFKREIA22FLID5AJ2KU7URG47MDLROZIH6YF2KALU2PWEFPVI37YLKRSCA
and will be placed at
SC/AFKREIA22FLID5AJ2KU7URG47MDLROZIH6YF2KALU2PWEFPVI37YLKRSCA.data
with 'SC' being the last-to-next two characters and the 'B' at the
beginning of the CIDv1 string is the multibase prefix that is not
stored in the filename.

View File

@ -1,86 +0,0 @@
{
"Addresses": {
"Swarm": [
"/ip4/0.0.0.0/tcp/4002",
"/ip4/127.0.0.1/tcp/4003/ws"
],
"API": "/ip4/127.0.0.1/tcp/5002",
"Gateway": "/ip4/127.0.0.1/tcp/9090"
},
"Discovery": {
"MDNS": {
"Enabled": true,
"Interval": 10
},
"webRTCStar": {
"Enabled": true
}
},
"Bootstrap": [
"/ip4/104.236.176.52/tcp/4001/ipfs/QmSoLnSGccFuZQJzRadHn95W2CrSFmZuTdDWP8HXaHca9z",
"/ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
"/ip4/104.236.179.241/tcp/4001/ipfs/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM",
"/ip4/162.243.248.213/tcp/4001/ipfs/QmSoLueR4xBeUbY9WZ9xGUUxunbKWcrNFTDAadQJmocnWm",
"/ip4/128.199.219.111/tcp/4001/ipfs/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu",
"/ip4/104.236.76.40/tcp/4001/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64",
"/ip4/178.62.158.247/tcp/4001/ipfs/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd",
"/ip4/178.62.61.185/tcp/4001/ipfs/QmSoLMeWqB7YGVLJN3pNLQpmmEk35v6wYtsMGLzSr5QBU3",
"/ip4/104.236.151.122/tcp/4001/ipfs/QmSoLju6m7xTh3DuokvT3886QRYqxAzb1kShaanJgW36yx",
"/ip6/2604:a880:1:20::1f9:9001/tcp/4001/ipfs/QmSoLnSGccFuZQJzRadHn95W2CrSFmZuTdDWP8HXaHca9z",
"/ip6/2604:a880:1:20::203:d001/tcp/4001/ipfs/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM",
"/ip6/2604:a880:0:1010::23:d001/tcp/4001/ipfs/QmSoLueR4xBeUbY9WZ9xGUUxunbKWcrNFTDAadQJmocnWm",
"/ip6/2400:6180:0:d0::151:6001/tcp/4001/ipfs/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu",
"/ip6/2604:a880:800:10::4a:5001/tcp/4001/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64",
"/ip6/2a03:b0c0:0:1010::23:1001/tcp/4001/ipfs/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd",
"/ip6/2a03:b0c0:1:d0::e7:1/tcp/4001/ipfs/QmSoLMeWqB7YGVLJN3pNLQpmmEk35v6wYtsMGLzSr5QBU3",
"/ip6/2604:a880:1:20::1d9:6001/tcp/4001/ipfs/QmSoLju6m7xTh3DuokvT3886QRYqxAzb1kShaanJgW36yx",
"/dns4/node0.preload.ipfs.io/tcp/443/wss/ipfs/QmZMxNdpMkewiVZLMRxaNxUeZpDUb34pWjZ1kZvsd16Zic",
"/dns4/node1.preload.ipfs.io/tcp/443/wss/ipfs/Qmbut9Ywz9YEDrz8ySBSgWyJk41Uvm2QJPhwDJzJyGFsD6"
],
"Swarm": {
"ConnMgr": {
"LowWater": 200,
"HighWater": 500
}
},
"Identity": {
"PeerID": "QmZDxp1kbEQTTeWNRN6xGWhH3AxNhR5J1ZspdAgS5JgLXW",
"PrivKey": "CAASpwkwggSjAgEAAoIBAQCsopwtbRiWIo/8VJWj5jN+w8rENSb/zpRhkMaPiyTV1KgSMqD5+beOacDH5hYhGOz7pjd7jzXVRrhIKQo6lIyk77aJieW/6Ny34uwYqAiGMZNahXnVhXAE6uLoU49l967/v6YXuKgWOFeOSnAznyIX7guJgN61swJbQ/N32Ho7Vbqykjf4ody5qu3BNTREa4g9TRqxYT8+vh/aHUTI2ze/Z+EwjNfOJVgGbAx9tqxozyiLcH+dHVLD4TKMOJ+s3wQ5TZfe7QaVSUxVUg9L4GYRpvB8GgDPcmAy23G61CYP62BGgU+/e8/fYD44aTfxg53XWt6FNcw0/Mzar9qjHqk3AgMBAAECggEAcRkLBjudyuYTvHTRoBG1FMxCb65+wUHeNdj6LJo05J2wClP+4CW4GmWv9YYIY2CICQlI+frFgtcU7bltSRl+1qNwy8R6rvJof1P75t9Wzkt2ROyC9962l5ImW5w6qsvMayJsNsgz3nLE8aRUw4zycgjyp/+0aAdBePcYbyB0W5/n4lSic9sNG48l7psq6LP6dt7V+AD+rqMYV3bMLPnhUgDeNVP7xILD30xWNbSfaimJfFMypli0K7BQst7tYI0r82rShkxKCEG7CgpzYKrVcXCD90xOEm7ZcUYf1bVtAPNCZ5KoVA7uAULpHd6OxxtQs+Rtg6gfajzyN2YXH/O0aQKBgQDYVkc8aBESDWytAl/4a62OQEX/f43sxqB9+7IxzcaOuSd5Rdn3jmHyi9tP+VLnuyRbXe7OhaWVrZDRdaV3R0TOGK/TdIzNNgfNA81sBAItedrpawVfb6GdXvrrBWOuFej8A5aUYpUY7JEwW8FBVuuM+cq4su5AEjmsIC0+is0AjQKBgQDMSTKoLqJsS3JHXYMsvQp+B2UO7kO8LLQPdM27Wet/1Id3O7jWgN7gEslrOuiqbsfuLlfe9TwiZk9Z9LdNDrUkHHY2XTrLpyEW4XAkZ2oVMqrQZczW8uw7JOwFcVWGnL+P0w3W9YQQjsnRGvje3oGfyRAvH1XGBIGfABc74LtJ0wKBgHUujtmWmSCJKwOv1KIwWUtDX2cdBZhqosZ7DrPRfasTeeFDx+RDOKTzwrDYIWMqSHBBOjidxeqEoHwE2ML6VLe6QYsth5MkoCcZ1yyaIz/U0JI9CST/x7ABobKqMas7bP8NRoRLve1JPv/Nw6mL1n1/VKKlMU59UMX+i+NjtdWFAoGAHYp0NdfQiwJ5+xHttxl7G/Brz7Xqu5pnS1jjqzT8lhagpEBRoUsvb42n7MavAH5WkP3InSgvUvYigWqe2xjGXvtyqLfgmbSIV2uwMMN3lqsmAk7GSUsFmCPlsX/LE1U1alHlzXDhcReE3aUd2fSpH/cOTRIl8CWUrO5xbao4yxsCgYEAsl8M2R7TjKpwoL+a9upZoIz4FDT0h+S3CTQhZSh4juVj/fOnzsMvesdbTb5w8rTg33yN8GLjEHeeLQei6vNxtK875cNsmm8hUIagB0+1IApkvswAJhpM/4gA1G+ZxTgR9pIqSu3iYuaESuEB763PyznmbUiV9a9glY8oSu0WFmU="
},
"datastore": {
"Spec": {
"type": "mount",
"mounts": [
{
"mountpoint": "/blocks",
"type": "measure",
"prefix": "flatfs.datastore",
"child": {
"type": "flatfs",
"path": "blocks",
"sync": true,
"shardFunc": "/repo/flatfs/shard/v1/next-to-last/2"
}
},
{
"mountpoint": "/",
"type": "measure",
"prefix": "leveldb.datastore",
"child": {
"type": "levelds",
"path": "datastore",
"compression": "none"
}
}
]
}
},
"Keychain": {
"dek": {
"keyLength": 64,
"iterationCount": 10000,
"salt": "cYS7ZeAxVX7IdDVJ2JDOYNio",
"hash": "sha2-512"
}
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1 +0,0 @@
MANIFEST-000201

View File

@ -1 +0,0 @@
2019/09/01-11:44:16.574088 7fd834d96700 Delete type=3 #200

Binary file not shown.

View File

@ -1 +0,0 @@
{"mounts":[{"mountpoint":"/blocks","path":"blocks","shardFunc":"/repo/flatfs/shard/v1/next-to-last/2","type":"flatfs"},{"mountpoint":"/","path":"datastore","type":"levelds"}],"type":"mount"}

View File

@ -1 +0,0 @@
 Y”„9_)ažô€Ë¹2¾RÅm™Åkeà˜»ï

View File

@ -1 +0,0 @@
7

View File

@ -0,0 +1 @@
MANIFEST-000002

View File

@ -0,0 +1 @@
2019/11/20-15:37:17.518217 7f2d57fff700 Delete type=3 #1

View File

@ -0,0 +1 @@
MANIFEST-000002

View File

@ -0,0 +1 @@
2019/11/20-15:37:17.490398 7f2d6ccf8700 Delete type=3 #1

89
test/offline-mode.js Normal file
View File

@ -0,0 +1,89 @@
'use strict'
const fs = require('fs')
const path = require('path')
const assert = require('assert')
const mapSeries = require('p-map-series')
const rmrf = require('rimraf')
const IPFS = require('ipfs')
const OrbitDB = require('../src/OrbitDB')
const Identities = require('orbit-db-identity-provider')
const Keystore = require('orbit-db-keystore')
const leveldown = require('leveldown')
const storage = require('orbit-db-storage-adapter')(leveldown)
// Include test utilities
const {
config,
startIpfs,
stopIpfs,
testAPIs,
} = require('./utils')
const dbPath1 = './orbitdb/tests/offline/db1'
const dbPath2 = './orbitdb/tests/offline/db2'
const ipfsPath = './orbitdb/tests/offline/ipfs'
Object.keys(testAPIs).forEach(API => {
describe(`orbit-db - Offline mode (${API})`, function() {
this.timeout(config.timeout)
let ipfsd1, ipfsd2, ipfs1, ipfs2, orbitdb, db, keystore
let identity1, identity2
let localDataPath
before(async () => {
config.daemon1.repo = path.join(ipfsPath, '/1')
config.daemon2.repo = path.join(ipfsPath, '/2')
rmrf.sync(config.daemon1.repo)
rmrf.sync(config.daemon2.repo)
rmrf.sync(path.join(ipfsPath, '/2'))
rmrf.sync('./orbitdb/tests/offline')
rmrf.sync(dbPath1)
rmrf.sync(dbPath2)
ipfsd1 = await startIpfs(API, config.daemon1)
ipfsd2 = await startIpfs(API, config.daemon2)
ipfs1 = ipfsd1.api
ipfs2 = ipfsd2.api
})
after(async () => {
if(orbitdb)
await orbitdb.stop()
if (ipfsd1)
await stopIpfs(ipfsd1)
if (ipfsd2)
await stopIpfs(ipfsd2)
})
it('starts in offline mode', async () => {
orbitdb = await OrbitDB.createInstance(ipfs1, { id: 'A', offline: true, directory: dbPath1 })
assert.equal(orbitdb._pubsub, null)
await orbitdb.stop()
})
it('does not start in offline mode', async () => {
orbitdb = await OrbitDB.createInstance(ipfs1, { offline: false, directory: dbPath1 })
assert.notEqual(orbitdb._pubsub, null)
await orbitdb.stop()
})
it('does not start in offline mode - default', async () => {
orbitdb = await OrbitDB.createInstance(ipfs1, { directory: dbPath1 })
assert.notEqual(orbitdb._pubsub, null)
await orbitdb.stop()
})
it('throws error if no `id` passed in offline mode', async () => {
let err
try {
orbitdb = await OrbitDB.createInstance(ipfs1, { offline: true, directory: dbPath1 })
} catch (e) {
err = e.message
}
assert.equal(err, 'Offline mode requires passing an `id` in the options')
await orbitdb.stop()
})
})
})

View File

@ -122,9 +122,18 @@ Object.keys(testAPIs).forEach(API => {
it('closes database while loading', async () => {
db = await orbitdb1.eventlog(address)
db.load() // don't wait for load to finish
await db.close()
assert.equal(db._cache.store, null)
await new Promise(async (resolve, reject) => {
// don't wait for load to finish
db.load().catch(e => {
if (e.toString() !== 'ReadError: Database is not open') {
reject(e)
} else {
assert.equal(db._cache.store, null)
resolve()
}
})
await db.close()
})
})
it('load, add one, close - several times', async () => {

View File

@ -22,7 +22,7 @@ const ipfsPath2 = './orbitdb/tests/replicate-and-load/2/ipfs'
Object.keys(testAPIs).forEach(API => {
describe(`orbit-db - Replicate and Load (${API})`, function() {
this.timeout(config.timeout)
this.timeout(config.timeout * 2)
let ipfsd1, ipfsd2, ipfs1, ipfs2
let orbitdb1, orbitdb2, db1, db2
@ -112,13 +112,16 @@ Object.keys(testAPIs).forEach(API => {
for (let i = 0; i < entryCount; i ++)
entryArr.push(i)
console.log("Writing to database...")
await mapSeries(entryArr, (i) => db1.add('hello' + i))
console.log("Done")
return new Promise((resolve, reject) => {
timer = setInterval(async () => {
const items = db2.iterator({ limit: -1 }).collect()
if (items.length === entryCount) {
if (db2._oplog.length === entryCount) {
clearInterval(timer)
const items = db2.iterator({ limit: -1 }).collect()
assert.equal(items.length, entryCount)
assert.equal(items[0].payload.value, 'hello0')
assert.equal(items[items.length - 1].payload.value, 'hello99')

View File

@ -3,9 +3,6 @@ module.exports = {
dbname: 'orbit-db-tests',
defaultIpfsConfig: {
start: true,
EXPERIMENTAL: {
pubsub: true
},
config: {
Addresses: {
API: '/ip4/127.0.0.1/tcp/0',
@ -25,9 +22,6 @@ module.exports = {
}
},
daemon1: {
EXPERIMENTAL: {
pubsub: true
},
config: {
Addresses: {
API: '/ip4/127.0.0.1/tcp/0',
@ -47,9 +41,6 @@ module.exports = {
},
},
daemon2: {
EXPERIMENTAL: {
pubsub: true
},
config: {
Addresses: {
API: '/ip4/127.0.0.1/tcp/0',

View File

@ -15,7 +15,7 @@ const startIpfs = (type, config = {}) => {
}
// If we're starting a process, pass command line arguments to it
if (!config.args) {
if (!config.args && type.includes('go')) {
config.args = ['--enable-pubsub-experiment']
}

View File

@ -1,4 +1,5 @@
const IPFS = require('ipfs')
const IPFSHTTPClient = require('ipfs-http-client')
/**
* IPFS daemons to run the tests with.
@ -8,7 +9,7 @@ const IPFS = require('ipfs')
// https://github.com/ipfs/js-ipfsd-ctl#ipfsfactory---const-f--ipfsfactorycreateoptions
let jsIpfs = {
'js-ipfs': {
type: 'proc',
type: 'proc',
exec: IPFS,
}
}
@ -16,6 +17,7 @@ let jsIpfs = {
const goIpfs = {
'go-ipfs': {
type: 'go',
IpfsClient: IPFSHTTPClient,
}
}

View File

@ -7,6 +7,7 @@ const path = require('path')
const rmrf = require('rimraf')
const levelup = require('levelup')
const leveldown = require('leveldown')
const Zip = require('adm-zip')
const OrbitDB = require('../src/OrbitDB')
const OrbitDBAddress = require('../src/orbit-db-address')
const io = require('orbit-db-io')
@ -27,25 +28,30 @@ const {
testAPIs,
} = require('./utils')
const dbPath = './orbitdb/tests/v0'
const dbPath = path.join('./orbitdb', 'tests', 'v0')
const dbFixturesDir = path.join('./test', 'fixtures', 'v0', 'QmWDUfC4zcWJGgc9UHn1X3qQ5KZqBv4KCiCtjnpMmBT8JC', 'v0-db')
const keyFixtures = path.join('./test', 'fixtures', 'keys','QmRfPsKJs9YqTot5krRibra4gPwoK4kghhU8iKWxBjGDDX')
const keyFixtures = './test/fixtures/keys/QmRfPsKJs9YqTot5krRibra4gPwoK4kghhU8iKWxBjGDDX'
const dbFixturesDir = './test/fixtures/v0/QmWDUfC4zcWJGgc9UHn1X3qQ5KZqBv4KCiCtjnpMmBT8JC/v0-db'
const ipfsFixturesDir = './test/fixtures/ipfs'
const ipfsFixtures = path.join('./test', 'fixtures', 'ipfs.zip')
const ipfsFixturesDir = path.join('./test', 'fixtures', 'ipfs')
Object.keys(testAPIs).forEach(API => {
describe(`orbit-db - Backward-Compatibility - Open & Load (${API})`, function () {
this.retries(1) // windows...
this.timeout(config.timeout)
let ipfsd, ipfs, orbitdb, db, address, store
let ipfsd, ipfs, orbitdb, db, address, keystore
let localDataPath
before(async () => {
ipfsd = await startIpfs(API, config.daemon1)
ipfs = ipfsd.api
rmrf.sync(dbPath)
const zip = new Zip(ipfsFixtures)
await zip.extractAllToAsync(path.join('./test', 'fixtures'), true)
const filterFunc = (src, dest) => {
// windows has problems copying these files...
return !(src.includes('LOG') || src.includes('LOCK'))
@ -54,29 +60,31 @@ Object.keys(testAPIs).forEach(API => {
// copy data files to ipfs and orbitdb repos
await fs.copy(path.join(ipfsFixturesDir, 'blocks'), path.join(ipfsd.path, 'blocks'))
await fs.copy(path.join(ipfsFixturesDir, 'datastore'), path.join(ipfsd.path, 'datastore'), { filter: filterFunc })
await fs.copy(dbFixturesDir, path.join(dbPath, ipfs._peerInfo.id._idB58String, 'cache'))
store = await storage.createStore(path.join(dbPath, ipfs._peerInfo.id._idB58String, 'keys'))
const keystore = new Keystore(store)
const store = await storage.createStore(path.join(dbPath, ipfs._peerInfo.id._idB58String, 'keys'))
keystore = new Keystore(store)
let identity = await Identities.createIdentity({ id: ipfs._peerInfo.id._idB58String, migrate: migrate(keyFixtures), keystore })
orbitdb = await OrbitDB.createInstance(ipfs, { directory: dbPath, identity, keystore })
orbitdb = await OrbitDB.createInstance(ipfs, { identity, keystore })
})
after(async () => {
await store.close()
rmrf.sync(dbPath)
await keystore.close()
if (orbitdb)
await orbitdb.stop()
if (ipfsd)
await stopIpfs(ipfsd)
rmrf.sync(ipfsFixturesDir)
})
describe('Open & Load', function () {
describe('Open & Load - V0 entries', function () {
before(async () => {
db = await orbitdb.open('/orbitdb/QmWDUfC4zcWJGgc9UHn1X3qQ5KZqBv4KCiCtjnpMmBT8JC/v0-db', { accessController: { type: 'legacy-ipfs', skipManifest: true } })
await fs.copy(dbFixturesDir, dbPath)
db = await orbitdb.open('/orbitdb/QmWDUfC4zcWJGgc9UHn1X3qQ5KZqBv4KCiCtjnpMmBT8JC/v0-db', { directory: dbPath, accessController: { type: 'legacy-ipfs', skipManifest: true } })
const localFixtures = await db._cache.get('_localHeads')
const remoteFixtures = await db._cache.get('_remoteHeads')
db._cache.set(db.localHeadsPath, localFixtures)
@ -93,6 +101,7 @@ Object.keys(testAPIs).forEach(API => {
})
after(async () => {
rmrf.sync(dbPath)
if (db)
await db.close()
})
@ -123,10 +132,76 @@ Object.keys(testAPIs).forEach(API => {
it('allows migrated key to write', async () => {
const hash = await db.add({ thing: 'new addition' })
const newEntries = db.all.filter(e => e.v === 1)
const newEntries = db.all.filter(e => e.v > 0)
assert.equal(newEntries.length, 1)
assert.strictEqual(newEntries[0].hash, hash)
})
})
describe('Open & Load - V1 entries', function () {
const dbPath2 = './orbitdb/tests/v1'
const dbv1Fix = './test/fixtures/v1/QmZrWipUpBNx5VjBTESCeJBQuj4rWahZMz8CV8hBjdJAec/cache'
const v1Address = '/orbitdb/zdpuAqpKBwd7ojM77o3rRVKA1PAEQBnWoRASY3ugJ7zqnM6z7/v1-entries'
before(async () => {
await fs.copy(dbv1Fix, dbPath2)
db = await orbitdb.open(v1Address, { directory: dbPath2 })
await db.load()
})
beforeEach(async () => {
if (process.platform === 'win32') {
// for some reason Windows does not load the database correctly at the first time.
// this is not a good solution but... it works.
await db.load()
}
})
after(async () => {
rmrf.sync(dbPath2)
if (db)
await db.close()
})
it('open v1 orbitdb address', async () => {
assert.notEqual(db, null)
})
it('database has the correct v1 address', async () => {
assert.equal(db.address.toString().indexOf('/orbitdb'), 0)
assert.equal(db.address.toString().indexOf('zd'), 9)
assert.equal(db.address.toString().indexOf('v1-entries'), 59)
})
it('has the correct type', async () => {
assert.equal(db.type, 'feed')
})
it('database has the correct access-controller', async () => {
assert.equal(db.access.type, 'ipfs')
assert.equal(db.options.accessControllerAddress, '/ipfs/zdpuAsYRtJLLLDibnmxWPzyRGJEqtjmJP27ppKWcLreNGGTFN')
assert.strictEqual(db.access.write[0], '*')
})
it('load v1 orbitdb address', async () => {
assert.equal(db.all.length, 100)
})
it('allows adding new entry', async () => {
const hash = await db.add('new entry')
const newEntries = db.all.filter(e => e.v > 1)
assert.equal(newEntries.length, 1)
assert.strictEqual(newEntries[0].hash, hash)
})
it('reopens db after adding new entry', async () => {
await db.close()
db = await orbitdb.open(v1Address, { directory: dbPath2 })
assert.notEqual(db, null)
await db.load()
assert.equal(db.all.length, 101)
const newEntries = db.all.filter(e => e.v > 1)
assert.equal(newEntries.length, 1)
})
})
})
})