Alexander Chepurnoy

The Web of Mind

Inside a Proof-of-Stake Cryptocurrency Part 4: The Executable Forging Simulation

| Comments


In first 3 parts Nxt-like 100% proof-of-stake forging algorithm was described. It would be exciting to run executable simulation of it to see network-wide consensus in action. And now this simulation tool is published! Please take a look to it’s README for details, and this article is about some aspects of the source code unrevealed yet.


All the code is split into three modules(files):

  • blockchain.hs, module Blockchain.Structures - basic structures and functions, building bricks for the simulated cryptocurrency network & its forging algorithm

  • simulation.hs, module Blockchain.Simulation - structures & functions related to simulation

  • launcher.hs. module Main - some auxiliary functions & main function running simulation and dumping results into files

Most of basic structures and functions were decscribed in first 3 parts of the series, so now we’re going to take a look into simulation functions.


The most important function in simulation module is systemTransform taking current state of a network along with timestamp and common data for the simulation and transforming it to resulting network state by applying some partial transformers:

systemTransform :: SimulationData -> Network -> Network
systemTransform sd network = networkForge sd $ generateTransactions sd $
            propagateLastBlock sd $ propagateTransactions sd $ downloadBlocksNetwork sd $
        dropConnections sd $ generateConnections sd $ addNode sd $ addInvestorNode sd network


  • addInvestorNode makes some initial investor online. Network starts with just one online investor out of 20, system balance is spread uniformly in a genesis block. Max number of investors online (14,000 seconds after genesis and on) are 13, means 65% forging power being online

  • addNode adds a node to the simulated network with no blockchain & empty account. The node needs to download a blockchain from other nodes.

  • generateConnections generates a connection for a node to another node if number of outgoing connection is less than a limit given in settings file(20 by default)

  • dropConnections works once per 60 seconds, drop oldest connection for a node, if number of outgoing connections equals to the limit

  • downloadBlocksNetwork selects random neighbour for each peer and check it’s cumulative difficulty, and if this metrics is better for the neighbour, the node is going to download a chunk of blockchain after common chain(14,400 blocks max)

  • propagateTransactions selects random neighbour for each peer and sends transactions from peer’s unconfirmed transactions pool a naighbour doesn’t have

  • propagateLastBlock selects nodes having last block generated by other node not more than 15 seconds ago and sends it out to a random neighbour

  • generateTransactions generates random transactions sending max 5% stake out(for account having more than 200 coins out of 1,000,000,000 issued)

  • networkForge asks each node whether it has a right to generate a block(by it’s own opinion) and if so generates blocks for forgers found and sends them out to random neighbours

Nothing-at-Stake simulation

By mixing multibranch forging simulation tool published previously with blockchain forging simulation tool described in the article it’s possible now to simulate Nothing-at-Stake attack, e.g. by mixing nodes doing blockchain forging with “attacker” doing multibranch forging. We’ll publish our work on that soon.

Conclusion & Further Work

Well, it’s the last article in the “Inside a Proof-of-Stake Cryptocurrency” series. All of them:

And executable code corresponding is on GitHub: Some modifications will be made, I want to replace all the constants with configurable parameters, at least. Performance optimization is also needed, for now it’s performance isn’t good for simplicity’s sake.