GithubHelp home page GithubHelp logo

spiceworm / pychain Goto Github PK

View Code? Open in Web Editor NEW
0.0 2.0 0.0 72 KB

My attempt at a creating a peer-to-peer network from scratch

License: Apache License 2.0

Dockerfile 3.70% Python 95.97% Shell 0.33%

pychain's Introduction

Node Configuration

  • BOOT_NODE (required)

    • Node to use for bootstrapping to the network.
    • Example config: BOOT_NODE=<URL or IP-address>
  • LOG_DIR (optional, default: /var/log/pychain)

    • Filesystem directory where logs will be written
  • LOG_LEVEL (optional, default: INFO)

    • Choices: DEBUG, INFO, WARNING, ERROR, CRITICAL
  • NETWORK_SYNC_INTERVAL (optional, default: 60)

    • How many seconds should elapse between executions of network_scan.py.
  • NETWORK_SYNC_JITTER (optional, default: 30)

    • Maximum number of seconds of jitter to add to NETWORK_SYNC_INTERVAL.
  • STORAGE_DIR (optional, default: /usr/local/etc/pychain)

    • Filesystem directory where data will be written

Development Environment

# Start 1 boot node and 4 client nodes with some environment variable tweaks suitable
# for a development environment.
$ ./run.py 4 -e NETWORK_SYNC_INTERVAL=15 -e NETWORK_SYNC_JITTER=5 -e LOG_LEVEL=DEBUG

# Tail logs to observe node behavior
$ docker exec -it pychain_client_1_1 tail -f /var/log/pychain/{api,network_sync}.log
$ docker exec -it pychain_boot_1_1 tail -f /var/log/pychain/{api,network_sync}.log

Tests

$ docker-compose -f test.yml up --build

Architecture

Each node is running the following processes managed by supervisor:
- network_sync: process that allows client to join the network and synchronize state with peers.
- nginx: reverse proxy to API
- redis: Used as storage for rq worker processes.
- rq-mempool-worker: Queues messages broadcast from peers.
- uvicorn: Asynchronously serves API requests.

Development notes

TODO:
Add a some sort of identifier to the response from /api/v1/status that
  tells the caller that the callee is actually a node on the pychain
  network. Otherwise any server that responds to requests on that
  endpoint will be seen as a valid peer.

Each node should determine if their peers are running a compatible version of
the software as their own before keeping them as a peer. Maybe there should be
a "capabilities" endpoint whose response gets added as an attribute to Peer
objects and those capabilities can be used to enable/disable certain features
when interacting with peer nodes.

For testing purposes, create a "beacon" node that all nodes alert when a message
  is broadcast. All nodes would tell the beacon that they received this message,
  Checking the beacon logs would allow us to confirm whether the broadcast was
  propogated to the entire network and how long it took for all nodes to see it.

Configure logrotate

Broadcast message when a peer is leaving the network
- Handle special message types (events)

Nodes should associate a timestamp with peer GUIDs. That timestamp should get
  updated each time the corresponding peer is responsive. If a client has not
  heard from a peer with a certain GUID after some time, it should delete all
  saved records associated with that GUID (such as peer IP address)

Authenticate requests between clients so that a malicious node is not able to
  call endpoints such as /network/join and provide a GUID that is in use by an
  existing client.

Mitigate sybil attack where attacker could have several client join and then leave.
  The existing nodes will still attempt to contact those nodes until their GUID
  timeout interval was hit. A valid client would waste a ton of time waiting for
  the requests to timeout to these malicious nodes.

Handle case where boot node goes down. It will need to remember the GUIDs it has
  allocated previously. All nodes should mount their databases

Make adding nodes to the database better. It's ugly to call `ensure_node` all over the
  place.

Fix ensure_address so that it is less cludgy and does not ONLY use the boot node

Add a counter to node entries that increments if the node is unresponsive. Ignore
  nodes that have not been responsive after N attempts.

TODO: Figure out how to prevent flooding the message with duplicate messages as it happens ALOT

Message Broadcasting

# Run this from within a client container.
# Make sure network_sync.py has run at least once by tailing the logs.
# Otherwise the client will not know any peers to sent the message to.
# If it has not ran a single time yet, the client will not even know
# it's own GUID and address.

import aiohttp, asyncio
from pychain.node.config import settings
from pychain.node.db import Storage
from pychain.node.models import DeadPeer, Node

async def main():
    Node.db = db = Storage(data_dir=settings.data_dir)
    client = db.get_client()

    async with aiohttp.ClientSession() as session:
        msg = DeadPeer(1)
        await client.broadcast(msg, session)


asyncio.run(main())

pychain's People

Contributors

spiceworm avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.