Skip to content
This repository has been archived by the owner on Aug 18, 2020. It is now read-only.
Artyom edited this page Oct 27, 2016 · 18 revisions

Guide to the codebase

UPDATE: see https://serokell.slack.com/files/gromak/F2US6DCLT/Overview_of_pos-prototype_code for an updated version.

Note: we use words patak, bardaq, and skovoroda throughout the code. You are greatly encouraged to use them too even if you don't understand them. They make the code more robust, performant, and generally better in all sorts of ways.

The rest of the style guide can be found here: https://github.com/serokell/serokell-core/blob/master/serokell-style.md. There are really only 5 things you need to know:

  • use 4 spaces
  • use stylish-haskell for imports
  • use spaces around all operators in all cases (exception: (%) from Formatting)
  • use ! for all fields in data types
  • all imports should be either qualified or explicit, i.e. with enumeration of stuff that you're importing (exceptions: Universum and Prelude)

Ok, so what we have now is the following:

  1. Pos.Crypto: various cryptographic stuff necessary for other code. This part is at very low level in terms of dependencies between different parts.

  2. Pos.Types. Here we have the most important types and functions which operate on them. Types.Types contains types definitions and instances of some type classes, other modules contain functions. This part is constantly updated. Note that there is GHC bug which forces us to put contents of Block.hs to Types.hs.

  3. DHT: it was written by @georgeee for peer discovery.

  4. Util, Slotting, Merkle, FollowTheSatoshi, Genesis, Constants. These modules are rather self-contained and descriptive. Their names are descriptive as well. I think everything should be clear here.

    Other modules are more high-level. We split this higher-level functionality into several parts:

    • MPC: this part is what distinguishes Static State version from paper from Dynamic State. We hope to write some abstraction on top of it later.

    • Static State: this part can be split into smaller parts:

      • Tx: this part processes transactions.
      • Block: this part process blocks.

    Maybe we will have more parts later.

  5. Communication. We use time-warp (https://github.com/serokell/time-warp), note that you need to look at super-communication branch there. We use MonadDialog from there. This library has documentation (which may be outdated somewhere), so please read it first to get high-level understanding of purposes of this library. If you have questions after that, feel free to ask. Here you can see separation into parts in action. For instance, Types defines types necessary to communication (basically messages) and it's split into three modules related to each part. Server is also split into three parts, each one defines some related listeners.

  6. State: this part deals with persistent state and has most of logic. We use acid-state. It's also split into aforementioned parts.

  7. Worker: this part defines various workers, which simply do some actions sometimes, e. g. when new slot starts (very abstract definition, but anyway). Again, it's split into parts.

  8. WorkMode: this is a constraint consisting of several monads (using ConstraintKinds) which most of code uses. It has monads from time-warp and some our ad-hoc monads (e. g. Slotting).

  9. Launcher: this is the main entry point, it defines functions which may be needed for executables.

  10. Executables: pos-node and pos-demo. pos-node is a single node. pos-demo runs several nodes.

Clone this wiki locally