mirror of
https://github.com/orbitdb/orbitdb.git
synced 2025-06-23 14:32:30 +00:00
commit
187422e7dd
4
API.md
4
API.md
@ -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).*
|
||||
|
3
Makefile
3
Makefile
@ -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
31322
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
20
package.json
20
package.json
@ -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"
|
||||
},
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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;">
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
108
test/feed-load.test.js
Normal 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
BIN
test/fixtures/ipfs.zip
vendored
Normal file
Binary file not shown.
@ -1 +0,0 @@
|
||||
¢dtypedipfsfparams¡gaddressx1zdpuAuhwhxGZSjWRqPBxfKoPEyF9gZHbKXvGqNtK9TEPJtj67
|
@ -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"}
|
Binary file not shown.
@ -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>
|
@ -1,2 +0,0 @@
|
||||
|
||||
h{"name":"v0-db","type":"feed","accessController":"/ipfs/Qmc3S7aMSmH8oGmx7Zdp8UxVWcDyCq5o2H9qYFgT3GW6nM"}
|
@ -1,8 +0,0 @@
|
||||
|
||||
º{
|
||||
"admin": [],
|
||||
"write": [
|
||||
"04b54f6ef529cd2dd2f9c6897a382c492222d42e57826269a38101ffe752aa07260ecd092a970d7eef08c4ddae2b7006ee25f07e4ab62fa5262ae3b51fdea29f78"
|
||||
],
|
||||
"read": []
|
||||
}
|
@ -1 +0,0 @@
|
||||
£dnameqcache-schema-testdtypehkeyvaluepaccessControllerx7/ipfs/zdpuAyfbHMCJgA1fL72eAq6pz7G3qKzGgLNZpnrHRbFexR6Zw
|
@ -1,4 +0,0 @@
|
||||
/
|
||||
" ĘI%Ľsć!@®<><őń'ŹŞ—ú8»đď@:µŃ<C2B5>o_÷directŤV2
|
||||
" ÝełßIž\(&PD¬
|
||||
<08> ô« 2ýhO.ß<>o» recursive¸V
|
@ -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"}
|
@ -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
|
||||
½
|
@ -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"}
|
Binary file not shown.
@ -1,3 +0,0 @@
|
||||
¡ewritexJ[
|
||||
"02b1a8717e8bdb12c29dae1a43ed83bc7621205c5ba3029a0ca842653c4a5a89d4"
|
||||
]
|
@ -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
|
||||
·
|
@ -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
|
||||
µ
|
@ -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.
|
||||
Š
|
@ -1,3 +0,0 @@
|
||||
|
||||
Index
|
||||
|
@ -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
|
||||
œ
|
@ -1 +0,0 @@
|
||||
©avbidxL/orbitdb/zdpuAkdtE84R9iHvk39m3qUJKP3RXD9c9EQJWVsLMXC4sYQFA/cache-schema-testckeyx‚040d2ae7ff5f52d41f65829f30b66eb2c85910f0c683d73ee3cead5d22c15702f32105cdfd83b031d6b2fa594d6ff725979e83bd23575dd26546ff1f30702eb507csigxŒ30440220328dedc06e17fb1a9cb9826c4daa1b5b8e9e609121d025389fccc49ce81787dc02202ea8ea8a691f8896c79bca42f5eba864daba5e920480c95cb88841d76e815308dhashödnext€eclock¢bidx‚040d2ae7ff5f52d41f65829f30b66eb2c85910f0c683d73ee3cead5d22c15702f32105cdfd83b031d6b2fa594d6ff725979e83bd23575dd26546ff1f30702eb507dtimegpayload£bopcPUTckeyckeyevalueevaluehidentity¤bidxB02b1a8717e8bdb12c29dae1a43ed83bc7621205c5ba3029a0ca842653c4a5a89d4dtypegorbitdbipublicKeyx‚040d2ae7ff5f52d41f65829f30b66eb2c85910f0c683d73ee3cead5d22c15702f32105cdfd83b031d6b2fa594d6ff725979e83bd23575dd26546ff1f30702eb507jsignatures¢bidxŒ304402200190b97ab06a0623a0fc0d9d7da60ff77515f0649a93d6a9dab3f3bd3bbfb4da02200520284db952c6f0a366b886b881ea5da5bd21a9c277f7d4d4fab1aa8e15682eipublicKeyxŽ3045022100c5e18a43dd47f915754ff964ff2c7f85dbc0a2827964553d648cf613baff6e4b02206e678964e12f8c1532b8d09116a9dc4dadf97b29e21199644b0130e39192259d
|
@ -1,4 +0,0 @@
|
||||
2
|
||||
" ’èžsÜL`•>¾P}ãÈD
|
||||
>ÚŸo_¸=¡"´u'Ò 0.0-intro§
|
||||
|
@ -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
|
||||
Г
|
@ -1,3 +0,0 @@
|
||||
-
|
||||
" õR ;<3B>—¿ˆfq<66>aU¿õ0[Xè@÷8Ó·O§¦index
|
||||
|
1
test/fixtures/ipfs/blocks/SHARDING
vendored
1
test/fixtures/ipfs/blocks/SHARDING
vendored
@ -1 +0,0 @@
|
||||
/repo/flatfs/shard/v1/next-to-last/2
|
Binary file not shown.
@ -1,2 +0,0 @@
|
||||
|
||||
|
22
test/fixtures/ipfs/blocks/_README
vendored
22
test/fixtures/ipfs/blocks/_README
vendored
@ -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.
|
86
test/fixtures/ipfs/config
vendored
86
test/fixtures/ipfs/config
vendored
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
BIN
test/fixtures/ipfs/datastore/000183.ldb
vendored
BIN
test/fixtures/ipfs/datastore/000183.ldb
vendored
Binary file not shown.
BIN
test/fixtures/ipfs/datastore/000187.ldb
vendored
BIN
test/fixtures/ipfs/datastore/000187.ldb
vendored
Binary file not shown.
BIN
test/fixtures/ipfs/datastore/000192.ldb
vendored
BIN
test/fixtures/ipfs/datastore/000192.ldb
vendored
Binary file not shown.
BIN
test/fixtures/ipfs/datastore/000197.ldb
vendored
BIN
test/fixtures/ipfs/datastore/000197.ldb
vendored
Binary file not shown.
BIN
test/fixtures/ipfs/datastore/000202.log
vendored
BIN
test/fixtures/ipfs/datastore/000202.log
vendored
Binary file not shown.
1
test/fixtures/ipfs/datastore/CURRENT
vendored
1
test/fixtures/ipfs/datastore/CURRENT
vendored
@ -1 +0,0 @@
|
||||
MANIFEST-000201
|
1
test/fixtures/ipfs/datastore/LOG
vendored
1
test/fixtures/ipfs/datastore/LOG
vendored
@ -1 +0,0 @@
|
||||
2019/09/01-11:44:16.574088 7fd834d96700 Delete type=3 #200
|
BIN
test/fixtures/ipfs/datastore/MANIFEST-000201
vendored
BIN
test/fixtures/ipfs/datastore/MANIFEST-000201
vendored
Binary file not shown.
1
test/fixtures/ipfs/datastore_spec
vendored
1
test/fixtures/ipfs/datastore_spec
vendored
@ -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"}
|
1
test/fixtures/ipfs/local/filesroot
vendored
1
test/fixtures/ipfs/local/filesroot
vendored
@ -1 +0,0 @@
|
||||
Y”„9_)ažô€Ë¹2¾RÅm™Å–keà9ð˜»ï
|
1
test/fixtures/ipfs/version
vendored
1
test/fixtures/ipfs/version
vendored
@ -1 +0,0 @@
|
||||
7
|
BIN
test/fixtures/v1/QmZrWipUpBNx5VjBTESCeJBQuj4rWahZMz8CV8hBjdJAec/cache/000003.log
vendored
Normal file
BIN
test/fixtures/v1/QmZrWipUpBNx5VjBTESCeJBQuj4rWahZMz8CV8hBjdJAec/cache/000003.log
vendored
Normal file
Binary file not shown.
1
test/fixtures/v1/QmZrWipUpBNx5VjBTESCeJBQuj4rWahZMz8CV8hBjdJAec/cache/CURRENT
vendored
Normal file
1
test/fixtures/v1/QmZrWipUpBNx5VjBTESCeJBQuj4rWahZMz8CV8hBjdJAec/cache/CURRENT
vendored
Normal file
@ -0,0 +1 @@
|
||||
MANIFEST-000002
|
1
test/fixtures/v1/QmZrWipUpBNx5VjBTESCeJBQuj4rWahZMz8CV8hBjdJAec/cache/LOG
vendored
Normal file
1
test/fixtures/v1/QmZrWipUpBNx5VjBTESCeJBQuj4rWahZMz8CV8hBjdJAec/cache/LOG
vendored
Normal file
@ -0,0 +1 @@
|
||||
2019/11/20-15:37:17.518217 7f2d57fff700 Delete type=3 #1
|
BIN
test/fixtures/v1/QmZrWipUpBNx5VjBTESCeJBQuj4rWahZMz8CV8hBjdJAec/cache/MANIFEST-000002
vendored
Normal file
BIN
test/fixtures/v1/QmZrWipUpBNx5VjBTESCeJBQuj4rWahZMz8CV8hBjdJAec/cache/MANIFEST-000002
vendored
Normal file
Binary file not shown.
BIN
test/fixtures/v1/QmZrWipUpBNx5VjBTESCeJBQuj4rWahZMz8CV8hBjdJAec/keystore/000003.log
vendored
Normal file
BIN
test/fixtures/v1/QmZrWipUpBNx5VjBTESCeJBQuj4rWahZMz8CV8hBjdJAec/keystore/000003.log
vendored
Normal file
Binary file not shown.
1
test/fixtures/v1/QmZrWipUpBNx5VjBTESCeJBQuj4rWahZMz8CV8hBjdJAec/keystore/CURRENT
vendored
Normal file
1
test/fixtures/v1/QmZrWipUpBNx5VjBTESCeJBQuj4rWahZMz8CV8hBjdJAec/keystore/CURRENT
vendored
Normal file
@ -0,0 +1 @@
|
||||
MANIFEST-000002
|
1
test/fixtures/v1/QmZrWipUpBNx5VjBTESCeJBQuj4rWahZMz8CV8hBjdJAec/keystore/LOG
vendored
Normal file
1
test/fixtures/v1/QmZrWipUpBNx5VjBTESCeJBQuj4rWahZMz8CV8hBjdJAec/keystore/LOG
vendored
Normal file
@ -0,0 +1 @@
|
||||
2019/11/20-15:37:17.490398 7f2d6ccf8700 Delete type=3 #1
|
BIN
test/fixtures/v1/QmZrWipUpBNx5VjBTESCeJBQuj4rWahZMz8CV8hBjdJAec/keystore/MANIFEST-000002
vendored
Normal file
BIN
test/fixtures/v1/QmZrWipUpBNx5VjBTESCeJBQuj4rWahZMz8CV8hBjdJAec/keystore/MANIFEST-000002
vendored
Normal file
Binary file not shown.
89
test/offline-mode.js
Normal file
89
test/offline-mode.js
Normal 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()
|
||||
})
|
||||
})
|
||||
})
|
@ -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 () => {
|
||||
|
@ -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')
|
||||
|
@ -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',
|
||||
|
@ -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']
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user