-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor, Mock API, more tests #1
Conversation
… runs under the test environment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome work @fazo96. Really loving the progress you are making.
I have left a few notes and suggestions. I would say, those comments that you think are future work, we should create issues for those. Can you do that?
And those you think you want to address as part of this PR itself, you can address them. The decision is up to you.
Send me a ping on slack later and I can merge once you confirm.
This module has not been release to NPM yet. You can however install it and import/require it, but it's still WIP. Check out [index.js](https://github.com/ChluNetwork/chlu-ipfs-support/blob/master/src/index.js) to see the available API calls, and the tests for examples. | ||
|
||
You can install this module globally and use `chlu-service-node` to run a Chlu Service Node. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fazo96 why do we need this to be installed globally? Can't one install it in a local folder and then run it with the required permissions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can also be installed locally: in any folder, run npm install chlu-ipfs-support
. The binary should be available under ./node_modules/chlu-ipfs-support/bin/
like any other npm module.
This binary just starts ChluIPFS and its service node routines for now, there are still a lot of improvements to make and tests to run
Addresses: { | ||
Swarm: [ | ||
// Enable WebSocketStar transport | ||
'/dns4/ws-star.discovery.libp2p.io/tcp/443/wss/p2p-websocket-star' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fazo96 did you check this endpoint is the same one used by orbitdb in their web examples?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it is: https://github.com/orbitdb/orbit-db/blob/master/examples/browser/example.js#L57
For now this is the only IPFS transport that is stable in the browser.
store: String(Math.random() + Date.now()) | ||
}; | ||
// TODO: review persisting data in orbitDb. we don't need persistence in the browser but it would help. | ||
this.orbitDbDirectory = options.orbitDbDirectory || '../orbit-db'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What will happen in the case of browser? I guess we should make sure we are setup properly for the browser use case.
I am also thinking if we should have a separate repo for chlu-service-node, so there we can have options and setup optimisations for a node process, and in this repo we only have browser setup options. Does that make sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the browser at the moment we don't persist OrbitDB. This is acceptable because the owner of the DB can replicate it from other nodes in the network, but we will change this anyway since there's no reason not to keep a copy in the browser.
When I wrote this code OrbitDB only had filesystem persistence (which obviously does not work in the browser) however they just changed it to an implementation using LevelDB: orbitdb/orbitdb#272
I opened an issue to track how we persist data: #4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am also thinking if we should have a separate repo for chlu-service-node, so there we can have options and setup optimisations for a node process, and in this repo we only have browser setup options. Does that make sense?
In the future we should probably take out the chlu service node as it becomes a more fleshed out application but for now it's so simple that I think it's ok for it to be in here.
About splitting the browser and node.js parts, I believe it's not a good idea because most of the code is the same and many of the differences are handled automatically by OrbitDB and IPFS themselves. It would introduce complexity for no benefits.
However we need to make sure everything works fine in the browser. I opened an issue about this: #5
src/ChluIPFS.js
Outdated
this.orbitDb = new OrbitDB(this.ipfs, this.orbitDbDirectory); | ||
} | ||
if (this.type === constants.types.customer && !this.db) { | ||
this.db = await this.orbitDb.feed('chlu-experimental-customer-review-updates'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we should have names like these in a constants file somewhere. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, I should put it with the other constants
if (this.ipfs.pin) { | ||
await this.ipfs.pin.add(multihash, { recursive: true }); | ||
} else { | ||
// TODO: Chlu service node need to be able to pin, so we should support using go-ipfs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do think the chlu service node should really be based on go-ipfs. Couple of reasons, 1) probably more mature implementation with more features and 2) probably less resource intensive. For the same reason I am in favour of a chlu-service-node-js and later a chlu-service-node-go repo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, when possible we should use go-ipfs. Lucky for us, we can talk to go-ipfs using js-ipfs-api, which has the same exact calls to js-ipfs with the difference that js-ipfs-api forwards calls to go-ipfs via HTTP and js-ipfs executes them in javascript.
This means we can support running ChluIPFS on top of go-ipfs (or any other ipfs implementation really) with configuration options.
We need to verify that go-ipfs can connect to js-ipfs nodes running in the browser. This might be an issue, in the browser we can only use the websocket-star transport and it's unclear wether it can connect to the go-ipfs websocket transport at the moment (https://github.com/libp2p/go-ws-transport) even though it should eventually.
I created an issue for this: #3
const dagNode = await this.ipfs.object.put(reviewRecord); | ||
const multihash = this.utils.multihashToString(dagNode.multihash); | ||
// Broadcast request for pin, then wait for response | ||
// TODO: handle a timeout and also rebroadcast periodically, otherwise new peers won't see the message |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be good to have a timeout as you said, but maybe use an exponential backoff while retrying. I am surprised orbitdb doesn't do that already
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I never thought about retrying but it makes a lot of sense
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I opened an issue about this: #6
} | ||
|
||
async start(){ | ||
await time.milliseconds(1000); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The time out thing is interesting. I can see it will be nice in the development mode. But it might unnecessarily slow us down for testing in a CI env. Can this be made optional? or maybe we have production, development, testing, three different modes? What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I put these in to simulate that these actions take some time with a real implementation. They are already disabled in the tests because the time.milliseconds function is mocked to return immediately so there are no artificial slowdowns when running the automated tests
At the moment I don't think we need three separate modes
} | ||
|
||
async importData() { | ||
throw new Error('not implemented'); | ||
async importData(exportedData) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what data do exportData and importData do? Maybe we can change these function names to more meaningful or descriptive names?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes that's a good idea, but first I need to figure out a good format for exporting what we need.
Both OrbitDB and IPFS have almost no support for exporting and importing keys so this could require some hacks, although I'm confident it's possible
@@ -0,0 +1,49 @@ | |||
#!/usr/bin/env node |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an awesome integration test. WIll travis ci be able to run this? I guess we'll find out soon. I'll set up travis as soon as we have merged this PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I enabled travis for my fork and this test passed 👍 I just copied the way OrbitDB did tests.
I moved a couple of hardcoded strings to the constants.js file. I think this PR can be merged now |
This PR is big, but the code was not very modular and the Mock API required moving most of the main logic, so I did some general refactoring.
Highlights of this PR:
mock: true
when creating the ChluIPFS instance. The mock API returns stubbed values and even fake-waits a couple of seconds on calls