HelloZeroNet / HelloZeroNet/ZeroNet
Peer-to-peer applications
- Lingua principale
- JavaScript
- Stelle
- 18.8k
- Fork
- 2.3k
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Descrizione
In fact, this is not a bug but a feature request. So I probably won't follow the recommended issue format.
# Idea
ZeroNet completely depends on sites. The only thing possible to be built on ZeroNet is a site.
However, I see a way to support much more. With the idea I promote we will be able to bring a blockchain here. The idea itself is rather simple: let's give the developer the control over P2P messages. For example, you could spread information to all peers, *without files*!
# Implementation
Now to the implementation. There will be a new ZeroFrame command called `peerBroadcast(message, peer_count=5, broadcast=True, immediate=False, timeout=60)`. This will:
1. Generate message ID by `some_hash(str(rand()) + "," + json.dumps(message))`.
2. Get `peer_count` random peers having current site.
3. Trigger `peerBroadcast(message=message, hash=hash_from_p1, peer_count=peer_count, broadcast=broadcast, immediate=immediate)` action on those peers.
## P2P
When a peer receives `peerBroadcast` from another peer, it first verifies that current message wasn't yet received *in current session* (i.e. check it by hash in some dict or list). It's unlikely that the IDs will be duplicated (they may be, but it should be handled by the zite correctly). And it's unlikely that the message will be received twice after shutdown (i.e. get mesasge, shutdown, start again, connect to other peers, get message again). So we don't need to store the list in file system.
If the current message hasn't been received yet, it is sent to all current site's WebSockets via `peerReceive(ip=from_ip, hash=message_hash, message=message)` message. `from_ip` is IPv4, IPv6, or some other ID in case of Tor or I2P. So the site gets messages. The site may respond with another `peerBroadcast` message if it wants to.
## `immediate`
If no WebSocket connection exists, e.g. the browser is closed, *and `immediate` flag is set*, the message is saved to the queue *in memory*. When the site is opened, the WebSocket connection is opened as well, and the queue is flushed to the socket. I say "*in memory*" because in fact if you shut down ZeroNet, other messages may be broadcasted, so you'll have to fetch them (e.g. by another `peerBroadcast` command).
## `broadcast`
Finally, *if the message hasn't been received yet* (this prevents infinite loop), the message is broadcasted to some random `peer_count` peers. All the arguments are same as received.
## Results
If `broadcast` is set to `False`, the count of peers will be rather small (`peer_count` or less if just a few peers are available). So we may get results from other peers (let's call them neighbours).
In this case, neighbours send the message to WebSockets, get the answer (via some another ZeroFrame command, e.g. `peerReply`), and return it to previous peer. The previous peer sets some timeout, i.e. in case that WebSocket isn't open or the remote side hangs. Finally, the gathered results are send in form of `[{ip: ip1, reply: reply1}, ...]`. `reply` is the exact reply from neighbour's WebSocket, and `ip` is either IPv4 or IPv6 or some other ID, e.g. in case of Tor/I2P.
## Reply
Another ZeroFrame command called `peerSend(ip, message)` will send a message to peer specified by IP `ip`. The remote side may then reply, which results in return from `actionPeerSend(self, to, ip, message)`, so the zite gets the reply.
# Cross-site broadcast
It makes sense to ask user for permission to use CORS (because some site may store private data) and Merger (because it allows writing). However, just sending *a message* is secure enough. It makes no sense to do something serious when *just a message* is received. So `as(..., "peer...", ...)` should always be allowed *for all sites*, which will send a message to another site.
# Spam spam spam spam
Sending messages to other peers may be unsafe. For example, peer A may send *lots of messages* to other peers. This leads to spamming their network traffic and wasting CPU power. So I'd like to add two levels of protection: *passive* and *active*.
## Passive protection
A new entry called `message_filter` will be added to `content.json`. When a message is received from peer A, it is checked against `message_filter` regex in `content.json`. If the message doesn't match (i.e. it's invalid), it shouldn't be sent to WebSocket, to other peers. In this case peer A gets *5 ban points*. So spamming won't be possible (no more than 20 invalid messages).
## Active protection
The only kind of correct but spam messages is *messages which are correct, but contain invalid data the remote side cannot handle*. In case of Bitcoin this is invalid block hash. It's impossible to run any code in Python safely, so here comes *active protection in browser*. When a message is received from WebSocket, the zite may send `peerInvalid(hash)`, which will *add 10 ban points* to the peer from which that message was received. This is more than *passive protection* because it's more likely to ban.
However, there is no way to reply to a broadcast message, so there is no way to check whether a message is correct without something like `sleep; if didn't receive peerInvalid, then this message is valid`. So instead we add `peerValid(hash)` command, which marks a message as valid, and will make broadcast a bit faster; however, if it isn't sent, it will be timeouted in say 5s, so messages will be transfered just a bit slower.
# Usage examples
## IRC
```javascript
// Using my ZeroPage library, hopefully this will be easy to understand
zeroPage.on("peerReceive", ({params}) => {
const {ip, message} = params;
showNewMessage(message);
});
buttonSend.onclick = () => {
zeroPage.cmd("peerBroadcast", {message: messageContent.value});
showNewMessage(messageContent.value);
};
```
---
More examples are welcome.
---
Looking forward to hear from you, @HelloZeroNet.
Guida per i contributori
Nessuna guida per i contributori indicizzata per questo repository
Valutazione
Questa issue non è ancora stata valutata.