170 comments

[ 5.3 ms ] story [ 221 ms ] thread
Author here. Amusingly, I wanted to link to the HN discussion on the page, but couldn't figure out how to... I don't think it's possible! Something I hadn't considered until just now with a content addressable web is there are no cycles in the links.

Edit: Another amusing anecdote. I've been following this on log2viz (the heroku realtime performance monitoring tool), and was aghast to see high response times and memory usage. Then I realized I was actually looking at the dashboard for one of my rails apps! Phoenix is sitting pretty at about 35MB memory usage, and a median response time of 5ms, so far.

Are you able to adjust the url of the HN submission? I don't feel like creating one just to check, but that makes it easy to link the discussion, create the discussion before the page.
No, but that would be the way to do it, for sure. There's a link to "edit" my submission, but the form it takes me to only allows updating the title. It displays the URL as ordinary text, rather than a text input.
I guess you'll need a fixed URL that redirects to the HN submission.
We'll change the URL for you if you like.
It seems ID's are assigned sequentially, so by timing your submission you should be able to get a predictable url.
An idea to make this(and the editable content suggestion in another comment) possible could be to add something to the protocol to define "previous versions" sha hashes. If you want to edit a page then create a new page which includes the sha hash of the previous versions. If you get a request for the content of a sha hash of an old version, you could suggest your sha hash as an updated version.
Or just send a new piece of content with the same ID and hope that it will win. But seriously, just a new created date. Same ID.
ID is a hash of the content so that's not possible unless you find a hash collision (highly unlikely with sha256).
(comment deleted)
Hmm, ok, but that is just an implementation detail. I just see a really simlple service here that could become really beautiful if one could manipulate the content, once it is in your browser, so the next time it is passed along, it will have evolved. Into what? I don't know. But what if I seeded the system with an image, a simple drawing or a shape, vector or whatever, and then just sat back, observed how other people took it further. Like graffiti. Forking of content could be insteresting. Or a github, but a peer-to-peer version?
This is a really cool idea.
Implement it as a merkle tree so that you can reference parents and know it will only evolve forward.
Doesn't git use hashes also? The old hash could redirect to the new "commit" hash, keeping the cycle and allowing for updates at the same time. One of those updates could be the page "changelog".
Yes, git does use hashes, but git similarly doesn't work in that manner for the same reason. Git commits can only point to commits in the past and not future commits. It is not possible to update old commits like you suggest.

The HEAD of a repository is like a pointer to the hash of a commit. You may think of HEAD like a repointable alias. `cat .git/refs/heads/master` in any of your git repositories to see what I mean.

> Git commits can only point to commits in the past and not future commits.

Not true! With git time-travel, you can refer to a future commits in the commit message. Eg:

    $ git log --oneline HEAD~2..HEAD
    9428c8c I am the child
    cdd3ab5 I am the parent of 9428c8 
https://github.com/hundt/git-time-travel

:p

Ha, that's a clever little tool!

For anyone curious, this uses the same idea as the "guess-and-check" approach spullara mentioned: https://news.ycombinator.com/item?id=953569

It changes the content of the commit (by iterating the hash in the commit message itself) until the hash of the child commit matches. A big part of the trick is that it only looks at a prefix of the hash, so the search space is much smaller than the full SHA1 hash.

This is a problem that Freenet solved a long time ago. It means you need public-key cryptography rather than hashes for security, but they support updating pages--and, of course, any and all leaf content can still use hashes for better cacheability.
Do you know about WebRTC and Webtorrent? You can do this even without a relay server. Just browser-to-browser.
It's worth noting that WebRTC still requires a server of SOME sort -- typically you want a "signaling" server, and you need at least a STUN server to pierce firewalls, though the latter can be found for free.

And some corporate networks are too restrictive to be pierced by STUN, which means you need a TURN server, which is a relay server.

But yes, 98% of the time, WebRTC can go directly browser to browser. As long as neither browser is Internet Explorer. Sigh.

I never knew about STUN, this solves so many problems I've had. Thanks.
> As long as neither browser is Internet Explorer. Sigh.

If all popular torrent sites moved to in-browser downloads over WebRTC, virtually everybody would move away from IE :)

Is it even possible to open a socket from a browser to another browser directly? I was under the impression that was restricted for security reasons (websites becoming botnets and such).
(comment deleted)
I think you are correct, this appears to require a sever side element, I assume you don't have any real proof of deletion with something like this.
I once solved a similar problem by creating a link at tinyurl and then updating that link to point to whatever the name of my uploaded file had become :)
Well, the site already uses DNS as an escape hatch for getting a pointer to content, so setting up a http-redirector might be a good idea...
(comment deleted)
Ok I am at a loss here. Why can't you link this discussion on that page?
Changing the contents changes the hash and the hash is used in the url
the hash is a hash of the content itself, so the link is immutable - if you changed the content the link wouldn't be pointing to the same thing anymore.
The web-pages are recognized by their hash, so you can't change them after you setup the page. The problem is that you would have to supply HN with the link to the page, and then go back and edit the page to include the link to the new HN article. Since you can't go back and edit the page, you can't include the link.
You'd have to be able to generate some pretty fantastically unique hash collisions!
It's great! Will the client complain if it receives content that doesn't hash from a malicious client?
Would a page be able to leave and come back into the network by having a computer that's offline but viewing the page and then comes back? i.e. is there anything to prevent it?
im not 100% sure how this all fits together, but you should be able to recreate a page, so long as the content was exactly the same, and therefor produced the same hash.

So you could set it up to automatically recreate the page when your machine comes back online.

is that what you meant?

Not quite but I assumed similarly. I'm wondering if it'll connect to the peers automatically after coming back online if just left in the browser. If it did then it'd be possible to keep a page unpublished except when asked for through another channel. It's definitely a really interesting idea to play with. It makes me wonder if it could be used to create a nicer interface for things like Freenet by doing more clientside these days.
I've actually seen people successfully get a tweet to link to itself through trial and error. You can try and guess the IDs and you will eventually get it right.
I just used firebug to alter the page in my browser. I changed the first heading from "This page exists only if someone is looking at it" to "What happens if I use Firebug to alter this page in-situ. Do I end up with malware?".

Will this change propagate? Has anyone yet seen this modified page in their own browser?

Edit:

From the original page: "The server double checks the hash of the content it gets and then passes it along to the new person." I guess the answer is that the change won't propagate?

Correct, the change won't propagate for the reasons you say. (See source [0]). Also, though, note that the content comes to you as a blob of JSON, which gets rendered into your page, and you respond to future content requests with that blob of JSON, rather than the HTML itself.

[0] https://github.com/losvedir/ephemeral2/blob/master/web/chann...

Thanks for the explanation.
I found this line amusing.

>and you shouldn't be trusting me any more than any other random internet person.

Because I did trust you more than most other random internet persons, I trusted your javascript by temporarily whitelisting it in my browser to view the contents. :)

Nice. Very nice.

If you ditched the hash that checks the content and made the whole page 'content-editable' (maybe with something that stripped certain tags like images and video for obvious reasons), that might be fun. :)

Ha, that's a fun idea. I imagine it would regress to a lot of inappropriate ASCII art pretty quickly, though...

The SHA-256 checksum is actually part of what makes it very interesting to me, though. Since the content of the page is guaranteed by the location of it, it's kind of a shared web that anyone can help host.

Very cool! Interesting to see your findings. Maybe the browser is capable already of simplifying p2p file sharing. It would be good to get rid of todays torrent clients and have your browser run some slick p2p service instead that also serves as a convenient way of sharing or sending files with collegues and friends. I also really love the idea of tossing web content around (between) peers like that. Good work, so far. Don't think you're done yet.
Very cool stuff. I wonder if it would be possible to host an entire webapp with sockets/rtc. I don't see why not, but it you'd have to re-invent decades worth of architecture built around http.
This is a wonderful proof-of-concept and has potential applications in better decentralising web services.

Keep going!

However in this case, only the content is being decentralized, not the service itself.
Author here.

True, and a very clear way of putting it. Interestingly, since Erlang is so well-suited for distributed computing, and Phoenix (the web framework I'm using) has been built to take advantage of that, it wouldn't be too hard to let someone else spin up this same service and take part in distributing the content.

Off the top of my head, the only thing that wouldn't work is the "Currently Viewing" counter, which relies on this all running on a single heroku dyno. Otherwise, the socket messages are routed over a distributed PubSub layer, which should be pretty easy to tap into.

It's a cool idea. What do you think about running it from an Android? (Isn't there an Apache APK?) So you can only view the page while connected to the phone's hotspot?

That would make it even more etheral.

could you also keep track of viewers on a per-server basis and simply add those numbers together on the fronted?

like if

server 1abcdef is managing 300 sockets server 2ghijkl is managing 200 sockets

then you just add those on the frontend

Yes, but as long as the same method is used to generate the hash, the same browser could connect to multiple services and share the same content.

In that sense there needn't be a single service. Just a bunch of rendevous points for browsers-with-content to connect and announce what they have.

Very nice idea and I'm sure that it's a great way to play with Elixir/a platform. Well done!

Two questions:

1) You talk about P2P uses, but would it be feasible to 'seed' a true P2P net? A site that delivers the application, and everything from there is P2P vs. 'ask the server so that the server asks potential peers (clients?)'?

2)

I got this at the top:

Connecting to websocket. Connected! Listening for content for hash 2bbbf21959178ef2f935e90fc60e5b6e368d27514fe305ca7dcecc32c0134838 Requesting content. Received content for hash 2bbbf21959178ef2f935e90fc60e5b6e368d27514fe305ca7dcecc32c0134838 Received content for hash 2bbbf21959178ef2f935e90fc60e5b6e368d27514fe305ca7dcecc32c0134838 Standing by... ready to share this content!

Two answers for the hash? Intentional? Fine? If that happens quite a lot, you might waste more bandwidth/resources than necessary in your experiment?

Great questions!

For (1) I'm not sure. I'm primarily a backend dev, so this was partly an experiment for me to play with the front end, too. I kind of hope javascript is not able to connect "sideways" to other ordinary browsers. I would think they'd need to be running some sort of server, which I don't think the browser can get going. Would be happy to learn more about this from someone more knowledgeable.

