0.0.1 • Published 4 years ago

@nanocat/democracyjs v0.0.1

Weekly downloads
-
License
MIT
Repository
github
Last release
4 years ago

democracyjs

Democracy election for decentralized systems.

App

This application implements consensus algorithm work. You can reimplement classess, objects, methods for your application.

Have four modules, based on app.MODULE:

  • Peer
  • Data
  • PeerManager
  • DataManager
  • Election

Peer

Define connected node entry

class Peer extends app.MODULE {
    constructor(data);//create new peer
    getId(); //get peer id
    signVote(vote); //vote = { id, answer }
}

PeerManager

Define Mapper of Peer entries. Storing, sorting, searching, etc...

class PeerMapper extends app.MODULE {
    getPeersList();//get list of all peers
    addPeer(peer);//add peer to list
    addPeers(peer_list);//add peers to list
    removePeerById(peerId);//remove peer by id
    removePeer(peer);//remove Peer
}

Data

Define election data message (election/vote)

class Data extends app.MODULE {
    constructor(data);//create new Data
    static getTypeFieldName()//type  field name, default "type"
    static getIdFieldName()//id  field name, default "id"
    static getPublicKeyFieldName()//publicKey  field name, default "pub"
    static getSignFieldName()//signature  field name, default "sig"
    static getAnswerFieldName()//answer  field name, default "answer"
    static getMethodFieldName()//method  field name, default "method"
    static getAnswersFieldName() //answers  field name, default "answes"
    static getStatusFieldName()//status field name, default "status"
    static getUntilFieldName() //until field name, default "until"
    static getBalancedFieldName()//balanced field name, default "balanced"
    getType()//type can be vote or election
    getId()//id of election
    getPublicKey()//public key of peer who create this data
    getSign()//EC signature
    getAnswer()//answer, only for type = vote
    getMethod()//method for callback, only for type = electin
    getAnswers()//answers list for election, only for type = election
    getStatus()//status can be pending, timeout, reached, only for type = election
    getUntil()//time when data will be timedout, only for type = election
    getBalanced()//balanced value, see method Election::balancing(), only for type = election and status = reached 
    isValid()//is valid data (signature and syntax)
    setStatus(newStatus)//set new status, only for type = election
    setBalanced(balanced)//set balanced value, only for type = election
}

DataMapper

Define Mapper of Data entries. Storing, sorting, searching, etc...

class DataMapper extends app.MODULE {

    getDataList();//get all data
    _addDataToList(data);//add data to list
    addData(data);//add data to list with verify (recive from network)
    getData(id);//get data by id
    removeData(data);//remove data 
    getElectionVoteByPeer(election_id, peer_id);//get peer vote in election
    getElectionPeers(election_id);//get publickeys of voted peers
    getElectionVotes(election_id);//get votes in election
    saveData(data);//save data with new parameters
}

Election

Describe election algorithm.

class Election extends app.MODULE {

    constructor(election_config_field);//election_config_field - config section, with params for this election algorithm. See more: config sections 
    getConfig(field, defaultValue);//get config section param (or all if first param is null);
    init()//init
    setKeystore(ks);//set keystore {publicKey: 'hex', privateKey: 'hex'}
    setOnEnd(cb);//set callback on finish election (timeout, reached)
    vote(electionId, answer);//vote for electionId with answer for current keystore
    isValidTime(time);//check time for valid
    create(request, answers, until, method);//create new election with request (text), answers - array, until - time in future, when election will timeout
     voteProcess(peer, voteData);//use this method when get message from another peer with vote data. voteData = {id, answer, sign}
     balancing(id, data);//use this method for choose value when election is reached
     getVotersList();//must be extended for valid peer list, who can voting
}

App.Extending

Any class in application can be redefined before start, for example we have app methods:

definePeerClass(man);
definePeerManagerClass(man);
setPeerManager(man);
defineDataClass(man);
defineDataManagerClass(man);
setDataManager(man);
defineElectionClass(man);

To redefine class you need create you own class and extends one from default modules:

  • app.PEER
  • app.DATA
  • app.PEERMANAGER
  • app.DATAMANAGER
  • app.ELECTION

For example we can create new election algorithm with another balancing algorithm and peer list:

module.exports = function(app) {
    class NewElection extends app.ELECTION {
        constructor(){
            super('election_field')
        }
        getVotersList() {
            return [
                '0x0',
                '0x1',
                '0x2',
                '0x3',
                '0x4',
                '0x5',
            ];
        }   
        balancing(id, data){//use average of all values 
            let answers = app.dataManager.getElectionVotes(id);
            let avg = 0;
            for (let i in answers){
                avg += answers[i].getAnswer();
            }

            return avg/answers.length
        }
    }

    return NewElection
}

Put this code to file newcons.js, and require it:

const newelect = require('newelect.js');
const DemocracyJs = require("democracyjs");
let config = {
    "election_field":{
        "majority": 0.5
    }
    "node":{ //required section
        ///...
    }
};
let app = new DemocracyJs(config);
app.defineElectionClass(newelect(app));
//now you can start app with new election
app.start();

Config sections

You can create many config sections:

"section1": {
    "param1": "value1",
    "param2": "value2"
    //etc
}

and use it in application: app.config.section1.param1 Any eection have default config section, defined in second param of constructor, for example:

constructor(){
    super('newconsensus_config_field')
}

in this example we must have section newconsensus_config_field in config!

node

Node section is required for application. Its describe keys of current peerm this keys will be used for signing messages

"node": {
    "publicKey": '0x...<hex>',
    "privateKey": '0x...<hex>'
},

extending sections

Config sections can be extending by existing sections:

"section1": {
    "param1":'value1',
    "param2":'value2',
},
"section2":{
    "extends":"section1",
    "param3":"value3"
}

In this example section2 have next params:

"param1":'value1',
"param2":'value2',
"param3":"value3"

Extending can be nested:

"section1": {
    "param1":'value1',
    "param2":'value2',
},
"section2":{
    "extends":"section1",
    "param3":"value3"
},
"section3": {
    "extends": "section2",
    "params5": 1,
}

it will be:

"param1":'value1',
"param2":'value2',
"param3":"value3",
"params5": 1,

Extending config sections is used for default election algorithms, see below.

default config parameters:

Config default parameters, that can be extend and rewrite defined in app.getDefaultConfig():

getDefaultConfig() {
    return {
            'election': {
                'majority': 0.75
            },
            'node': {
                'privateKey': '',
                'publicKey': ''
            }
        };
    }
}