Skip to content
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
131 commits
Select commit Hold shift + click to select a range
fba4dee
Added README skeleton
Mikerah Jan 7, 2019
5739dfd
Added skeleton Gossipsub class based on libp2p's floodsub class struc…
Mikerah Jan 8, 2019
76cdd26
Added message directory and changed the rpc protobuf format
Mikerah Jan 8, 2019
bf78ed6
Created messageCache.js
Mikerah Jan 8, 2019
72a11d4
Added dependencies for using protobufs and fixed the protobuf file fo…
Mikerah Jan 8, 2019
affafc8
Added peer.js and utils.js from js-libp2p-floodsub and added appropri…
Mikerah Jan 9, 2019
33c9c54
Completed an initial implementation of the message cache for gossipsu…
Mikerah Jan 9, 2019
112ed3a
Some preliminary refactoring
Mikerah Jan 9, 2019
b74ecc4
started implementation of control message handlers
Mikerah Jan 10, 2019
ceaea5f
More preliminary refactoring
Mikerah Jan 10, 2019
6a46922
Added functions from js-libp2p-floodsub that might be relevant for im…
Mikerah Jan 10, 2019
c6a625d
Fixed some minor bugs
Mikerah Jan 11, 2019
bdf3228
Changed the return type of the get function in the message cache data…
Mikerah Jan 11, 2019
8bbb62f
Completed handleIWant and handleIhave functions. Will do some tests l…
Mikerah Jan 12, 2019
a970bbb
Completed handleGraft
Mikerah Jan 14, 2019
0e5d249
Completed all handle functions for the different ctrl msgs
Mikerah Jan 14, 2019
2f55dbb
Changed code design. Decided to have GossipSub be a subclass of Flood…
Mikerah Jan 21, 2019
beae133
Did a little bit of clean up, added documentation and fixed non-worki…
Mikerah Jan 24, 2019
74d186a
Added 2 helper functions from js-libp2p-floodsub
Mikerah Jan 24, 2019
ba72c5d
Completed subscribe function
Mikerah Jan 29, 2019
56c3bed
Completed publish, subscribe and unsubscribe
Mikerah Jan 29, 2019
c7fd88a
Fixed constructor in messageCache.js
Mikerah Jan 30, 2019
94e97d3
Completed initial version of heartbeat for managing the mesh
Mikerah Jan 30, 2019
e1e0dcb
Completed heartbeat functionality.
Mikerah Feb 6, 2019
4b4dad4
updated package.json
Mikerah Feb 7, 2019
dfe820f
Updated repo structure
Mikerah Feb 7, 2019
1570cd0
Started message cache tests and updated package.json
Mikerah Feb 8, 2019
6757b14
All tests for the message cache except for shifting pass. Debugged me…
Mikerah Feb 9, 2019
bebeebf
Completed messageCache tests. Resolves #3
Mikerah Feb 12, 2019
9167bb7
Renamed messageCache functions and made design changes regarding enco…
Mikerah Feb 12, 2019
24851d6
Made changes to the README based on Vasco's suggestions
Mikerah Feb 12, 2019
34e5d5a
Removed uneeded dependency in package.json
Mikerah Feb 12, 2019
eef548e
Made changes that Vasco suggested to the message cache data structure
Mikerah Feb 13, 2019
0206925
Made changes to protobuf files as per Vasco's suggestions
Mikerah Feb 13, 2019
2436b05
Renamed tests to test
Mikerah Feb 13, 2019
f5c6e6e
Added a constants.js file and updated index.js accordingly
Mikerah Feb 13, 2019
9ad06cd
Minor edit to description of the fanout mapping.
vasco-santos Feb 13, 2019
47930f4
Removed dependency from package.json
Mikerah Feb 14, 2019
dc2f1fc
Changed when heartbeatTimer is called and overrode both start and sto…
Mikerah Feb 14, 2019
ecfb30c
Switch from using setImmediate to nextTick as per Vasco's suggestion
Mikerah Feb 14, 2019
91e5d42
Simplified conditionals statements as per Vasco's suggestions
Mikerah Feb 14, 2019
5075903
Re-implemented heartbeat timer functionality.
Mikerah Feb 16, 2019
11834c8
Updated package.json
Mikerah Feb 16, 2019
7fa5df3
More debugging and started writing tests
Mikerah Feb 19, 2019
24b3543
Updated package.json
Mikerah Feb 19, 2019
7a5f16c
Fixed scoping bug affecting heartbeat function
Mikerah Feb 20, 2019
d8fa84c
Fixed typos
Mikerah Feb 20, 2019
1edb911
Finally got a hold of starting to fix the subscribe functionality.
Mikerah Feb 22, 2019
3da46f1
Updated comment for fanout map
vasco-santos Mar 13, 2019
5e20f38
Updated comments
Mikerah Mar 13, 2019
8786e25
Added changes requested by Vasco and Greg
Mikerah Mar 13, 2019
f1b11c0
Merge branch 'gossip_implementation' of github.com:ChainSafeSystems/g…
Mikerah Mar 13, 2019
bc0447e
Fixed conflicts
Mikerah Mar 13, 2019
8b890db
linted 2-nodes.js
Mikerah Mar 14, 2019
2ad2c05
linted constants.js
Mikerah Mar 14, 2019
78e66f6
updated package.json
Mikerah Mar 29, 2019
0b93b94
linted and bug fixes
Mikerah Mar 29, 2019
df7a597
Added Cayman's suggestions
Mikerah Apr 1, 2019
f953ad5
Fixed and debugged subscribe functionality
Mikerah Apr 2, 2019
1bc3198
Debugged removing of peers once a connection ends
Mikerah Apr 3, 2019
4144639
Updated package.json to include Vasco's suggestions
Mikerah Apr 17, 2019
b5313fd
Rewrote messageCache tests so that each test case is independent of e…
Mikerah Apr 17, 2019
c10747f
Add override tag to _onDial
vasco-santos Apr 17, 2019
03bd5cb
Changed undefined tag to void tag
vasco-santos Apr 17, 2019
26cc50f
Merge branch 'gossip_implementation' of github.com:ChainSafe/gossipsu…
Mikerah Apr 17, 2019
ecf7b7f
Changed the require statement for the rpc protobufs
vasco-santos Apr 17, 2019
73b3adf
Fix heartbeatTimer
wemeetagain Apr 16, 2019
de8ea9c
Use rpc.RPC
wemeetagain Apr 17, 2019
2b2b7db
Fix linter issues
wemeetagain Apr 17, 2019
ab0ab2f
Update libp2p-pubsub to 0.0.3
wemeetagain Apr 17, 2019
1a173f1
Clean up packages version / lock
wemeetagain Apr 17, 2019
a2dc1cc
Clean up 2-node tests
wemeetagain Apr 23, 2019
005ac63
Clean up _removePeer
wemeetagain Apr 23, 2019
e53e129
Clean up _rpcWithControl
wemeetagain Apr 23, 2019
cbe2db8
Clean up _handlePrune
wemeetagain Apr 23, 2019
52cad48
Replace _nowInNano with _now
wemeetagain Apr 23, 2019
f157015
Add _sendRpc and piggyback functions
wemeetagain Apr 23, 2019
d6e3aee
Clean up subscribe/unsubscribe
wemeetagain Apr 23, 2019
5fdac8e
Clean up publish
wemeetagain Apr 23, 2019
b0177b5
Clean up _heartbeat
wemeetagain Apr 23, 2019
e46f5a1
Clean up _processRpcMessages
wemeetagain Apr 23, 2019
13b6d3d
Clean up _onRpc
wemeetagain Apr 23, 2019
5cfa016
Clean up _handleIHave
wemeetagain Apr 23, 2019
fad2c9f
Clean up _handleIWant
wemeetagain Apr 23, 2019
b74ea23
Clean up _handleGraft
wemeetagain Apr 23, 2019
fefdef5
Clean up _sendGraft
wemeetagain Apr 23, 2019
b162fb5
Clean up _sendPrune
wemeetagain Apr 23, 2019
a912b6c
Fix stop comment
wemeetagain Apr 23, 2019
f527ae8
Clean up multiple-node tests
wemeetagain Apr 23, 2019
3b9aa4d
Remove browser test
wemeetagain Apr 23, 2019
03c518a
Move promisify to devDependencies
wemeetagain Apr 23, 2019
f82f474
Update libp2p-pubsub to 0.0.4
wemeetagain Apr 24, 2019
d776f16
Move devDependencies
wemeetagain Apr 24, 2019
287dc05
Use newer style import for MessageCache
wemeetagain Apr 24, 2019
8606234
Replace lets with consts
wemeetagain Apr 24, 2019
916a2a6
Clean up rpc handling functions
wemeetagain Apr 24, 2019
fb3a7b5
Clean up start
wemeetagain Apr 24, 2019
0488d47
Clean up stop
wemeetagain Apr 24, 2019
de067ad
Clean up subscribe
wemeetagain Apr 24, 2019
b476cc4
Clean up unsubscribe
wemeetagain Apr 24, 2019
65d09f2
Add assert to publish
wemeetagain Apr 24, 2019
369e929
Clean up piggyback
wemeetagain Apr 24, 2019
4ccf644
Clean up _getPeers
wemeetagain Apr 24, 2019
ded7ef3
Clean up _sendGraftPrune
wemeetagain Apr 24, 2019
1f350a7
Clean up rpc functions
wemeetagain Apr 24, 2019
89c50a4
Clean up testing
wemeetagain Apr 27, 2019
4ea637d
Add flush of gossip and control to heartbeat
wemeetagain Apr 28, 2019
d1e0e35
Refactor basic pubsub functionality
wemeetagain Apr 28, 2019
37e3ca7
Remove travis commitlint step
wemeetagain May 8, 2019
f4e296e
Refactor heartbeat
wemeetagain May 8, 2019
bf1f731
Add message signing
wemeetagain May 9, 2019
f945810
Fix/simplify heartbeat
wemeetagain May 9, 2019
7094830
Add heartbeat tests
wemeetagain May 9, 2019
289cda2
Add mesh overlay tests
wemeetagain May 9, 2019
40ca723
Fix gossiping
wemeetagain May 9, 2019
6841dee
Add gossip tests
wemeetagain May 9, 2019
b89fe3f
Add messageCache test
wemeetagain May 9, 2019
f3d1b21
Fix gossip/control piggyback
wemeetagain May 10, 2019
e9dd2cc
Add piggyback test
wemeetagain May 10, 2019
19bd1d4
Tweak multiple node test
wemeetagain May 10, 2019
a4c3937
Extend mesh timeout
wemeetagain May 10, 2019
471a618
Extend heartbeat test margin of error
wemeetagain May 10, 2019
55368cf
Fix mesh test check
wemeetagain May 10, 2019
2c7123b
Update src/heartbeat.js
wemeetagain May 13, 2019
3c76300
Update heartbeat error callback
wemeetagain May 13, 2019
665a74c
Change pubsub noops to error throws
wemeetagain May 13, 2019
c9410bf
Bound test timeouts
wemeetagain May 13, 2019
298ebd7
Remove file-wide eslint disables, lint
wemeetagain May 13, 2019
10aa17c
Update readme
wemeetagain May 13, 2019
8cba0c7
Increase test timeouts
wemeetagain May 13, 2019
34f5c09
Increase test timeouts
wemeetagain May 13, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,13 @@
# gossipsub-js
Javascript implementation of Gossipsub
Javascript implementation of Gossipsub.

Comment thread
Mikerah marked this conversation as resolved.
## Overview
Gossipsub is an implementation of pubsub based on meshsub and floodsub. You can read the specification [here](https://github.com/libp2p/specs/tree/master/pubsub/gossipsub).

## Install

## Usage

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please complete the README.md first?

References:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it looks like the API documentation was autogenerated in both cases.
I left the API section blank for now.


## API

## Contribute
228 changes: 228 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
'use strict'
Comment thread
Mikerah marked this conversation as resolved.
Outdated

const libp2p = require('libp2p')
const EventEmitter = require('events')
const values = require('lodash/values')
const pull = require('pull-stream')
const asyncEach = require('async/each')
const setImmediate = require('async/setImmediate')
const debug = require('debug')

const pb = require('./message')
const MessageCache = require('./messageCache')
const utils = require('./utils')
const Peer = require('./peer') // Will switch to js-peer-info once stable

// Overlay parameters
const GossipSubD = 6
const GossipSubDlo = 4
const GossipSubDhi = 12

// Gossip parameters
const GossipSubHistoryLength = 5
const GossipSubHistoryGossip = 3

// Heartbeat interval
const GossipSubHeartbeatInitialDelay = 100 // In milliseconds
const GossipSubHeartbeatInterval = 1 // In seconds

// Fanout ttl
const GossipSubFanoutTTL = 60 // in seconds


class GossipSub extends EventEmitter {

constructor (debugName, multicodec, libp2p) {
super()

this.log = debug(debugName)
this.log.err = debug(`${debugName}:error`)
this.multicodec = multicodec
this.libp2p = libp2p
this.started = false

/**
* Map of peers.
* Some peers will be gossipsub peers while others will be floodsub peers
* @type {Map<string, Peer>}
*/
this.peers = new Map()

/**
* Map of topic meshes
*
* @type {Map<string, Set<Peer>>}
*/
this.mesh = new Map()

/**
* Map of topics to lists of peers. These mesh peers are peers to which we are publishing to without topic membership
*
*@type {Map<string, Set<Peer>>}
*/
this.fanout = new Map()

/**
* Map of last publish time for fanout topics
* Note: Could use https://github.com/chjj/n64 to get an int64 obj in JS
*@type {Map<string,int64>}
*/
this.lastpub = new Map()

/**
* Map of pending messages to gossip
*
* @type {Map<Peer, string[]> }
*/
this.gossip = new Map()

/**
* Map of control messages
*
* @type {Map<Peer, string>}
*/
this.control = new Map()

/**
* A message cache that contains the messages for last few hearbeat ticks
*
*/
this.messageCache = new MessageCache()
}


/**
* The next few functions will be copied over from the js-libp2p-floodsub
* repository. Might need to copy over the base.js file from the js-libp2p-floodsub repository
*
*/
_addPeer (peer) {
const id = peer.info.id.toB58String()

/*
Always use an existing peer.
What is happening here is: "If the other peer has already dialed to me, we already have
an establish link between the two, what might be missing is a
Connection specifically between me and that Peer"
*/
let existing = this.peers.get(id)
if (!existing) {
this.log('new peer', id)
this.peers.set(id, peer)
existing = peer

peer.once('close', () => this._removePeer(peer))
}
++existing._references

return existing
}

_removePeer (peer) {
const id = peer.info.id.toB58String()

this.log('remove', id, peer._references)
// Only delete when no one else if referencing this peer.
if (--peer._references === 0){
this.log('delete peer', id)
this.peers.delete(id)

// Remove this peer from the mesh
for(let topic, peers of this.mesh.entries()){
peers.delete(peer)
}
// Remove this peer from the fanout
for (let topic, peers of this.fanout.entries()){
peers.delete(peer)
}

// Remove from gossip mapping
this.gossip.delete(peer)
// Remove from control mapping
this.control.delete(peer)
}
}

_onRpc(idB58Str, rpc) {
if(!rpc){
return
}

this.log('rpc from', idB58Str)
const controlMsg = rpc.control

const iwant = this.handleIHave(idB58Str, controlMsg)
const ihave = this.handleIWant(idB58Str, controlMsg)
const prune = this.handleGraft(idB58Str, controlMsg)
this.handlePrune(idB58Str, controlMsg)


}

handleIHave(id, controlMsg) {

}

handleIWant(id, controlMsg) {

}

handleGraft(id, controlMsg) {

}

handlePrune(id, controlMsg) {

}

_processRpcControlMsgs() {

}


/**
* Mounts the gossipsub protocol onto a libp2p node
* and sends subscriptions to every peer as per the protocol
*
* @param {Function} callback
* @return {undefined}
*/
start (callback) {
}

/**
* Publish messages to the given topics
*
* @param {Array<string>|string} topics
* @param {Array<any>|any} messages
* @returns {undefined}
*/
publish (topics, messages) {
}

/**
* Subscribe to the given topics
* @param {Array<string>|string} topics
* @returns {undefined}
*/
subscribe (topics) {
}

/**
* Unsubscribe from the given topics
* @param {Array<string>|string} topics
* @returns {undefined}
*/
unsubscribe (topics) {
}

/**
* Unmounts the gossipsub protocol and shuts down every connection
*
*/
stop (callback) {
}

}

module.exports = GossipSub
10 changes: 10 additions & 0 deletions message/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
'use strict'

const protons = require('protons')

const rpcProto = protons(require('./rpc.proto.js'))
const topicDescriptorProto = protons(require('./topic-descriptor.proto.js'))

exports = module.exports
exports.rpc = rpcProto
exports.td = topicDescriptorProto
44 changes: 44 additions & 0 deletions message/rpc.proto.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
'use strict'
module.exports = `
message RPC {
repeated SubOpts subscriptions = 1;
repeated Message msgs = 2;

message SubOpts {
optional bool subscribe = 1; // subscribe or unsubcribe
optional string topicCID = 2;
}

message Message {
optional bytes from = 1;
optional bytes data = 2;
optional bytes seqno = 3;
repeated string topicIDs = 4;
}

optional ControlMessage control = 3;

message ControlMessage {
repeated ControlIHave ihave = 1;
repeated ControlIWant iwant = 2;
repeated ControlGraft graft = 3;
repeated ControlPrune prune = 4;
}

message ControlIHave {
optional string topicID = 1;
repeated string messageIDs = 2;
}

message ControlIWant {
repeated string messageIDs = 1;
}

message ControlGraft {
optional string topicID = 1;
}

message ControlPrune {
optional string topicID = 1;
}
}`
30 changes: 30 additions & 0 deletions message/topic-descriptor.proto.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
'use strict'
module.exports = `
// topicCID = cid(merkledag_protobuf(topicDescriptor)); (not the topic.name)
message TopicDescriptor {
optional string name = 1;
optional AuthOpts auth = 2;
optional EncOpts enc = 2;

message AuthOpts {
optional AuthMode mode = 1;
repeated bytes keys = 2; // root keys to trust

enum AuthMode {
NONE = 0; // no authentication, anyone can publish
KEY = 1; // only messages signed by keys in the topic descriptor are accepted
WOT = 2; // web of trust, certificates can allow publisher set to grow
}
}

message EncOpts {
optional EncMode mode = 1;
repeated bytes keyHashes = 2; // the hashes of the shared keys used (salted)

enum EncMode {
NONE = 0; // no encryption, anyone can read
SHAREDKEY = 1; // messages are encrypted with shared key
WOT = 2; // web of trust, certificates can allow publisher set to grow
}
}
}`
Loading