Regarding (2), you should have seen my first approach: Every new client broadcasted a request for the content, and everyone with it responded! Now that was a waste of bandwidth.

But what I've done here is I send the request for content out to everyone with it, with a probability of 1/N, where N is roughly the number of people with it. So in your case, it looks like it got sent to two folks. Sometimes it gets sent to none, in which case the client will retry in 2 seconds.

It was a little tricky to figure out since phoenix runs every socket connection in its own erlang process (great for robustness and concurrency, but a real mind bender if you're not used to it). So this probabilistic approach was the best I could come up with, instead of having some master process select the right person to send the request to.

Maybe the side-channel connections could be built on WebRTC, which includes STUN facilities for making the connection.
Try this page, too!

http://ephemeralp2p.durazo.us/82d78987fd1cd530302b81d5643739...

This is a test page with embedded media via base64 encoding. This shouldn't touch the server, so hopefully no bottlenecks for this page either :)

Unfortunately it seems to have gone to 0 and therefore disappeared? =/
Hmm, I'm still viewing it, and it says 4 others are also viewing right now...
Oh, interesting. For me it's at 0 viewing, and stuck in a 'Requesting content' loop -- and of course, as I wrote that, it found a peer! :)
Does this also mean that, technically, I can edit the page and someone else, who connects after my edits, gets to see my edited page?
I think you'd have to send them a link with the new hash in it. If you sent them the current page, the hash wouldn't match your changes.
As mentioned on the page, it does a sha-256 hash of the content, which you can think of as a fingerprint of the page.

If the content you get sent doesn't match that fingerprint, it will reject it.

Damn you, author. This is cool and now I am loath to close the page.
It would be cool if you could drag and expand the log window. Can you patch the content?
As the page is content-addressed, it can only change the content by changing the address, thus creating a whole new webpage - address and content, after all, define the resource.
Don't all dynamic pages only exist if someone is looking at it?

I think a better title would be "This page only exists AS LONG AS someone is looking at it"

Either way, cool demo!

Hahaha the old "if a tree fell in the woods" eh?
I think the concept is akin to a beach ball that is passed from hand to hand. It only exists one instance of it. With a webserver, a new instance is created for each user viewing the page.
A beach ball that can be held simultaneously by any amount of people, though
Read this aloud: "[] that is passed from hand to hand. "
Here's another, it is a please CLICKME page, even if it doesn't look like it. [0]

[0] http://ephemeralp2p.durazo.us/ae0fad06ab58fa6bbc1599733b6c0c...

What is this exactly? As a general warning, I don't sanitize or otherwise modify the shared content, so any sorts of badness could be there.
Apparently it simply try to open a bunch of modal window to close. Chrome is smarter enough to figure that out, and there's only about five windows before the script is killed.
This somehow crashed my system (caused a black screen). Firefox on linux. Beware.

  Currently Viewing: 0
  
  Connecting to websocket.
Having a Sixth Sense-style existential crisis moment here... o_0
Same here... but I'm viewing from inside corporate firewall and it may have blocked some scripts.
This is more interesting than the title eludes to; this is P2P via websockets. Neat!
Fun, but not really P2P. Have a look at WebRTC for actual P2P :)
Thsi reminds me of Mystery Men's Invisible Boy who has invisibility - but only when no one is looking!

I need to re-watch that movie.

>Request received... >Content sent!

That was rewarding :)

This is awesome. Would be fun to see more statistics - how many people have I provided the page for, for example.
Well it still goes right through the server, so it only causes more strain on the server than a standard setup.

The actual way to do this an acctualy call it p2p would be with a small WebRTC framework that can bootstrap the actual site.

I once implemented a crude but serverless P2P in JavaScript by using pulse-width-modulating information inside bandwidth usage; anyone on the same Wi-Fi frequency would then be able to stream some arbitrary fixed-bitrate content and observe the drops in their bandwidth throughput to pick up the modulated information. But it was hellishly slow (a couple of bytes a second at best, a couple of bits at worst), and didn't work as soon as there were 3 devices on the frequency.

Would be interested to explore other ways to make pure-JS mesh networking happen. I've thought of using the JavaScript image pinging trick to "port scan" the entire subnet for peers, and communicate by "mildly DDoSing" each other with pings, but haven't actually tried yet.

Another potential method to pure-JS P2P is by using the microphone and speaker and building a mesh network at inaudible frequencies but this requires microphone permissions and won't work beyond the same room, and would be only several hundred bytes per second at best.

Interesting, this is like a P2P Snapchat for text. Or no. Better said, I am having trouble trying to associate this with something that exists already.

Good job for the innovation!

I've been thinking of it as somewhat like a Bluetooth pairing. Only exists when two devices are connected.
So would we call it a heisenpage?
Feross has built the thing the author talks about, a Bittorrent client in the browser called WebTorrent, it is super awesome and incredibly useful for sending files, check it out at: http://instant.io !
Very cool! This is exactly what I had in mind, but couldn't find any implementations of it. Thanks for sharing.