Merge pull request #134 from varasev/update-core-129-131

(Feature, Core) Ballot finalization before its endTime and new fields for miningKey creation
This commit is contained in:
Victor Baranov 2018-06-14 11:51:03 +03:00 committed by GitHub
commit ca50f9e999
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 402 additions and 86 deletions

File diff suppressed because one or more lines are too long

View File

@ -47,11 +47,16 @@
width: 30%;
}
&_mining-key {
&_key {
width: 25%;
word-break: break-all;
}
&_key_wide {
width: 50%;
word-break: break-all;
}
&_proposed-min-threshold {
width: 70%;
word-break: break-all;

View File

@ -19,6 +19,7 @@
p {
line-height: 18px;
color: #8197a2;
max-width: 340px;
}
&-finalize {

View File

@ -3,7 +3,6 @@ import moment from "moment";
import { observable, action, computed } from "mobx";
import { inject, observer } from "mobx-react";
import { toAscii } from "../helpers";
import { constants } from "../constants";
import { messages } from "../messages";
import swal from "sweetalert2";
@ -48,8 +47,15 @@ export class BallotCard extends React.Component {
}
@computed get finalizeDescription () {
const _finalizeDescription = this.isFinalized ? '' : constants.CARD_FINALIZE_DESCRIPTION;
return _finalizeDescription;
if (this.isFinalized) {
return '';
}
const { contractsStore, votingType } = this.props;
let description = 'Finalization is available after ballot time is finished';
if (this.getContract(contractsStore, votingType).doesMethodExist('canBeFinalizedNow')) {
description += ' or all validators are voted';
}
return description;
}
@computed get votesForNumber() {
@ -147,9 +153,14 @@ export class BallotCard extends React.Component {
@action("Get creator")
getCreator = async () => {
const { contractsStore, id, votingType } = this.props;
let votingState = await this.repeatGetProperty(contractsStore, votingType, id, "votingState", 0);
if (votingState) {
this.getValidatorFullname(votingState.creator);
let creator = await this.repeatGetProperty(contractsStore, votingType, id, "getCreator", 0);
if (creator) {
this.getValidatorFullname(creator);
} else {
let votingState = await this.repeatGetProperty(contractsStore, votingType, id, "votingState", 0);
if (votingState) {
this.getValidatorFullname(votingState.creator);
}
}
}
@ -221,6 +232,12 @@ export class BallotCard extends React.Component {
return _isActive;
}
canBeFinalizedNow = async () => {
const { contractsStore, id, votingType } = this.props;
let _canBeFinalizedNow = await this.repeatGetProperty(contractsStore, votingType, id, "canBeFinalizedNow", 0);
return _canBeFinalizedNow;
}
getMemo = async () => {
const { contractsStore, id, votingType } = this.props;
let memo = await this.repeatGetProperty(contractsStore, votingType, id, "getMemo", 0);
@ -279,8 +296,12 @@ export class BallotCard extends React.Component {
return;
}
commonStore.showLoading();
let isActive = await this.isActive();
if (isActive) {
let canBeFinalized = await this.canBeFinalizedNow();
if (canBeFinalized === null) {
console.log('canBeFinalizedNow is not existed');
canBeFinalized = !(await this.isActive());
}
if (!canBeFinalized) {
commonStore.hideLoading();
swal("Warning!", messages.INVALID_FINALIZE_MSG, "warning");
return;
@ -468,7 +489,7 @@ export class BallotCard extends React.Component {
</div>
</div>
<div className="info">
Minimum {threshold} from {contractsStore.validatorsLength} validators is required to pass the proposal
Minimum {threshold} from {contractsStore.validatorsLength} validators are required to pass the proposal
</div>
<div className="info">
{this.memo}

View File

@ -7,8 +7,9 @@ import { BallotCard } from "./BallotCard";
@observer
export class BallotKeysCard extends React.Component {
@observable affectedKey;
@observable newVotingKey;
@observable newPayoutKey;
@observable affectedKeyType;
@observable affectedKeyTypeDisplayName;
@observable ballotType;
@observable ballotTypeDisplayName;
@observable miningKey;
@ -32,25 +33,6 @@ export class BallotKeysCard extends React.Component {
}
}
@action("Get affectedKeyTypeDisplayName")
getAffectedKeyTypeDisplayName(affectedKeyType) {
const { ballotStore } = this.props;
switch(parseInt(affectedKeyType, 10)) {
case ballotStore.KeyType.mining:
this.affectedKeyTypeDisplayName = "mining";
break;
case ballotStore.KeyType.voting:
this.affectedKeyTypeDisplayName = "voting";
break;
case ballotStore.KeyType.payout:
this.affectedKeyTypeDisplayName = "payout";
break;
default:
this.affectedKeyTypeDisplayName = "";
break;
}
}
@action("Get ballot type of keys ballot")
getBallotType = async () => {
const { contractsStore, id } = this.props;
@ -74,10 +56,8 @@ export class BallotKeysCard extends React.Component {
console.log(e.message);
}
this.affectedKeyType = affectedKeyType;
this.getAffectedKeyTypeDisplayName(affectedKeyType);
}
@action("Get affected key of keys ballot")
getAffectedKey = async () => {
const { contractsStore, id } = this.props;
@ -89,6 +69,37 @@ export class BallotKeysCard extends React.Component {
}
this.affectedKey = affectedKey;
}
@action("Get new voting key of keys ballot")
getNewVotingKey = async () => {
const { contractsStore, id } = this.props;
let newVotingKey;
try {
newVotingKey = await contractsStore.votingToChangeKeys.getNewVotingKey(id);
if (newVotingKey === "0x0000000000000000000000000000000000000000") {
newVotingKey = "";
}
} catch (e) {
console.log(e.message);
}
this.newVotingKey = newVotingKey;
}
@action("Get new payout key of keys ballot")
getNewPayoutKey = async () => {
const { contractsStore, id } = this.props;
let newPayoutKey;
try {
newPayoutKey = await contractsStore.votingToChangeKeys.getNewPayoutKey(id);
if (newPayoutKey === "0x0000000000000000000000000000000000000000") {
newPayoutKey = "";
}
} catch (e) {
console.log(e.message);
}
this.newPayoutKey = newPayoutKey;
}
@action("Get mining key of keys ballot")
getMiningKey = async () => {
const { contractsStore, id } = this.props;
@ -113,25 +124,93 @@ export class BallotKeysCard extends React.Component {
constructor(props) {
super(props);
this.getAffectedKey();
this.getNewVotingKey();
this.getNewPayoutKey();
this.getAffectedKeyType();
this.getBallotType();
this.getMiningKey();
}
getAffectedKeyTypeDisplayName = () => {
const { ballotStore } = this.props;
let result;
switch(parseInt(this.affectedKeyType, 10)) {
case ballotStore.KeyType.mining:
result = "mining";
break;
case ballotStore.KeyType.voting:
result = "voting";
break;
case ballotStore.KeyType.payout:
result = "payout";
break;
default:
result = "";
break;
}
if (this.isAddMining()) {
if (this.newVotingKey) result += ', voting';
if (this.newPayoutKey) result += ', payout';
}
return result;
}
isAddMining = () => {
const { ballotStore } = this.props;
const ballotType = parseInt(this.ballotType, 10);
const affectedKeyType = parseInt(this.affectedKeyType, 10);
return ballotType === ballotStore.KeysBallotType.add && affectedKeyType === ballotStore.KeyType.mining;
}
isSearchPattern = () => {
let { commonStore } = this.props;
if (commonStore.searchTerm) {
const affectedKeyTypeDisplayName = this.getAffectedKeyTypeDisplayName();
const isMiningKeyPattern = String(this.miningKey).toLowerCase().includes(commonStore.searchTerm);
const isAffectedKeyPattern = String(this.affectedKey).toLowerCase().includes(commonStore.searchTerm);
const isAffectedKeyTypeDisplayNamePattern = String(this.affectedKeyTypeDisplayName).toLowerCase().includes(commonStore.searchTerm);
const isNewVotingKeyPattern = String(this.newVotingKey).toLowerCase().includes(commonStore.searchTerm);
const isNewPayoutKeyPattern = String(this.newPayoutKey).toLowerCase().includes(commonStore.searchTerm);
const isAffectedKeyTypeDisplayNamePattern = String(affectedKeyTypeDisplayName).toLowerCase().includes(commonStore.searchTerm);
const isBallotTypeDisplayNamePattern = String(this.ballotTypeDisplayName).toLowerCase().includes(commonStore.searchTerm);
return (isMiningKeyPattern || isAffectedKeyPattern || isAffectedKeyTypeDisplayNamePattern || isBallotTypeDisplayNamePattern);
return (
isMiningKeyPattern ||
isAffectedKeyPattern ||
isNewVotingKeyPattern ||
isNewPayoutKeyPattern ||
isAffectedKeyTypeDisplayNamePattern ||
isBallotTypeDisplayNamePattern
);
}
return true;
}
render () {
let { id } = this.props;
let affectedKeyClassName;
let affectedKey = <p>{this.affectedKey}</p>;
let newVotingKey;
let newPayoutKey;
let miningKeyDiv;
if (this.isAddMining()) {
affectedKeyClassName = 'ballots-about-i_key_wide';
if (this.newVotingKey || this.newPayoutKey) {
affectedKey = <p>Mining: {this.affectedKey}</p>;
if (this.newVotingKey) newVotingKey = <p>Voting: {this.newVotingKey}</p>;
if (this.newPayoutKey) newPayoutKey = <p>Payout: {this.newPayoutKey}</p>;
}
} else {
affectedKeyClassName = 'ballots-about-i_key';
miningKeyDiv = <div className="ballots-about-i ballots-about-i_key">
<div className="ballots-about-td">
<p className="ballots-about-i--title">Validator key</p>
</div>
<div className="ballots-about-td">
<p>{this.miningKey}</p>
</div>
</div>;
}
return (
<BallotCard votingType="votingToChangeKeys" id={id} isSearchPattern={this.isSearchPattern()}>
<div className="ballots-about-i ballots-about-i_action">
@ -147,25 +226,20 @@ export class BallotKeysCard extends React.Component {
<p className="ballots-about-i--title">Key type</p>
</div>
<div className="ballots-about-td">
<p>{this.affectedKeyTypeDisplayName}</p>
<p>{this.getAffectedKeyTypeDisplayName()}</p>
</div>
</div>
<div className="ballots-about-i ballots-about-i_mining-key">
<div className={`ballots-about-i ${affectedKeyClassName}`}>
<div className="ballots-about-td">
<p className="ballots-about-i--title">Affected key</p>
</div>
<div className="ballots-about-td">
<p>{this.affectedKey}</p>
</div>
</div>
<div className="ballots-about-i ballots-about-i_mining-key">
<div className="ballots-about-td">
<p className="ballots-about-i--title">Validator key</p>
</div>
<div className="ballots-about-td">
<p>{this.miningKey}</p>
{affectedKey}
{newVotingKey}
{newPayoutKey}
</div>
</div>
{miningKeyDiv}
</BallotCard>
);
}

View File

@ -7,20 +7,49 @@ import "react-select/dist/react-select.css";
@observer
export class BallotKeysMetadata extends React.Component {
render() {
const options = this.props.contractsStore.validatorsMetadata.slice();
const { ballotStore } = this.props;
const { ballotStore, contractsStore } = this.props;
const options = contractsStore.validatorsMetadata.slice();
let newVotingPayoutKeys = '';
if (ballotStore.isNewValidatorPersonalData && contractsStore.votingToChangeKeys.doesMethodExist('createBallotToAddNewValidator')) {
newVotingPayoutKeys = <div>
<div className="left">
<div className="form-el">
<label htmlFor="new-voting-key">New Voting Key</label>
<input type="text" id="new-voting-key"
value={ballotStore.ballotKeys.newVotingKey}
onChange={e => ballotStore.changeBallotMetadata(e, "newVotingKey", "ballotKeys")}
/>
<p className="hint">
Voting key address of new validator.<br />Example: 0xc70760D23557A4FDE612C0bE63b26EBD023C51Ee.
</p>
</div>
</div>
<div className="right">
<div className="form-el">
<label htmlFor="new-payout-key">New Payout Key</label>
<input type="text" id="new-payout-key"
value={ballotStore.ballotKeys.newPayoutKey}
onChange={e => ballotStore.changeBallotMetadata(e, "newPayoutKey", "ballotKeys")}
/>
<p className="hint">
Payout key address of new validator.<br />Example: 0xc70760D23557A4FDE612C0bE63b26EBD023C51Ee.
</p>
</div>
</div>
</div>;
}
return (
<div>
<div>
<div className="left">
<div className="form-el">
<label htmlFor="key">Affected Key</label>
<label htmlFor="key">{ballotStore.isNewValidatorPersonalData ? 'New Mining Key' : 'Affected Key'}</label>
<input type="text" id="key"
value={ballotStore.ballotKeys.affectedKey}
onChange={e => ballotStore.changeBallotMetadata(e, "affectedKey", "ballotKeys")}
/>
<p className="hint">
Affected key address of validator to vote for. Example: 0xc70760D23557A4FDE612C0bE63b26EBD023C51Ee.
{ballotStore.isNewValidatorPersonalData ? 'Mining key address of new validator.' : 'Affected key address of validator to vote for.'}<br />Example: 0xc70760D23557A4FDE612C0bE63b26EBD023C51Ee.
</p>
</div>
</div>
@ -33,12 +62,14 @@ export class BallotKeysMetadata extends React.Component {
value={ballotStore.ballotKeys.miningKey}
onChange={ballotStore.setMiningKey}
options={options}
disabled={ballotStore.isNewValidatorPersonalData}
/>
<p className="hint">
Mining key address of validator to vote for. Example: 0xc70760D23557A4FDE612C0bE63b26EBD023C51Ee.
Mining key address of validator to vote for.<br />Example: 0xc70760D23557A4FDE612C0bE63b26EBD023C51Ee.
</p>
</div>
</div>
{newVotingPayoutKeys}
<div className="left">
<div className="form-el">
<label htmlFor="datetime-local">Ballot End</label>

View File

@ -2,11 +2,26 @@ import React from 'react';
import { inject, observer } from "mobx-react";
import Select from 'react-select';
@inject("ballotStore")
@inject("ballotStore", "contractsStore")
@observer
export class BallotProxyMetadata extends React.Component {
render() {
const { ballotStore } = this.props;
const { ballotStore, contractsStore } = this.props;
let options = [
/*0*/ { value: '', label: '' },
/*1*/ { value: '1', label: ballotStore.ProxyBallotType[1] }, // KeysManager
/*2*/ { value: '2', label: ballotStore.ProxyBallotType[2] }, // VotingToChangeKeys
/*3*/ { value: '3', label: ballotStore.ProxyBallotType[3] }, // VotingToChangeMinThreshold
/*4*/ { value: '4', label: ballotStore.ProxyBallotType[4] }, // VotingToChangeProxy
/*5*/ { value: '5', label: ballotStore.ProxyBallotType[5] }, // BallotsStorage
/*6*/ { value: '7', label: ballotStore.ProxyBallotType[7] }, // ValidatorMetadata
/*7*/ { value: '8', label: ballotStore.ProxyBallotType[8] }, // ProxyStorage
];
if (!contractsStore.proxyStorage.doesMethodExist('getValidatorMetadata')) {
options.splice(6); // keep 0-5 and remove 6-... items if ProxyStorage is old
}
return (
<div>
<div>
@ -24,18 +39,11 @@ export class BallotProxyMetadata extends React.Component {
</div>
<div className="right">
<div className="form-el">
<label htmlFor="us-state">Contract Type</label>
<Select id="us-state"
<label htmlFor="contract-type">Contract Type</label>
<Select id="contract-type"
value={ballotStore.ballotProxy.contractType}
onChange={e => ballotStore.changeBallotMetadata(e, "contractType", "ballotProxy")}
options={[
{ value: '', label: '' },
{ value: '1', label: ballotStore.ProxyBallotType[1] },
{ value: '2', label: ballotStore.ProxyBallotType[2] },
{ value: '3', label: ballotStore.ProxyBallotType[3] },
{ value: '4', label: ballotStore.ProxyBallotType[4] },
{ value: '5', label: ballotStore.ProxyBallotType[5] },
]}
options={options}
>
</Select>
<p className="hint">

View File

@ -56,6 +56,9 @@ export class NewBallot extends React.Component {
if (ballotStore.isBallotForKey) {
for (let ballotKeysProp in ballotStore.ballotKeys) {
if (ballotKeysProp === 'newVotingKey' || ballotKeysProp === 'newPayoutKey') {
continue;
}
if (!ballotStore.ballotKeys[ballotKeysProp]) {
swal("Warning!", `Ballot ${ballotKeysProp} is empty`, "warning");
commonStore.hideLoading();
@ -128,12 +131,23 @@ export class NewBallot extends React.Component {
endTime: ballotStore.endTimeUnix,
affectedKey: ballotStore.ballotKeys.affectedKey,
affectedKeyType: ballotStore.ballotKeys.keyType,
newVotingKey: ballotStore.ballotKeys.newVotingKey,
newPayoutKey: ballotStore.ballotKeys.newPayoutKey,
miningKey: ballotStore.ballotKeys.miningKey.value,
ballotType: ballotStore.ballotKeys.keysBallotType,
sender: contractsStore.votingKey,
memo: ballotStore.memo
};
let method = contractsStore.votingToChangeKeys.createVotingForKeys(inputToMethod);
let method;
if (
inputToMethod.ballotType === ballotStore.KeysBallotType.add &&
inputToMethod.affectedKeyType === ballotStore.KeyType.mining &&
(inputToMethod.newVotingKey || inputToMethod.newPayoutKey)
) {
method = contractsStore.votingToChangeKeys.createBallotToAddNewValidator(inputToMethod);
} else {
method = contractsStore.votingToChangeKeys.createBallot(inputToMethod);
}
return method;
}
@ -146,7 +160,7 @@ export class NewBallot extends React.Component {
sender: contractsStore.votingKey,
memo: ballotStore.memo
};
let method = contractsStore.votingToChangeMinThreshold.createBallotToChangeThreshold(inputToMethod);
let method = contractsStore.votingToChangeMinThreshold.createBallot(inputToMethod);
return method;
}
@ -160,7 +174,7 @@ export class NewBallot extends React.Component {
sender: contractsStore.votingKey,
memo: ballotStore.memo
};
let method = contractsStore.votingToChangeProxy.createBallotToChangeProxyAddress(inputToMethod);
let method = contractsStore.votingToChangeProxy.createBallot(inputToMethod);
return method;
}
@ -271,7 +285,7 @@ export class NewBallot extends React.Component {
className={this.menuItemActive(ballotStore.BallotType.minThreshold)}
onClick={(e) => ballotStore.changeBallotType(e, ballotStore.BallotType.minThreshold)}
>
Consenus Thershold Ballot
Consenus Threshold Ballot
</div>
<div
className={this.menuItemActive(ballotStore.BallotType.proxy)}

View File

@ -2,8 +2,9 @@ import React from 'react';
import { inject, observer } from "mobx-react";
import Select from 'react-select';
import PlacesAutocomplete, { geocodeByAddress } from 'react-places-autocomplete';
import { constants } from "../constants";
@inject("validatorStore")
@inject("validatorStore", "ballotStore")
@observer
export class Validator extends React.Component {
onSelectAutocomplete = async (data) => {
@ -43,6 +44,17 @@ export class Validator extends React.Component {
}
}
componentDidMount() {
this.props.ballotStore.ballotKeys.miningKey = constants.NEW_MINING_KEY;
}
componentWillUnmount() {
const { ballotStore } = this.props;
if (JSON.stringify(ballotStore.ballotKeys.miningKey) === JSON.stringify(constants.NEW_MINING_KEY)) {
ballotStore.ballotKeys.miningKey = "";
}
}
render() {
const { validatorStore } = this.props;
const inputProps = {

View File

@ -1,5 +1,4 @@
let constants = {};
constants.CARD_FINALIZE_DESCRIPTION = "Finalization is available after ballot time is finished";
constants.organization = 'poanetwork';
constants.repoName = 'poa-chain-spec';
constants.addressesSourceFile = 'contracts.json';
@ -7,11 +6,16 @@ constants.ABIsSources = {
'KeysManager': 'KeysManager.abi.json',
'PoaNetworkConsensus': 'PoaNetworkConsensus.abi.json',
'BallotStorage': 'BallotsStorage.abi.json',
'ProxyStorage': 'ProxyStorage.abi.json',
'ValidatorMetadata': 'ValidatorMetadata.abi.json',
'VotingToChangeKeys': 'VotingToChangeKeys.abi.json',
'VotingToChangeMinThreshold': 'VotingToChangeMinThreshold.abi.json',
'VotingToChangeProxyAddress': 'VotingToChangeProxyAddress.abi.json'
};
constants.NEW_MINING_KEY = {
label: "New Mining Key",
value: "0x0000000000000000000000000000000000000000"
};
module.exports = {
constants
constants
}

View File

@ -0,0 +1,20 @@
import Web3 from 'web3';
import { networkAddresses } from './addresses';
import helpers from "./helpers";
export default class ProxyStorage {
async init({web3, netId}){
const {PROXY_ADDRESS} = networkAddresses(netId);
console.log('Proxy Storage address', PROXY_ADDRESS);
let web3_10 = new Web3(web3.currentProvider);
const branch = helpers.getBranch(netId);
let proxyStorageAbi = await helpers.getABI(branch, 'ProxyStorage')
this.proxyStorageInstance = new web3_10.eth.Contract(proxyStorageAbi, PROXY_ADDRESS);
}
doesMethodExist(methodName) {
return this.proxyStorageInstance && this.proxyStorageInstance.methods[methodName];
}
}

View File

@ -17,8 +17,18 @@ export default class VotingToChangeKeys {
}
//setters
createVotingForKeys({startTime, endTime, affectedKey, affectedKeyType, miningKey, ballotType, sender, memo}) {
return this.votingToChangeKeysInstance.methods.createVotingForKeys(startTime, endTime, affectedKey, affectedKeyType, miningKey, ballotType, memo).send({from: sender, gasPrice: this.gasPrice});
createBallot({startTime, endTime, affectedKey, affectedKeyType, miningKey, ballotType, sender, memo}) {
let method;
if (this.votingToChangeKeysInstance.methods.createBallot) {
method = this.votingToChangeKeysInstance.methods.createBallot;
} else {
method = this.votingToChangeKeysInstance.methods.createVotingForKeys;
}
return method(startTime, endTime, affectedKey, affectedKeyType, miningKey, ballotType, memo).send({from: sender, gasPrice: this.gasPrice});
}
createBallotToAddNewValidator({startTime, endTime, affectedKey, newVotingKey, newPayoutKey, sender, memo}) {
return this.votingToChangeKeysInstance.methods.createBallotToAddNewValidator(startTime, endTime, affectedKey, newVotingKey, newPayoutKey, memo).send({from: sender, gasPrice: this.gasPrice});
}
vote(_id, choice, sender) {
@ -34,6 +44,10 @@ export default class VotingToChangeKeys {
return this.votingToChangeKeysInstance.methods.areBallotParamsValid(ballotType, affectedKey, affectedKeyType, miningKey).call();
}
doesMethodExist(methodName) {
return this.votingToChangeKeysInstance && this.votingToChangeKeysInstance.methods[methodName];
}
getStartTime(_id) {
return this.votingToChangeKeysInstance.methods.getStartTime(_id).call();
}
@ -43,7 +57,17 @@ export default class VotingToChangeKeys {
}
votingState(_id) {
return this.votingToChangeKeysInstance.methods.votingState(_id).call();
if (this.doesMethodExist('votingState')) {
return this.votingToChangeKeysInstance.methods.votingState(_id).call();
}
return null;
}
getCreator(_id) {
if (this.doesMethodExist('getCreator')) {
return this.votingToChangeKeysInstance.methods.getCreator(_id).call();
}
return null;
}
getTotalVoters(_id) {
@ -70,6 +94,13 @@ export default class VotingToChangeKeys {
return this.votingToChangeKeysInstance.methods.isActive(_id).call();
}
canBeFinalizedNow(_id) {
if (this.doesMethodExist('canBeFinalizedNow')) {
return this.votingToChangeKeysInstance.methods.canBeFinalizedNow(_id).call();
}
return null;
}
getBallotType(_id) {
return this.votingToChangeKeysInstance.methods.getBallotType(_id).call();
}
@ -82,6 +113,20 @@ export default class VotingToChangeKeys {
return this.votingToChangeKeysInstance.methods.getAffectedKey(_id).call();
}
getNewVotingKey(_id) {
if (this.doesMethodExist('getNewVotingKey')) {
return this.votingToChangeKeysInstance.methods.getNewVotingKey(_id).call();
}
return "";
}
getNewPayoutKey(_id) {
if (this.doesMethodExist('getNewPayoutKey')) {
return this.votingToChangeKeysInstance.methods.getNewPayoutKey(_id).call();
}
return "";
}
getMiningKey(_id) {
return this.votingToChangeKeysInstance.methods.getMiningKey(_id).call();
}

View File

@ -17,8 +17,14 @@ export default class VotingToChangeMinThreshold {
}
//setters
createBallotToChangeThreshold({startTime, endTime, proposedValue, sender, memo}) {
return this.votingToChangeMinThresholdInstance.methods.createBallotToChangeThreshold(startTime, endTime, proposedValue, memo).send({from: sender, gasPrice: this.gasPrice})
createBallot({startTime, endTime, proposedValue, sender, memo}) {
let method;
if (this.votingToChangeMinThresholdInstance.methods.createBallot) {
method = this.votingToChangeMinThresholdInstance.methods.createBallot;
} else {
method = this.votingToChangeMinThresholdInstance.methods.createBallotToChangeThreshold;
}
return method(startTime, endTime, proposedValue, memo).send({from: sender, gasPrice: this.gasPrice})
}
vote(_id, choice, sender) {
@ -30,6 +36,13 @@ export default class VotingToChangeMinThreshold {
}
//getters
doesMethodExist(methodName) {
if (this.votingToChangeMinThresholdInstance.methods[methodName]) {
return true;
}
return false;
}
getStartTime(_id) {
return this.votingToChangeMinThresholdInstance.methods.getStartTime(_id).call();
}
@ -39,7 +52,17 @@ export default class VotingToChangeMinThreshold {
}
votingState(_id) {
return this.votingToChangeMinThresholdInstance.methods.votingState(_id).call();
if (this.doesMethodExist('votingState')) {
return this.votingToChangeMinThresholdInstance.methods.votingState(_id).call();
}
return null;
}
getCreator(_id) {
if (this.doesMethodExist('getCreator')) {
return this.votingToChangeMinThresholdInstance.methods.getCreator(_id).call();
}
return null;
}
getTotalVoters(_id) {
@ -66,6 +89,13 @@ export default class VotingToChangeMinThreshold {
return this.votingToChangeMinThresholdInstance.methods.isActive(_id).call();
}
canBeFinalizedNow(_id) {
if (this.doesMethodExist('canBeFinalizedNow')) {
return this.votingToChangeMinThresholdInstance.methods.canBeFinalizedNow(_id).call();
}
return null;
}
getProposedValue(_id) {
return this.votingToChangeMinThresholdInstance.methods.getProposedValue(_id).call();
}

View File

@ -17,8 +17,14 @@ export default class VotingToChangeProxy {
}
//setters
createBallotToChangeProxyAddress({startTime, endTime, proposedValue, contractType, sender, memo}) {
return this.votingToChangeProxyInstance.methods.createBallotToChangeProxyAddress(startTime, endTime, proposedValue, contractType, memo).send({from: sender, gasPrice: this.gasPrice})
createBallot({startTime, endTime, proposedValue, contractType, sender, memo}) {
let method;
if (this.votingToChangeProxyInstance.methods.createBallot) {
method = this.votingToChangeProxyInstance.methods.createBallot;
} else {
method = this.votingToChangeProxyInstance.methods.createBallotToChangeProxyAddress;
}
return method(startTime, endTime, proposedValue, contractType, memo).send({from: sender, gasPrice: this.gasPrice})
}
vote(_id, choice, sender) {
@ -30,6 +36,13 @@ export default class VotingToChangeProxy {
}
//getters
doesMethodExist(methodName) {
if (this.votingToChangeProxyInstance.methods[methodName]) {
return true;
}
return false;
}
getStartTime(_id) {
return this.votingToChangeProxyInstance.methods.getStartTime(_id).call();
}
@ -39,7 +52,17 @@ export default class VotingToChangeProxy {
}
votingState(_id) {
return this.votingToChangeProxyInstance.methods.votingState(_id).call();
if (this.doesMethodExist('votingState')) {
return this.votingToChangeProxyInstance.methods.votingState(_id).call();
}
return null;
}
getCreator(_id) {
if (this.doesMethodExist('getCreator')) {
return this.votingToChangeProxyInstance.methods.getCreator(_id).call();
}
return null;
}
getTotalVoters(_id) {
@ -66,6 +89,13 @@ export default class VotingToChangeProxy {
return this.votingToChangeProxyInstance.methods.isActive(_id).call();
}
canBeFinalizedNow(_id) {
if (this.doesMethodExist('canBeFinalizedNow')) {
return this.votingToChangeProxyInstance.methods.canBeFinalizedNow(_id).call();
}
return null;
}
getProposedValue(_id) {
return this.votingToChangeProxyInstance.methods.getProposedValue(_id).call();
}

View File

@ -41,12 +41,21 @@ class AppMainRouter extends Component {
let setPoaConsensus = contractsStore.setPoaConsensus(web3Config);
let setBallotsStorage = contractsStore.setBallotsStorage(web3Config);
let setProxyStorage = contractsStore.setProxyStorage(web3Config);
let setVotingToChangeKeys = contractsStore.setVotingToChangeKeys(web3Config);
let setVotingToChangeMinThreshold = contractsStore.setVotingToChangeMinThreshold(web3Config);
let setVotingToChangeProxy = contractsStore.setVotingToChangeProxy(web3Config);
let setValidatorMetadata = contractsStore.setValidatorMetadata(web3Config);
await Promise.all([setPoaConsensus, setBallotsStorage, setVotingToChangeKeys, setVotingToChangeMinThreshold, setVotingToChangeProxy, setValidatorMetadata])
await Promise.all([
setPoaConsensus,
setBallotsStorage,
setProxyStorage,
setVotingToChangeKeys,
setVotingToChangeMinThreshold,
setVotingToChangeProxy,
setValidatorMetadata
]);
await contractsStore.setMiningKey(web3Config);
await contractsStore.setVotingKey(web3Config);

View File

@ -22,7 +22,9 @@ class BallotStore {
2: 'VotingToChangeKeys',
3: 'VotingToChangeMinThreshold',
4: 'VotingToChangeProxy',
5: 'BallotsStorage'
5: 'BallotsStorage',
7: 'ValidatorMetadata',
8: 'ProxyStorage'
}
@observable ballotType;
@observable keysBallotType;
@ -44,6 +46,8 @@ class BallotStore {
keysBallotType: null,
//memo: "",
affectedKey: "",
newVotingKey: "",
newPayoutKey: "",
miningKey: ""
};

View File

@ -3,6 +3,7 @@ import React from 'react';
import PoaConsensus from '../contracts/PoaConsensus.contract'
import BallotsStorage from '../contracts/BallotsStorage.contract'
import ProxyStorage from '../contracts/ProxyStorage.contract'
import VotingToChangeKeys from '../contracts/VotingToChangeKeys.contract'
import VotingToChangeMinThreshold from '../contracts/VotingToChangeMinThreshold.contract'
import VotingToChangeProxy from '../contracts/VotingToChangeProxy.contract'
@ -13,12 +14,14 @@ import commonStore from './CommonStore'
import { BallotKeysCard } from "../components/BallotKeysCard";
import { BallotMinThresholdCard } from "../components/BallotMinThresholdCard";
import { BallotProxyCard } from "../components/BallotProxyCard";
import { constants } from "../constants";
import "babel-polyfill";
class ContractsStore {
@observable poaConsensus;
@observable ballotsStorage;
@observable proxyStorage;
@observable votingToChangeKeys;
@observable votingToChangeMinThreshold;
@observable votingToChangeProxy;
@ -84,6 +87,15 @@ class ContractsStore {
});
}
@action("Set ProxyStorage contract")
setProxyStorage = async (web3Config) => {
this.proxyStorage = new ProxyStorage();
await this.proxyStorage.init({
web3: web3Config.web3Instance,
netId: web3Config.netId
});
}
@action("Set VotingToChangeKeys contract")
setVotingToChangeKeys = async (web3Config) => {
this.votingToChangeKeys = new VotingToChangeKeys();
@ -240,11 +252,7 @@ class ContractsStore {
@action
async getAllValidatorMetadata() {
const newMiningKey = {
label: "New Mining Key",
value: "0x0000000000000000000000000000000000000000"
}
this.validatorsMetadata.push(newMiningKey);
this.validatorsMetadata.push(constants.NEW_MINING_KEY);
const keys = await this.poaConsensus.getValidators();
keys.forEach(async (key) => {
const metadata = await this.validatorMetadata.getValidatorData({miningKey: key})