-
Notifications
You must be signed in to change notification settings - Fork 27
Conversation
db97b73
to
b8cca2d
Compare
603aea4
to
1093890
Compare
1093890
to
7d5b3c4
Compare
7c975af
to
fe6329f
Compare
fe6329f
to
d8671f9
Compare
@wemeetagain can you give a pass through this PR? I did these changes in parallel with the routers update libp2p/js-libp2p-floodsub#108 and ChainSafe/js-libp2p-gossipsub#122 which are successfully using this code now The main things left for me to finish tomorrow are improving the docs for usage and the refactor of the tests to include more than we had in libp2p-pubsub |
src/pubsub/index.js
Outdated
* @param {InMessage} msg | ||
* @returns {void} | ||
*/ | ||
_publishFrom (msg) { |
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 need to remove this according to the gossipsub last PR merged!
src/pubsub/README.md
Outdated
| Name | Type | Description | | ||
|------|------|-------------| | ||
| topics | `Array<string>|string` | set of pubsub topics | | ||
| [handler] | `function (msg)` | handler for messages received in the given topics | |
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 think the interface should only allow subscription/unsubscription of a single topic at a time.
Attaching a handler to multiple topics at once feels like an anti-pattern, or at least a less primary interface, in the same way we were previously attaching multiple topics to multiple messages at once in publish
.
I think this will simplify some of the underlying implementations, too. The body of our subscription code looks roughly like: for (const topic of topics) { /* doSubscribe(topic) */ }
. We would be able to remove this outer loop and better support extended behavior.
Also, go-libp2p-pubsub's interface for subscribing is for a single topic at a time, for what its worth.
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 that the API would look better with one topic. Taking into account that we are doing several breaking changes in pubsub, I think we should also change this.
The libp2p API doc also says a single topic, so we were supporting it below in the stack but we were not mentioning it. However, this should be pointed in the migration guide
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 about publish? Should we also just accept one topic per API call? That's how we have it in libp2p main docs as well
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.
👍 for publish also accepting a single topic per API call
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 will update it
src/pubsub/index.js
Outdated
* @returns {Uint8Array} | ||
*/ | ||
_encodeRpc (rpc) { | ||
throw errcode(new Error('_encodeRpc must be implemented by the subclass'), 'ERR_NOT_IMPLEMENTED') |
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 same way that _acceptFrom
returns a default implementation, we should consider providing default encoding/decoding using the base protobuf.
seqno: utils.randomSeqno(), | ||
topicIDs: topics | ||
} | ||
|
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.
pls copy the latest edits from gossipsub here, so we can have the signature already attached in _publish
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 looks like this wasn't copied exactly, there was a reason it was as it was before:
- we want to emit the message object with the optional signature (since other messages will be emitted with the signature and we shouldn't be treating self-published messages differently)
- _publish currently expects an "InMessage" message transformed using
utils.normalizeInRpcMessage
. It should be standardized bc this function is called in different contexts: self-publish and peer-publish. Also, all overridable methods that operate on messages (_publish, _processRpcMessage, etc) receive an "InMessage". It's nice to rely on that and not require overriders to call 'utils.normalizeInRpcMessage'.
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.
We had a test before stating: "should emit non normalized messages on publish" and that's why I put it like this.
I will revisit this in a bit
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.
Yeah, the code is a little screwy, I think a proper solution would be to allow an InMessage (plus private key) to be signed (and have signature/key attached).
What we were doing to get around all this was:
- create msg: InMessage
- normalize/sign
outMsg = await this.buildMessage(msg)
- set msg to the non-normalized msg, but including the signature (
msg = utils.normalizeInRpcMsg(outMsg)
) - then emit msg
- _publish(msg)
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 guess we can emit it normalized and signed for now. I don't see any reason against it. I changed to what you had before for now
src/pubsub/index.js
Outdated
* @param {function} [handler] | ||
* @returns {void} | ||
*/ | ||
subscribe (topics, handler) { |
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.
Previously, we had this broken into two levels subscribe
and _subscribe
.
Perhaps this can be better named, eg: subscribe
and _newSubscription
(or some other).
But the outer layer, subscribe
normalized input and removed existing subscriptions, so that _newSubscription
was able to be extended in a way that didn't need to renormalize + remove existing subscriptions, but rather acted on known new subscriptions.
Eg: In gossipsub, we want to call join
only on new subscriptions, so overriding just using this method becomes somewhat more cumbersome, than overriding a lower level method for "subscribing to new, previously unsubscribed topic".
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 went with not decoupling it because all these operations seem mandatory to do. For the gossipsub example, I changed it to:
subscribe (topics: string[], handler: (msg: any) => void): void {
super.subscribe(topics, handler)
this.join(topics)
}
We should only be extending its behaviour, not changing what it currently is implementing it.
Any reason you foresee to not simplify this?
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 think this is fine, especially considering we'll only be operating on a single topic.
e266b17
to
3173755
Compare
e905864
to
ec5ae25
Compare
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 nice for typescript router implementers to have a typescript interface
Ideally, we should move forward with the support via js doc + aegir soon |
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 still need to run through the tests but adding my initial comments on the source for now.
also, test/pubsub/utils/emit-self.spec.js
is an empty file.
src/pubsub/message/sign.js
Outdated
const baseMessage = { ...message } | ||
delete baseMessage.signature | ||
delete baseMessage.key | ||
if (typeof baseMessage.from === 'string') { |
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.
Won't this always be a string as this takes an InMessage
? The message is run through the normalizeIn function by this point. If this is not a string there's an issue.
src/pubsub/index.js
Outdated
this.log('received message we didn\'t subscribe to. Dropping.') | ||
return | ||
} | ||
const msg = utils.normalizeInRpcMessage(message, PeerId.createFromB58String(idB58Str)) |
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 PeerId passed to normalizeInRpcMessage
is converted to its string form for use, and I only see this called with a PeerId here. Perhaps this should just change to taking and using the string to avoid the double conversion.
9c7dd34
to
bc8ed8b
Compare
Co-authored-by: Jacob Heun <[email protected]>
bc8ed8b
to
d5ffc49
Compare
yeah lol, I created it inside utils by mistake and it moved away from my radar. Just added the base tests for it and the review is addressed |
6a967fd
to
94c1806
Compare
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.
Just a few minor things left
Co-authored-by: Jacob Heun <[email protected]>
…es into feat/interface-pubsub
00104ec
to
2152105
Compare
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.
LGTM
This PR adds pubsub-interface, which will replace libp2p/js-libp2p-pubsub per #53 . This is also an important work in the context of dropping the pubsub abstraction layer in
js-libp2p
per libp2p/js-libp2p-pubsub#68The interface is closely in line with the base pubsub spec and also got some inspiration from
go-libp2p-pubsub
during the gossipsub refactor in preparation for 1.1.This PR includes:
libp2p-pubsub
content intosrc/pubsub
andtest/pubsub
.libp2p-pubsub
codebase regarding constructor and to better track streamsTODO:
Unblocks: