This crate holds the raw modules for Fledger. They are written in a way to be as reusable as possible. For this, most modules have the following structure:
broker.rs
- which contains the code to interact with the other modulesmodule.rs
- with the main code of the module, with at least aprocess_msg
method that inputs a message and outputs a vector of answerscore.rs
- implementing the basic functionality of the module.
The following modules are available:
- dht_router implements a message routing system based on kademlia. It can send messages directly to connected nodes, to the closest nodes (useful for DHT storage), or broadcast to directly connected nodes.
- dht_storage allows to store blobs of data on the nodes, which can be updated and read by all other nodes.
- gossip_events exchanges events emitted by the nodes and updates the list. It works both in active mode - sending new messages to neighbours - as in passive mode - requesting list of available events from other nodes.
- network is the basic networking code to set up a new connection using the signalling server.
- ping uses
random_connections
to send regular messages to the connected nodes to make sure they answer. If a node doesn't answer in due time, a failure message is emitted. - random_connections takes a list of nodes and randomly selects enough nodes for a fully connected network
- router is an intermediate layer that contains all messages to be implemented
for current and future communication layers.
Currently it's implemented for
random_connections
andnetwork
. - timer sends out one message per second and one message per minute
- web_proxy allows sending a http GET request to another node, using the other node as a proxy.
This is the dependencies between the different modules:
Signal
is the root of all controlNetwork
sets up its connections usingSignal
RandomConnection
uses theNetwork
to set up connectionsRouter
is an abstraction of theNetwork
or theRandomConnection
DHT_Router
usesRouter
DHT_Storage
usesDHT_Router
WebProxy
usesRouter
As described in the previous section, you should write your modules in three parts:
-
Core Logic: persistent data, configuration, methods. This part does not handle any messages to/from the system, but only provides the actual algorithm. This might include cryptographic calculations, caching, updating, and other tasks necessary for the functionality. Write it in a way that it can also be used by a non-fledger project. If possible, no async should be used in this implementation.
-
Message Handling: create all messages that this module should receive or send during its lifetime. All messages defined here must be self-contained: this part must not depend directly on any other module's message definitions.
-
Translation: this part defines the interactions with the other modules. This is mostly done with defining
translator
methods which take incoming messages and output messges for this module.
Testing your new module should be done in three steps:
-
Write tests for the core logic. Make sure that all the necessary logic functions as it should. Test edge-cases, and add more tests as the core logic expands. The
Message Handling
part should be as simple as possible, and as much of the logic should be here. -
Then go on to test the
Message Handling
part. Create multiple objects of the structure, and let them interact using simple simulators. In this stage, it might be enough to do all message-passing manually, so you have full control over what is going on. This also helps to test edge-cases, because it allows you to 'delay' messages artificially between modules. -
At the very end should you start implementing the more end-to-end tests. As a first step it is good to use the router simulator in router_simul. It abstracts the router in a useful way, while still allowing you to have some control of the message flow. Depending on what you're doing, it might also be worth using the full_simul which has an as-close-as-possible simulation of all the messages.
Once all these tests work, you can do real tests with the binaries and set them up to use a signalling server.