Code Monkey home page Code Monkey logo

cbc-casper-js's Introduction

Casper the Friendly Javascript Ghost ๐Ÿ‘ป

Travis CI

A Javascript implementation of Vlad Zamfir's Casper the Friendly Ghost CBC consensus protocol.

The paper is based primarily from the CasperTFG paper by Vlad Zamfir and also draws inspiration from the current Python implementation by Nate Rush, Danny Ryan, Vlad Zamfir, Karl Floersch and others.

Note: this project is still in very early stages. It is likely faulty and is subject to significant change. This should only be the case for the next few weeks (i.e., until mid-April 2018).

Casper: GHOST or finality gadget?

There are two distinct projects, both sharing the name "Casper".

  1. Casper Correct-by-Construction (aka Casper CBC, "Vlad's Casper")
  2. Casper the Friendly Finality Gadget (aka Casper FFG, "Vitalik's Casper)

This project is implementing (1), Casper CBC. This project seeks to simulate a network of peers coming to consensus across a loosely-asynchronous network whilst tolerating some faulty behaviour. This project is not (at this stage) concerned with any economic incentive mechanisms (i.e., it does not implement staking).

For more detail, see Jon Choi's "Ethereum Casper 101" (the "A Tale of Two Caspers" section): https://medium.com/@jonchoi/ethereum-casper-101-7a851a4f1eb0

Motivation

The motivation for creating a new implemenation can be seen in the following:

  • Browser compatibility: running Casper sims in the browser should hopefully improve accessibility for those who wish to understand how Casper TFG work.
  • Diversity: mutliple implementations will hopefully allow for a wider range of perspectives.

Requirements

This codebase has been developed in node v9.8.0. It uses some ES6 syntax and therefore some older versions of node will be incompatible.

Usage

For first time usage, clone the repo and run npm install in the repo directory.

Command-line

The command-line script is casper.js and it has a fully featured argument parser; you can run ./casper.js -h (or node casper.js -h) to view help.

Random Binary Conensus Simulator

Currenly the only available command-line function is $ ./casper.js random which will run a binary consensus simulation where the following conditions are randomised:

  • The initial estimate of the validators. I.e., if they choose to start with a 0 or 1.
  • The senders and recipients of messages for each round.

In this binary simulation, there is no concept of "rounds". I.e., validators will not wait for some minimum threshold of votes before they issue a new estimate to the network. This means that it is possible for all validators to reach consensus on a value which was not average of all validator starting points. E.g., there exists a pattern of messages so that validators with starting points (0, 1, 1) can come to consensus on the 0 value.

The random sim will output a JSON object to console with the following properties:

  • initialConfig: The starting values and weights for each validator. I.e., what their states were before the consensus process started.
  • decisions: The estimates and associated safety ratios for each validator, as of simulation completion.
  • majorityFlip: true if the majority of validators decided upon the average of all staring positions.
  • messageLogLength: the number of messages which were sent whilst forming consensus.

Example

The following example is running a simulation with the following attributes:

  • -n 3: Three validators will form consensus.
  • -s 0.5: The simulation will end once at least half (0.5) of validators consider themselves safe with half (0.5) the other validators. We do not wait for all validators to get to target safety because this can take a very long time with random message propagation.
$ ./casper.js random -n 3
{
  "intialConfig": [
    {
      "name": "0",
      "weight": 100,
      "startingPoint": 1
    },
    {
      "name": "1",
      "weight": 100,
      "startingPoint": 0
    },
    {
      "name": "2",
      "weight": 100,
      "startingPoint": 0
    }
  ],
  "decisions": {
    "0": {
      "estimate": 0,
      "safe": true,
      "safety": 1
    },
    "1": {
      "estimate": 0,
      "safe": true,
      "safety": 0.6666666666666666
    },
    "2": {
      "estimate": 0,
      "safe": true,
      "safety": 1
    }
  },
  "majorityFlip": false,
  "messageLogLength": 6
}

My laptop can comfortably run ./casper.js random -n 100 in about 5 seconds.

Tests

Tests are written in Mocha, run them with $ npm run test.

Notes

To reduce the processing burden of equivocation detection, some new requirements for message formation were added:

  • A validator must include a message from themself in the justifications of each message they send (unless the message is an "initial message" which does not provide any justification).
  • A validator must not include two messages from the same validator in their justification. This only applies to the first level of justifications, not the justifications of justifications (and their justifications, and so on).

Any validator which defies these rules will be flagged as Byzantine.

Roadmap

  • Binary Consensus
    • Estimator
    • Byzantine Fault Detection
    • Safety Oracle
    • Command-line simulator
    • Shared database for faster sims
  • Blockchain Consensus
  • Full code coverage for tests
  • Linting
  • Graphical simulation (to be implemented as a separate project)

cbc-casper-js's People

Contributors

paulhauner avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

cbc-casper-js's Issues

Only recurse for unseen messages

It seems that when a new message is verified and stored, all the messages in its justification are as well, and all the messages in these messages justifications are as well, etc (happens here).

I don't think we have to recurse all the way through the justifications - just down until we bump into messages we know. So I think it suffices to only recurse if !this.isMessageKnown, or something similar. This will stop a validator from doing to much extra work.

Another option is to add a function getNewMessages(msg) that recurses through a justification, and grabs all the messages that are not known yet, and then adding them all in one go. It might make the recursion easier to follow - but it's just a style thing here, so do what you think is best.

It's also possible I'm misunderstanding the code properly - in which case let me know :)

Investigate this message

I need to double check that this message checks out. There is some misunderstanding here,

./casper.js random -c binary -n 3 -s 0.5 -m 1
{ decisions: 
   { '0': { estimate: 1, safety: 0.6666666666666666 },
     '1': { estimate: 0, safety: 0.6666666666666666 },
     '2': { estimate: 0, safety: 0.6666666666666666 } },
  initialConfig: 
   [ { name: '0', weight: 100, startingPoint: 1 },
     { name: '1', weight: 100, startingPoint: 0 },
     { name: '2', weight: 100, startingPoint: 1 } ],
  log: 
   [ { msg: [Object], to: '0', from: '2', timestamp: 1522060122619 },
     { msg: [Object], to: '0', from: '2', timestamp: 1522060122620 },
     { msg: [Object], to: '1', from: '2', timestamp: 1522060122621 },
     { msg: [Object], to: '0', from: '2', timestamp: 1522060122621 },
     { msg: [Object], to: '2', from: '1', timestamp: 1522060122621 },
     { msg: [Object], to: '1', from: '2', timestamp: 1522060122622 } ]

Add oracle for safety calculation

Currently, safety is calculated for some estimate by finding the proportion of validators whose latest messages have this estimate.

However, because we insist on our protocols being safe without any timing assumptions, it's possible that there are some messages currently floating about in the network that may change these validators minds. Thus, just checking the proportion of validators whose latest messages have the same estimate isn't enough (it's actually possible for all validators to have the same estimate on their latest messages [in some validator's view] but then they all end up switching because of messages floating around the network).

Thus, to calculate safety for some estimate, we have to check a set of stronger conditions about recent messages from other validators using a safety oracle. The oracle that makes sense to implement is probably the Clique Oracle - which pretty much checks if validators are "locked in" to some specific message.

You can see the python implementation of the clique oracle here, and you can read it's specification here, and you can hear it described here.

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.