ChainSafe / js-libp2p-gossipsub

TypeScript implementation of Gossipsub
Apache License 2.0
145 stars 43 forks source link

js gossipsub not working in browser. #381

Open nuel77 opened 1 year ago

nuel77 commented 1 year ago

Hello, I created a basic gossipsub implementation as shown here. Heavily referencing the examples . I am always getting this error when trying to publish a message using gossipsub. I am using libp2p with the basic create-react-app template.

buildRawMessage.ts:40 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'Message')
    at buildRawMessage (buildRawMessage.ts:40:1)
    at GossipSub.publish (index.ts:2036:1)
    at App.js:81:1
nonchip commented 1 year ago

maybe show us App.js:81:1 (and the remainder of it, probably)?

nuel77 commented 1 year ago

I had attached the link for the implementation along with the issue. here it is again. https://github.com/nuel77/libp2p-mulitlang-gossip/blob/main/browser-node/src/App.js

nonchip commented 1 year ago

ah ok, sorry, i didn't actually click that link at first because "as shown here" sounded like you're mentioning a tutorial, not your own code :'D

but yeah the line in question is the }) bit of:

    node.pubsub.addEventListener("message", (evt) => {
      console.log(`node1 received: ${uint8ArrayToString(evt.detail.data)} on topic ${evt.detail.topic}`)
    })

which doesn't contain publish anywhere, so i'mma assume what it actually complains about is the code that follows that:

    setInterval(async () => {
      await node.pubsub.publish(topic, uint8ArrayFromString('Bird bird bird, bird is the word!'))
    }, 5000)

i don't know how exactly uint8ArrayFromString works (looks like a utility library? i always use UInt8Array = new TextEncoder().encode(str), does the same i think), but otherwise that code looks fine.

the error seems to happen in https://github.com/ChainSafe/js-libp2p-gossipsub/blob/master/src/utils/buildRawMessage.ts#L40, so that's RPC.Message lacking the Message bit if i see that right, which almost sounds like a protocol error or the RPC subsystem not running or somesuch?

frankly not sure what's happening there, your code does look fine, but i'm doing almost the exact same thing over there and there in the browser; and there on nodejs, feel free to compare or whatever, maybe that helps :/

note i'm not actually using the official bootstrap right now, because for some reason gossipsub never managed to actually find pubsub-enabled peers via that (and i don't need peer-/contentrouting via the giant p2p cloud yet), instead i'm telling gossipsub to dial a peer directly, which also currently does still seem to be leaking some resources or something (my bootstrapper stops accepting new clients after a while even if it was only talking to like 3 different nodeIds) but at least it should work a bit better.

nuel77 commented 1 year ago

In the repository i linked, i also created a node.js implementation using the same logic. which worked fine. Thats why it felt quite wierd when the it didnt work on browser side.

nonchip commented 1 year ago

literally the only difference i needed between browser and nodejs was that the browser version of webrtc-star gets no options, while the node one gets a wrtc object (just so it knows which implementation to use), otherwise there should be essentially no differences for anything you're using afaik.

nonchip commented 1 year ago

actually i just noticed something: you discover every bootstrap node every 100ms while a comment claims that "autoDial is on" (but it's not in your options object)... might wanna check if actually turning it on does something for you, or if it's the extremely short bootstrap interval that's messing with you (it's about a tenth to a hundredth of every other peer-related timer after all)

btw that same comment also claims that "autodial is on" is the reason there's "no need to dial" every single discovered peer ever immediately, but the real reason for that is actually that it would nuke your network to hell and back and screw with every single libp2p subsystem involved :P

nuel77 commented 1 year ago

ahh .. yea i was tinkering with those timings.. i did test with the larger values before I pushed the code with the smaller autodial. Which also gave the same error on publish :(

nonchip commented 1 year ago

that's not a smaller autodial timer though. that's no autodial config whatsoever as far as i can tell and a smaller bootstrap-fake-discovery timer. so every few seconds autodial might (or not, depending on the defaults) happen but that's already after you "discovered" the same list of peers 10-100 times since the last time, that might confuse it a lot.

also note that after starting the node you ping (NOT dial!) a hardcoded address, presumably to see whether you can still reach the webrtc-star server (because, again, you're not gonna make any long-living connection with that, and definitely none that gossipsub will be aware of!), and then just scream into the void. nothing there guarantees that the two nodes are actually exchanging any information at all.

but then again, neither of those issues should technically mess with the RTC object apparently not existing, as far as i can tell? maybe it's a dependency screwup? might need some polyfills/shims/whatevertheycallitnowadays? :P

marcus-pousette commented 1 year ago

See this https://github.com/ChainSafe/js-libp2p-gossipsub/pull/368