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:
commit
ca50f9e999
File diff suppressed because one or more lines are too long
|
@ -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;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
p {
|
||||
line-height: 18px;
|
||||
color: #8197a2;
|
||||
max-width: 340px;
|
||||
}
|
||||
|
||||
&-finalize {
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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)}
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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];
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
11
src/index.js
11
src/index.js
|
@ -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);
|
||||
|
|
|
@ -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: ""
|
||||
};
|
||||
|
||||
|
|
|
@ -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})
|
||||
|
|
Loading…
Reference in New Issue