@nanocat/democracyjs
v0.0.1
Published
Democracy module for applications
Downloads
7
Maintainers
Readme
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': ''
}
};
}
}