diff --git a/abis/BlockReward_abi.json b/abis/BlockReward_abi.json index db92f6a..d1ba8dd 100644 --- a/abis/BlockReward_abi.json +++ b/abis/BlockReward_abi.json @@ -1,78 +1,99 @@ [ { - "constant": true, - "inputs": [], - "name": "DECIMALS", - "outputs": [ + "anonymous": false, + "inputs": [ { - "name": "", + "indexed": false, + "internalType": "address[]", + "name": "receivers", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "rewards", + "type": "uint256[]" + } + ], + "name": "Rewarded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", "type": "uint256" } ], - "payable": false, - "stateMutability": "view", - "type": "function" + "name": "RewardedOnCycle", + "type": "event" }, { - "constant": true, "inputs": [], - "name": "isInitialized", + "name": "BLOCKS_PER_YEAR", "outputs": [ { + "internalType": "uint256", "name": "", - "type": "bool" + "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "getRewardedOnCycle", + "name": "DECIMALS", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "shouldEmitRewardedOnCycle", + "name": "INFLATION", "outputs": [ { + "internalType": "uint256", "name": "", - "type": "bool" + "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, + "inputs": [], + "name": "emitRewardedOnCycle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { "inputs": [], "name": "getBlockRewardAmount", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { + "internalType": "address", "name": "_validator", "type": "address" } @@ -80,124 +101,121 @@ "name": "getBlockRewardAmountPerValidator", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "INFLATION", + "name": "getBlocksPerYear", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, - "stateMutability": "view", + "stateMutability": "pure", "type": "function" }, { - "constant": true, "inputs": [], - "name": "getBlocksPerYear", + "name": "getInflation", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, - "stateMutability": "view", + "stateMutability": "pure", "type": "function" }, { - "constant": false, "inputs": [], - "name": "onCycleEnd", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", + "name": "getProxyStorage", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "getTotalSupply", + "name": "getRewardedOnCycle", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "BLOCKS_PER_YEAR", + "name": "getTotalSupply", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": false, - "inputs": [], - "name": "emitRewardedOnCycle", + "inputs": [ + { + "internalType": "uint256", + "name": "_supply", + "type": "uint256" + } + ], + "name": "initialize", "outputs": [], - "payable": false, "stateMutability": "nonpayable", "type": "function" }, { - "constant": true, "inputs": [], - "name": "getInflation", + "name": "isInitialized", "outputs": [ { + "internalType": "bool", "name": "", - "type": "uint256" + "type": "bool" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "getProxyStorage", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", + "name": "onCycleEnd", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { - "constant": false, "inputs": [ { + "internalType": "address[]", "name": "benefactors", "type": "address[]" }, { + "internalType": "uint16[]", "name": "kind", "type": "uint16[]" } @@ -205,59 +223,30 @@ "name": "reward", "outputs": [ { + "internalType": "address[]", "name": "", "type": "address[]" }, { + "internalType": "uint256[]", "name": "", "type": "uint256[]" } ], - "payable": false, "stateMutability": "nonpayable", "type": "function" }, { - "constant": false, - "inputs": [ + "inputs": [], + "name": "shouldEmitRewardedOnCycle", + "outputs": [ { - "name": "_supply", - "type": "uint256" + "internalType": "bool", + "name": "", + "type": "bool" } ], - "name": "initialize", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "receivers", - "type": "address[]" - }, - { - "indexed": false, - "name": "rewards", - "type": "uint256[]" - } - ], - "name": "Rewarded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "amount", - "type": "uint256" - } - ], - "name": "RewardedOnCycle", - "type": "event" } -] \ No newline at end of file +] diff --git a/abis/Consensus_abi.json b/abis/Consensus_abi.json index 719c831..36f699f 100644 --- a/abis/Consensus_abi.json +++ b/abis/Consensus_abi.json @@ -1,279 +1,294 @@ [ { - "constant": true, - "inputs": [], - "name": "getLastSnapshotTakenAtBlock", - "outputs": [ + "anonymous": false, + "inputs": [ { - "name": "", - "type": "uint256" + "indexed": false, + "internalType": "address[]", + "name": "newSet", + "type": "address[]" } ], - "payable": false, - "stateMutability": "view", - "type": "function" + "name": "ChangeFinalized", + "type": "event" }, { - "constant": true, - "inputs": [], - "name": "jailedValidatorsLength", - "outputs": [ + "anonymous": false, + "inputs": [ { - "name": "", - "type": "uint256" + "indexed": true, + "internalType": "bytes32", + "name": "parentHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address[]", + "name": "newSet", + "type": "address[]" } ], - "payable": false, - "stateMutability": "view", - "type": "function" + "name": "InitiateChange", + "type": "event" }, { - "constant": true, + "anonymous": false, "inputs": [ { - "name": "_p", + "indexed": false, + "internalType": "uint256", + "name": "requiredVersion", "type": "uint256" - } - ], - "name": "pendingValidatorsAtPosition", - "outputs": [ + }, { - "name": "", - "type": "address" + "indexed": false, + "internalType": "uint256", + "name": "upgradedCount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalCount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bool", + "name": "quorumReached", + "type": "bool" } ], - "payable": false, - "stateMutability": "view", - "type": "function" + "name": "NodeVersionCheckExecuted", + "type": "event" }, { - "constant": true, + "anonymous": false, "inputs": [ { - "name": "_snapshotId", - "type": "uint256" - } - ], - "name": "getSnapshotAddresses", - "outputs": [ + "indexed": true, + "internalType": "address", + "name": "validator", + "type": "address" + }, { - "name": "", - "type": "address[]" + "indexed": false, + "internalType": "uint256", + "name": "version", + "type": "uint256" } ], - "payable": false, - "stateMutability": "view", - "type": "function" + "name": "NodeVersionReported", + "type": "event" }, { - "constant": false, + "anonymous": false, "inputs": [ { - "name": "_newAddress", - "type": "address" + "indexed": false, + "internalType": "uint256", + "name": "version", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "activationBlock", + "type": "uint256" } ], - "name": "setProxyStorage", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" + "name": "RequiredNodeVersionSet", + "type": "event" }, { - "constant": true, + "anonymous": false, "inputs": [], - "name": "getMinValidatorFee", + "name": "ShouldEmitInitiateChange", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "CYCLE_DURATION_BLOCKS", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, - "inputs": [ - { - "name": "_address", - "type": "address" - } - ], - "name": "isJailed", + "inputs": [], + "name": "DECIMALS", "outputs": [ { + "internalType": "uint256", "name": "", - "type": "bool" + "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, - "inputs": [ - { - "name": "_address", - "type": "address" - }, - { - "name": "_validator", - "type": "address" - } - ], - "name": "delegatedAmount", + "inputs": [], + "name": "DEFAULT_VALIDATOR_FEE", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "SNAPSHOTS_PER_CYCLE", + "name": "MAX_STAKE", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "pendingValidatorsLength", + "name": "MAX_STRIKE_COUNT", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "newValidatorSetLength", + "name": "MAX_VALIDATORS", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "DECIMALS", + "name": "MIN_STAKE", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": false, - "inputs": [ + "inputs": [], + "name": "SNAPSHOTS_PER_CYCLE", + "outputs": [ { - "name": "_amount", + "internalType": "uint256", + "name": "", "type": "uint256" } ], - "name": "withdraw", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "isInitialized", + "name": "STRIKE_RESET", "outputs": [ { + "internalType": "uint256", "name": "", - "type": "bool" + "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": false, "inputs": [], - "name": "stake", - "outputs": [], - "payable": true, - "stateMutability": "payable", + "name": "UPGRADE_QUORUM_BP", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "currentValidatorsLength", + "name": "VALIDATOR_PRODUCTIVITY_BP", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": false, "inputs": [ { - "name": "_amount", + "internalType": "address", + "name": "_validator", + "type": "address" + } + ], + "name": "blockCounter", + "outputs": [ + { + "internalType": "uint256", + "name": "", "type": "uint256" } ], - "name": "setValidatorFee", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "getMinStake", + "name": "currentValidators", "outputs": [ { + "internalType": "address[]", "name": "", - "type": "uint256" + "type": "address[]" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { + "internalType": "uint256", "name": "_p", "type": "uint256" } @@ -281,404 +296,481 @@ "name": "currentValidatorsAtPosition", "outputs": [ { + "internalType": "address", "name": "", "type": "address" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": false, + "inputs": [], + "name": "currentValidatorsLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { "inputs": [ { + "internalType": "address", + "name": "_validator", + "type": "address" + } + ], + "name": "cycle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", "name": "_validator", "type": "address" } ], "name": "delegate", "outputs": [], - "payable": true, "stateMutability": "payable", "type": "function" }, { - "constant": true, - "inputs": [], - "name": "newValidatorSet", + "inputs": [ + { + "internalType": "address", + "name": "_address", + "type": "address" + }, + { + "internalType": "address", + "name": "_validator", + "type": "address" + } + ], + "name": "delegatedAmount", "outputs": [ { + "internalType": "uint256", "name": "", - "type": "address[]" + "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, - "inputs": [], - "name": "jailedValidators", + "inputs": [ + { + "internalType": "address", + "name": "_validator", + "type": "address" + } + ], + "name": "delegators", "outputs": [ { + "internalType": "address[]", "name": "", "type": "address[]" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { + "internalType": "address", "name": "_validator", "type": "address" }, { - "name": "_rewardAmount", + "internalType": "uint256", + "name": "_p", "type": "uint256" } ], - "name": "getDelegatorsForRewardDistribution", + "name": "delegatorsAtPosition", "outputs": [ { + "internalType": "address", "name": "", - "type": "address[]" - }, - { - "name": "", - "type": "uint256[]" + "type": "address" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, - "inputs": [], - "name": "STRIKE_RESET", + "inputs": [ + { + "internalType": "address", + "name": "_validator", + "type": "address" + } + ], + "name": "delegatorsLength", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": false, "inputs": [], - "name": "maintenance", + "name": "emitInitiateChange", "outputs": [], - "payable": false, "stateMutability": "nonpayable", "type": "function" }, { - "constant": false, "inputs": [], - "name": "unJail", + "name": "finalizeChange", "outputs": [], - "payable": false, "stateMutability": "nonpayable", "type": "function" }, { - "constant": true, "inputs": [], - "name": "MAX_VALIDATORS", + "name": "getCurrentCycleEndBlock", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "VALIDATOR_PRODUCTIVITY_BP", + "name": "getCurrentCycleStartBlock", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": false, "inputs": [], - "name": "finalizeChange", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", + "name": "getCycleDurationBlocks", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_validator", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_rewardAmount", + "type": "uint256" + } + ], + "name": "getDelegatorsForRewardDistribution", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "getMaxValidators", + "name": "getLastSnapshotTakenAtBlock", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, - "inputs": [ + "inputs": [], + "name": "getMaxStake", + "outputs": [ { - "name": "_validator", - "type": "address" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "name": "getStrikes", + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getMaxValidators", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, - "stateMutability": "view", + "stateMutability": "pure", "type": "function" }, { - "constant": true, - "inputs": [ + "inputs": [], + "name": "getMinStake", + "outputs": [ { - "name": "_validator", - "type": "address" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "name": "blockCounter", + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getMinValidatorFee", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, - "stateMutability": "view", + "stateMutability": "pure", "type": "function" }, { - "constant": true, "inputs": [], - "name": "CYCLE_DURATION_BLOCKS", + "name": "getNextSnapshotId", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": false, "inputs": [ { + "internalType": "address", "name": "_validator", "type": "address" } ], - "name": "cycle", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "MAX_STRIKE_COUNT", + "name": "getNodeVersion", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "getSnapshotsPerCycle", + "name": "getNodeVersionActivationBlock", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "requiredSignatures", + "name": "getProxyStorage", "outputs": [ { + "internalType": "address", "name": "", - "type": "uint256" + "type": "address" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { + "internalType": "address", "name": "_validator", "type": "address" } ], - "name": "delegators", + "name": "getReleaseBlock", "outputs": [ { + "internalType": "uint256", "name": "", - "type": "address[]" + "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "isFinalized", + "name": "getRequiredNodeVersion", "outputs": [ { + "internalType": "uint256", "name": "", - "type": "bool" + "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { - "name": "_p", + "internalType": "uint256", + "name": "_snapshotId", "type": "uint256" } ], - "name": "jailedValidatorsAtPosition", + "name": "getSnapshotAddresses", "outputs": [ { + "internalType": "address[]", "name": "", - "type": "address" + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getSnapshotsPerCycle", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "payable": false, - "stateMutability": "view", + "stateMutability": "pure", "type": "function" }, { - "constant": true, - "inputs": [], - "name": "DEFAULT_VALIDATOR_FEE", + "inputs": [ + { + "internalType": "address", + "name": "_validator", + "type": "address" + } + ], + "name": "getStrikeReset", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, - "inputs": [], - "name": "getCurrentCycleStartBlock", + "inputs": [ + { + "internalType": "address", + "name": "_validator", + "type": "address" + } + ], + "name": "getStrikes", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": false, - "inputs": [], - "name": "emitInitiateChange", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, "inputs": [], - "name": "totalStakeAmount", + "name": "getValidators", "outputs": [ { + "internalType": "address[]", "name": "", - "type": "uint256" + "type": "address[]" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { - "name": "_validator", + "internalType": "address", + "name": "_initialValidator", "type": "address" } ], - "name": "validatorFee", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { - "constant": true, "inputs": [ { + "internalType": "address", "name": "_validator", "type": "address" }, { + "internalType": "address", "name": "_address", "type": "address" } @@ -686,375 +778,414 @@ "name": "isDelegator", "outputs": [ { + "internalType": "bool", "name": "", "type": "bool" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "currentValidators", + "name": "isFinalized", "outputs": [ { + "internalType": "bool", "name": "", - "type": "address[]" + "type": "bool" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "getCycleDurationBlocks", + "name": "isInitialized", "outputs": [ { + "internalType": "bool", "name": "", - "type": "uint256" + "type": "bool" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, - "inputs": [], - "name": "pendingValidators", - "outputs": [ + "inputs": [ { - "name": "", - "type": "address[]" + "internalType": "address", + "name": "_address", + "type": "address" } ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getCurrentCycleEndBlock", + "name": "isJailed", "outputs": [ { + "internalType": "bool", "name": "", - "type": "uint256" + "type": "bool" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "getValidators", + "name": "isNodeVersionCheckExecuted", "outputs": [ { + "internalType": "bool", "name": "", - "type": "address[]" + "type": "bool" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { + "internalType": "address", "name": "_address", "type": "address" } ], - "name": "stakeAmount", + "name": "isPendingValidator", "outputs": [ { + "internalType": "bool", "name": "", - "type": "uint256" + "type": "bool" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": false, "inputs": [ { - "name": "_initialValidator", + "internalType": "address", + "name": "_address", "type": "address" } ], - "name": "initialize", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "MAX_STAKE", + "name": "isValidator", "outputs": [ { + "internalType": "bool", "name": "", - "type": "uint256" + "type": "bool" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "MIN_STAKE", + "name": "jailedValidators", "outputs": [ { + "internalType": "address[]", "name": "", - "type": "uint256" + "type": "address[]" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { - "name": "_validator", + "internalType": "uint256", + "name": "_p", + "type": "uint256" + } + ], + "name": "jailedValidatorsAtPosition", + "outputs": [ + { + "internalType": "address", + "name": "", "type": "address" } ], - "name": "getStrikeReset", + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "jailedValidatorsLength", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, - "inputs": [ + "inputs": [], + "name": "maintenance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "newValidatorSet", + "outputs": [ { - "name": "_validator", - "type": "address" + "internalType": "address[]", + "name": "", + "type": "address[]" } ], - "name": "delegatorsLength", + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "newValidatorSetLength", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "getNextSnapshotId", + "name": "pendingValidators", "outputs": [ { + "internalType": "address[]", "name": "", - "type": "uint256" + "type": "address[]" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { - "name": "_validator", - "type": "address" - }, - { + "internalType": "uint256", "name": "_p", "type": "uint256" } ], - "name": "delegatorsAtPosition", + "name": "pendingValidatorsAtPosition", "outputs": [ { + "internalType": "address", "name": "", "type": "address" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "getProxyStorage", + "name": "pendingValidatorsLength", "outputs": [ { + "internalType": "uint256", "name": "", - "type": "address" + "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { - "name": "_validator", - "type": "address" + "internalType": "uint256", + "name": "_version", + "type": "uint256" } ], - "name": "getReleaseBlock", + "name": "reportNodeVersion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "requiredSignatures", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, - "inputs": [], - "name": "shouldEmitInitiateChange", - "outputs": [ + "inputs": [ { - "name": "", - "type": "bool" + "internalType": "address", + "name": "_newAddress", + "type": "address" } ], - "payable": false, - "stateMutability": "view", + "name": "setProxyStorage", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { - "constant": false, "inputs": [ { - "name": "_validator", - "type": "address" + "internalType": "uint256", + "name": "_version", + "type": "uint256" }, { - "name": "_amount", + "internalType": "uint256", + "name": "_activationBlock", "type": "uint256" } ], - "name": "withdraw", + "name": "setRequiredNodeVersion", "outputs": [], - "payable": false, "stateMutability": "nonpayable", "type": "function" }, { - "constant": true, "inputs": [ { - "name": "_address", - "type": "address" + "internalType": "uint256", + "name": "_amount", + "type": "uint256" } ], - "name": "isValidator", + "name": "setValidatorFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "shouldEmitInitiateChange", "outputs": [ { + "internalType": "bool", "name": "", "type": "bool" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, + "inputs": [], + "name": "stake", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { "inputs": [ { + "internalType": "address", "name": "_address", "type": "address" } ], - "name": "isPendingValidator", + "name": "stakeAmount", "outputs": [ { + "internalType": "uint256", "name": "", - "type": "bool" + "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "getMaxStake", + "name": "totalStakeAmount", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "payable": true, - "stateMutability": "payable", - "type": "fallback" + "inputs": [], + "name": "unJail", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": false, - "name": "newSet", - "type": "address[]" + "internalType": "address", + "name": "_validator", + "type": "address" } ], - "name": "ChangeFinalized", - "type": "event" + "name": "validatorFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, - "inputs": [], - "name": "ShouldEmitInitiateChange", - "type": "event" + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, - "name": "parentHash", - "type": "bytes32" + "internalType": "address", + "name": "_validator", + "type": "address" }, { - "indexed": false, - "name": "newSet", - "type": "address[]" + "internalType": "uint256", + "name": "_amount", + "type": "uint256" } ], - "name": "InitiateChange", - "type": "event" + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" } -] \ No newline at end of file +] diff --git a/abis/EternalStorageProxy_abi.json b/abis/EternalStorageProxy_abi.json index 919894e..9352997 100644 --- a/abis/EternalStorageProxy_abi.json +++ b/abis/EternalStorageProxy_abi.json @@ -1,60 +1,26 @@ [ - { - "constant": true, - "inputs": [], - "name": "isInitialized", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { + "internalType": "address", "name": "_proxyStorage", "type": "address" }, { + "internalType": "address", "name": "_implementation", "type": "address" } ], - "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, - { - "payable": true, - "stateMutability": "payable", - "type": "fallback" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "version", - "type": "uint256" - }, - { - "indexed": true, - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, { "anonymous": false, "inputs": [ { "indexed": true, + "internalType": "address", "name": "previousOwner", "type": "address" } @@ -67,11 +33,13 @@ "inputs": [ { "indexed": true, + "internalType": "address", "name": "previousOwner", "type": "address" }, { "indexed": true, + "internalType": "address", "name": "newOwner", "type": "address" } @@ -80,101 +48,134 @@ "type": "event" }, { - "constant": false, + "anonymous": false, "inputs": [ { - "name": "_newImplementation", + "indexed": false, + "internalType": "uint256", + "name": "version", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "implementation", "type": "address" } ], - "name": "upgradeTo", + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "getImplementation", "outputs": [ { + "internalType": "address", "name": "", - "type": "bool" + "type": "address" } ], - "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { - "constant": false, "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ + "name": "getOwner", + "outputs": [ { - "name": "_newOwner", + "internalType": "address", + "name": "", "type": "address" } ], - "name": "transferOwnership", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "getOwner", + "name": "getProxyStorage", "outputs": [ { + "internalType": "address", "name": "", "type": "address" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], "name": "getVersion", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "getImplementation", + "name": "isInitialized", "outputs": [ { + "internalType": "bool", "name": "", - "type": "address" + "type": "bool" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "getProxyStorage", + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", "outputs": [ { + "internalType": "bool", "name": "", - "type": "address" + "type": "bool" } ], - "payable": false, - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" } ] diff --git a/abis/ProxyStorage_abi.json b/abis/ProxyStorage_abi.json index 1a3619e..15f3b05 100644 --- a/abis/ProxyStorage_abi.json +++ b/abis/ProxyStorage_abi.json @@ -1,33 +1,41 @@ [ { - "constant": true, - "inputs": [], - "name": "isInitialized", - "outputs": [ + "anonymous": false, + "inputs": [ { - "name": "", - "type": "bool" + "indexed": false, + "internalType": "uint256", + "name": "contractType", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "contractAddress", + "type": "address" } ], - "payable": false, - "stateMutability": "view", - "type": "function" + "name": "AddressSet", + "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": false, + "internalType": "address", "name": "consensus", "type": "address" }, { "indexed": false, + "internalType": "address", "name": "blockReward", "type": "address" }, { "indexed": false, + "internalType": "address", "name": "voting", "type": "address" } @@ -36,81 +44,92 @@ "type": "event" }, { - "anonymous": false, - "inputs": [ + "inputs": [], + "name": "getBlockReward", + "outputs": [ { - "indexed": false, - "name": "contractType", - "type": "uint256" - }, + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getConsensus", + "outputs": [ { - "indexed": false, - "name": "contractAddress", + "internalType": "address", + "name": "", "type": "address" } ], - "name": "AddressSet", - "type": "event" + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getVoting", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" }, { - "constant": false, "inputs": [ { + "internalType": "address", "name": "_consensus", "type": "address" } ], "name": "initialize", "outputs": [], - "payable": false, "stateMutability": "nonpayable", "type": "function" }, { - "constant": false, "inputs": [ { + "internalType": "address", "name": "_blockReward", "type": "address" }, { + "internalType": "address", "name": "_voting", "type": "address" } ], "name": "initializeAddresses", "outputs": [], - "payable": false, "stateMutability": "nonpayable", "type": "function" }, { - "constant": false, - "inputs": [ - { - "name": "_contractType", - "type": "uint256" - }, - { - "name": "_contractAddress", - "type": "address" - } - ], - "name": "setContractAddress", + "inputs": [], + "name": "isInitialized", "outputs": [ { + "internalType": "bool", "name": "", "type": "bool" } ], - "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { + "internalType": "uint256", "name": "_contractType", "type": "uint256" } @@ -118,54 +137,36 @@ "name": "isValidContractType", "outputs": [ { + "internalType": "bool", "name": "", "type": "bool" } ], - "payable": false, "stateMutability": "pure", "type": "function" }, { - "constant": true, - "inputs": [], - "name": "getConsensus", - "outputs": [ + "inputs": [ { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getBlockReward", - "outputs": [ + "internalType": "uint256", + "name": "_contractType", + "type": "uint256" + }, { - "name": "", + "internalType": "address", + "name": "_contractAddress", "type": "address" } ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getVoting", + "name": "setContractAddress", "outputs": [ { + "internalType": "bool", "name": "", - "type": "address" + "type": "bool" } ], - "payable": false, - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function" } ] diff --git a/abis/Voting_abi.json b/abis/Voting_abi.json index 762687b..df7c217 100644 --- a/abis/Voting_abi.json +++ b/abis/Voting_abi.json @@ -1,692 +1,792 @@ [ { - "constant": true, + "anonymous": false, "inputs": [ { - "name": "_id", + "indexed": true, + "internalType": "uint256", + "name": "id", "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "creator", + "type": "address" } ], - "name": "getStartBlock", - "outputs": [ + "name": "BallotCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { - "name": "", + "indexed": true, + "internalType": "uint256", + "name": "id", "type": "uint256" } ], - "payable": false, - "stateMutability": "view", - "type": "function" + "name": "BallotFinalized", + "type": "event" }, { - "constant": true, + "anonymous": false, "inputs": [ { - "name": "_id", + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "decision", "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "voter", + "type": "address" } ], - "name": "getQuorumState", + "name": "Vote", + "type": "event" + }, + { + "inputs": [], + "name": "DECIMALS", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "MIN_BALLOT_DURATION_CYCLES", + "name": "MAX_BALLOT_DURATION_CYCLES", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, - "inputs": [ + "inputs": [], + "name": "MAX_LIMIT_OF_BALLOTS", + "outputs": [ { - "name": "_id", + "internalType": "uint256", + "name": "", "type": "uint256" - }, - { - "name": "_key", - "type": "address" } ], - "name": "getVoterChoice", + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINIMUM_TURNOUT_BP", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, - "inputs": [ + "inputs": [], + "name": "MIN_BALLOT_DURATION_CYCLES", + "outputs": [ { - "name": "_id", + "internalType": "uint256", + "name": "", "type": "uint256" } ], - "name": "getAccepted", + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "activeBallots", "outputs": [ { + "internalType": "uint256[]", "name": "", - "type": "uint256" + "type": "uint256[]" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { - "name": "_id", + "internalType": "uint256", + "name": "_index", "type": "uint256" } ], - "name": "getIsFinalized", + "name": "activeBallotsAtIndex", "outputs": [ { + "internalType": "uint256", "name": "", - "type": "bool" + "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, - "inputs": [ - { - "name": "_id", - "type": "uint256" - } - ], - "name": "isActiveBallot", + "inputs": [], + "name": "activeBallotsLength", "outputs": [ { + "internalType": "uint256", "name": "", - "type": "bool" + "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { + "internalType": "uint256", "name": "_id", "type": "uint256" } ], - "name": "getFinalizeCalled", + "name": "canBeFinalized", "outputs": [ { + "internalType": "bool", "name": "", "type": "bool" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, - "inputs": [], - "name": "DECIMALS", + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + } + ], + "name": "getAccepted", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, - "inputs": [], - "name": "MINIMUM_TURNOUT_BP", + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_key", + "type": "address" + } + ], + "name": "getBallotInfo", "outputs": [ { - "name": "", + "internalType": "uint256", + "name": "startBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "endBlock", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isFinalized", + "type": "bool" + }, + { + "internalType": "address", + "name": "proposedValue", + "type": "address" + }, + { + "internalType": "uint256", + "name": "contractType", + "type": "uint256" + }, + { + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "internalType": "string", + "name": "description", + "type": "string" + }, + { + "internalType": "bool", + "name": "canBeFinalizedNow", + "type": "bool" + }, + { + "internalType": "bool", + "name": "alreadyVoted", + "type": "bool" + }, + { + "internalType": "bool", + "name": "belowTurnOut", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "accepted", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rejected", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalStake", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "isInitialized", + "name": "getBallotLimitPerValidator", "outputs": [ { + "internalType": "uint256", "name": "", - "type": "bool" + "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, - "inputs": [], - "name": "getNextBallotId", + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + } + ], + "name": "getBallotType", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { + "internalType": "uint256", "name": "_id", "type": "uint256" } ], - "name": "getTotalStake", + "name": "getBelowTurnOut", "outputs": [ { + "internalType": "bool", "name": "", - "type": "uint256" + "type": "bool" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, - "inputs": [], - "name": "MAX_BALLOT_DURATION_CYCLES", + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + } + ], + "name": "getContractType", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { + "internalType": "uint256", "name": "_id", "type": "uint256" } ], - "name": "getDescription", + "name": "getCreator", "outputs": [ { + "internalType": "address", "name": "", - "type": "string" + "type": "address" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { + "internalType": "uint256", "name": "_id", "type": "uint256" } ], - "name": "getBelowTurnOut", + "name": "getDescription", "outputs": [ { + "internalType": "string", "name": "", - "type": "bool" + "type": "string" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { + "internalType": "uint256", "name": "_id", "type": "uint256" } ], - "name": "getRejected", + "name": "getEndBlock", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, - "inputs": [], - "name": "activeBallotsLength", + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + } + ], + "name": "getFinalizeCalled", "outputs": [ { + "internalType": "bool", "name": "", - "type": "uint256" + "type": "bool" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { - "name": "_address", - "type": "address" + "internalType": "uint256", + "name": "_id", + "type": "uint256" } ], - "name": "isValidVotingKey", + "name": "getIndex", "outputs": [ { + "internalType": "uint256", "name": "", - "type": "bool" + "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { + "internalType": "uint256", "name": "_id", "type": "uint256" } ], - "name": "canBeFinalized", + "name": "getIsFinalized", "outputs": [ { + "internalType": "bool", "name": "", "type": "bool" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "MAX_LIMIT_OF_BALLOTS", + "name": "getMaxBallotDurationCycles", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, - "stateMutability": "view", + "stateMutability": "pure", "type": "function" }, { - "constant": true, "inputs": [], - "name": "getMaxBallotDurationCycles", + "name": "getMinBallotDurationCycles", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "pure", "type": "function" }, { - "constant": true, - "inputs": [ - { - "name": "_id", - "type": "uint256" - } - ], - "name": "getEndBlock", + "inputs": [], + "name": "getNextBallotId", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { + "internalType": "uint256", "name": "_id", "type": "uint256" } ], - "name": "getIndex", + "name": "getProposedActivationBlock", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { + "internalType": "uint256", "name": "_id", "type": "uint256" } ], - "name": "getContractType", + "name": "getProposedNodeVersion", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { + "internalType": "uint256", "name": "_id", "type": "uint256" - }, - { - "name": "_key", - "type": "address" } ], - "name": "hasAlreadyVoted", + "name": "getProposedValue", "outputs": [ { + "internalType": "address", "name": "", - "type": "bool" + "type": "address" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "activeBallots", + "name": "getProxyStorage", "outputs": [ { + "internalType": "address", "name": "", - "type": "uint256[]" + "type": "address" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { + "internalType": "uint256", "name": "_id", "type": "uint256" } ], - "name": "getCreator", + "name": "getQuorumState", "outputs": [ { + "internalType": "uint256", "name": "", - "type": "address" + "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { + "internalType": "uint256", "name": "_id", "type": "uint256" } ], - "name": "getProposedValue", + "name": "getRejected", "outputs": [ { + "internalType": "uint256", "name": "", - "type": "address" + "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { - "name": "_index", + "internalType": "uint256", + "name": "_id", "type": "uint256" } ], - "name": "activeBallotsAtIndex", + "name": "getStartBlock", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, - "inputs": [], - "name": "getProxyStorage", + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + } + ], + "name": "getTotalStake", "outputs": [ { + "internalType": "uint256", "name": "", - "type": "address" + "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { - "name": "_contractType", + "internalType": "uint256", + "name": "_id", "type": "uint256" + }, + { + "internalType": "address", + "name": "_key", + "type": "address" } ], - "name": "validContractType", + "name": "getVoterChoice", "outputs": [ { + "internalType": "uint256", "name": "", - "type": "bool" + "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, - "inputs": [], - "name": "getMinBallotDurationCycles", + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_key", + "type": "address" + } + ], + "name": "hasAlreadyVoted", "outputs": [ { + "internalType": "bool", "name": "", - "type": "uint256" + "type": "bool" } ], - "payable": false, - "stateMutability": "pure", + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { - "constant": true, "inputs": [ { - "name": "_key", - "type": "address" + "internalType": "uint256", + "name": "_id", + "type": "uint256" } ], - "name": "validatorActiveBallots", + "name": "isActiveBallot", "outputs": [ { + "internalType": "bool", "name": "", - "type": "uint256" + "type": "bool" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "getBallotLimitPerValidator", + "name": "isInitialized", "outputs": [ { + "internalType": "bool", "name": "", - "type": "uint256" + "type": "bool" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, - "name": "id", - "type": "uint256" - }, - { - "indexed": true, - "name": "creator", + "internalType": "address", + "name": "_address", "type": "address" } ], - "name": "BallotCreated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "id", - "type": "uint256" - } - ], - "name": "BallotFinalized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "id", - "type": "uint256" - }, - { - "indexed": false, - "name": "decision", - "type": "uint256" - }, + "name": "isValidVotingKey", + "outputs": [ { - "indexed": true, - "name": "voter", - "type": "address" + "internalType": "bool", + "name": "", + "type": "bool" } ], - "name": "Vote", - "type": "event" - }, - { - "constant": false, - "inputs": [], - "name": "initialize", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { - "constant": false, "inputs": [ { + "internalType": "uint256", "name": "_startAfterNumberOfCycles", "type": "uint256" }, { + "internalType": "uint256", "name": "_cyclesDuration", "type": "uint256" }, { + "internalType": "uint256", "name": "_contractType", "type": "uint256" }, { + "internalType": "address", "name": "_proposedValue", "type": "address" }, { + "internalType": "string", "name": "_description", "type": "string" } @@ -694,114 +794,119 @@ "name": "newBallot", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "nonpayable", "type": "function" }, { - "constant": true, "inputs": [ { - "name": "_id", + "internalType": "uint256", + "name": "_startAfterNumberOfCycles", "type": "uint256" }, { - "name": "_key", - "type": "address" - } - ], - "name": "getBallotInfo", - "outputs": [ - { - "name": "startBlock", + "internalType": "uint256", + "name": "_cyclesDuration", "type": "uint256" }, { - "name": "endBlock", + "internalType": "uint256", + "name": "_version", "type": "uint256" }, { - "name": "isFinalized", - "type": "bool" - }, - { - "name": "proposedValue", - "type": "address" - }, - { - "name": "contractType", + "internalType": "uint256", + "name": "_activationBlock", "type": "uint256" }, { - "name": "creator", - "type": "address" - }, - { - "name": "description", + "internalType": "string", + "name": "_description", "type": "string" - }, - { - "name": "canBeFinalizedNow", - "type": "bool" - }, - { - "name": "alreadyVoted", - "type": "bool" - }, - { - "name": "belowTurnOut", - "type": "bool" - }, + } + ], + "name": "newNodeVersionBallot", + "outputs": [ { - "name": "accepted", + "internalType": "uint256", + "name": "", "type": "uint256" - }, + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ { - "name": "rejected", - "type": "uint256" - }, + "internalType": "address[]", + "name": "validators", + "type": "address[]" + } + ], + "name": "onCycleEnd", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ { - "name": "totalStake", + "internalType": "uint256", + "name": "_contractType", "type": "uint256" } ], - "payable": false, + "name": "validContractType", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], "stateMutability": "view", "type": "function" }, { - "constant": false, "inputs": [ { - "name": "_id", - "type": "uint256" - }, + "internalType": "address", + "name": "_key", + "type": "address" + } + ], + "name": "validatorActiveBallots", + "outputs": [ { - "name": "_choice", + "internalType": "uint256", + "name": "", "type": "uint256" } ], - "name": "vote", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { - "constant": false, "inputs": [ { - "name": "validators", - "type": "address[]" + "internalType": "uint256", + "name": "_id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_choice", + "type": "uint256" } ], - "name": "onCycleEnd", + "name": "vote", "outputs": [], - "payable": false, "stateMutability": "nonpayable", "type": "function" } diff --git a/app/abi/blockReward.json b/app/abi/blockReward.json index becd4c4..d1ba8dd 100644 --- a/app/abi/blockReward.json +++ b/app/abi/blockReward.json @@ -1,244 +1,252 @@ [ { - "constant": true, + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address[]", + "name": "receivers", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "rewards", + "type": "uint256[]" + } + ], + "name": "Rewarded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "RewardedOnCycle", + "type": "event" + }, + { "inputs": [], - "name": "DECIMALS", + "name": "BLOCKS_PER_YEAR", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "isInitialized", + "name": "DECIMALS", "outputs": [ { + "internalType": "uint256", "name": "", - "type": "bool" + "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], "name": "INFLATION", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "BLOCKS_PER_YEAR", + "name": "emitRewardedOnCycle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getBlockRewardAmount", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": false, - "name": "receivers", - "type": "address[]" - }, - { - "indexed": false, - "name": "rewards", - "type": "uint256[]" + "internalType": "address", + "name": "_validator", + "type": "address" } ], - "name": "Rewarded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + "name": "getBlockRewardAmountPerValidator", + "outputs": [ { - "indexed": false, - "name": "amount", + "internalType": "uint256", + "name": "", "type": "uint256" } ], - "name": "RewardedOnCycle", - "type": "event" + "stateMutability": "view", + "type": "function" }, { - "constant": false, - "inputs": [ + "inputs": [], + "name": "getBlocksPerYear", + "outputs": [ { - "name": "_supply", + "internalType": "uint256", + "name": "", "type": "uint256" } ], - "name": "initialize", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "pure", "type": "function" }, { - "constant": false, - "inputs": [ - { - "name": "benefactors", - "type": "address[]" - }, - { - "name": "kind", - "type": "uint16[]" - } - ], - "name": "reward", + "inputs": [], + "name": "getInflation", "outputs": [ { + "internalType": "uint256", "name": "", - "type": "address[]" - }, - { - "name": "", - "type": "uint256[]" + "type": "uint256" } ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "onCycleEnd", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "emitRewardedOnCycle", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "pure", "type": "function" }, { - "constant": true, "inputs": [], - "name": "getTotalSupply", + "name": "getProxyStorage", "outputs": [ { + "internalType": "address", "name": "", - "type": "uint256" + "type": "address" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], "name": "getRewardedOnCycle", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "getInflation", + "name": "getTotalSupply", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, - "stateMutability": "pure", + "stateMutability": "view", "type": "function" }, { - "constant": true, - "inputs": [], - "name": "getBlocksPerYear", - "outputs": [ + "inputs": [ { - "name": "", + "internalType": "uint256", + "name": "_supply", "type": "uint256" } ], - "payable": false, - "stateMutability": "pure", + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { - "constant": true, "inputs": [], - "name": "getBlockRewardAmount", + "name": "isInitialized", "outputs": [ { + "internalType": "bool", "name": "", - "type": "uint256" + "type": "bool" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "getProxyStorage", + "name": "onCycleEnd", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "benefactors", + "type": "address[]" + }, + { + "internalType": "uint16[]", + "name": "kind", + "type": "uint16[]" + } + ], + "name": "reward", "outputs": [ { + "internalType": "address[]", "name": "", - "type": "address" + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" } ], - "payable": false, - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function" }, { - "constant": true, "inputs": [], "name": "shouldEmitRewardedOnCycle", "outputs": [ { + "internalType": "bool", "name": "", "type": "bool" } ], - "payable": false, "stateMutability": "view", "type": "function" } -] \ No newline at end of file +] diff --git a/app/abi/consensus.json b/app/abi/consensus.json index 0fe7207..36f699f 100644 --- a/app/abi/consensus.json +++ b/app/abi/consensus.json @@ -1,232 +1,496 @@ [ { - "constant": true, + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address[]", + "name": "newSet", + "type": "address[]" + } + ], + "name": "ChangeFinalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "parentHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address[]", + "name": "newSet", + "type": "address[]" + } + ], + "name": "InitiateChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "requiredVersion", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "upgradedCount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalCount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bool", + "name": "quorumReached", + "type": "bool" + } + ], + "name": "NodeVersionCheckExecuted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "validator", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "version", + "type": "uint256" + } + ], + "name": "NodeVersionReported", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "version", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "activationBlock", + "type": "uint256" + } + ], + "name": "RequiredNodeVersionSet", + "type": "event" + }, + { + "anonymous": false, "inputs": [], - "name": "getLastSnapshotTakenAtBlock", + "name": "ShouldEmitInitiateChange", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "CYCLE_DURATION_BLOCKS", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, - "inputs": [ + "inputs": [], + "name": "DECIMALS", + "outputs": [ { - "name": "_p", + "internalType": "uint256", + "name": "", "type": "uint256" } ], - "name": "pendingValidatorsAtPosition", + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_VALIDATOR_FEE", "outputs": [ { + "internalType": "uint256", "name": "", - "type": "address" + "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, - "inputs": [ + "inputs": [], + "name": "MAX_STAKE", + "outputs": [ { - "name": "_snapshotId", + "internalType": "uint256", + "name": "", "type": "uint256" } ], - "name": "getSnapshotAddresses", + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_STRIKE_COUNT", "outputs": [ { + "internalType": "uint256", "name": "", - "type": "address[]" + "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": false, - "inputs": [ + "inputs": [], + "name": "MAX_VALIDATORS", + "outputs": [ { - "name": "_newAddress", - "type": "address" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "name": "setProxyStorage", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { - "constant": true, - "inputs": [ - { - "name": "_address", - "type": "address" - }, + "inputs": [], + "name": "MIN_STAKE", + "outputs": [ { - "name": "_validator", - "type": "address" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "name": "delegatedAmount", + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SNAPSHOTS_PER_CYCLE", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "SNAPSHOTS_PER_CYCLE", + "name": "STRIKE_RESET", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "pendingValidatorsLength", + "name": "UPGRADE_QUORUM_BP", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "newValidatorSetLength", + "name": "VALIDATOR_PRODUCTIVITY_BP", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, - "inputs": [], - "name": "DECIMALS", + "inputs": [ + { + "internalType": "address", + "name": "_validator", + "type": "address" + } + ], + "name": "blockCounter", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "isInitialized", + "name": "currentValidators", "outputs": [ { + "internalType": "address[]", "name": "", - "type": "bool" + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_p", + "type": "uint256" + } + ], + "name": "currentValidatorsAtPosition", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], "name": "currentValidatorsLength", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, - "inputs": [], - "name": "getMinStake", + "inputs": [ + { + "internalType": "address", + "name": "_validator", + "type": "address" + } + ], + "name": "cycle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_validator", + "type": "address" + } + ], + "name": "delegate", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_address", + "type": "address" + }, + { + "internalType": "address", + "name": "_validator", + "type": "address" + } + ], + "name": "delegatedAmount", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, - "stateMutability": "pure", + "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { + "internalType": "address", + "name": "_validator", + "type": "address" + } + ], + "name": "delegators", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_validator", + "type": "address" + }, + { + "internalType": "uint256", "name": "_p", "type": "uint256" } ], - "name": "currentValidatorsAtPosition", + "name": "delegatorsAtPosition", "outputs": [ { + "internalType": "address", "name": "", "type": "address" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "_validator", + "type": "address" + } + ], + "name": "delegatorsLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { "inputs": [], - "name": "newValidatorSet", + "name": "emitInitiateChange", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "finalizeChange", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentCycleEndBlock", "outputs": [ { + "internalType": "uint256", "name": "", - "type": "address[]" + "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, + "inputs": [], + "name": "getCurrentCycleStartBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCycleDurationBlocks", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { "inputs": [ { + "internalType": "address", "name": "_validator", "type": "address" }, { + "internalType": "uint256", "name": "_rewardAmount", "type": "uint256" } @@ -234,176 +498,279 @@ "name": "getDelegatorsForRewardDistribution", "outputs": [ { + "internalType": "address[]", "name": "", "type": "address[]" }, { + "internalType": "uint256[]", "name": "", "type": "uint256[]" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "MAX_VALIDATORS", + "name": "getLastSnapshotTakenAtBlock", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, + "inputs": [], + "name": "getMaxStake", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { "inputs": [], "name": "getMaxValidators", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "pure", "type": "function" }, { - "constant": true, "inputs": [], - "name": "CYCLE_DURATION_BLOCKS", + "name": "getMinStake", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, - "stateMutability": "view", + "stateMutability": "pure", "type": "function" }, { - "constant": true, "inputs": [], - "name": "getSnapshotsPerCycle", + "name": "getMinValidatorFee", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "pure", "type": "function" }, { - "constant": true, "inputs": [], - "name": "requiredSignatures", + "name": "getNextSnapshotId", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { + "internalType": "address", "name": "_validator", "type": "address" } ], - "name": "delegators", + "name": "getNodeVersion", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getNodeVersionActivationBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getProxyStorage", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_validator", + "type": "address" + } + ], + "name": "getReleaseBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRequiredNodeVersion", "outputs": [ { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_snapshotId", + "type": "uint256" + } + ], + "name": "getSnapshotAddresses", + "outputs": [ + { + "internalType": "address[]", "name": "", "type": "address[]" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "isFinalized", + "name": "getSnapshotsPerCycle", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_validator", + "type": "address" + } + ], + "name": "getStrikeReset", "outputs": [ { + "internalType": "uint256", "name": "", - "type": "bool" + "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, - "inputs": [], - "name": "DEFAULT_VALIDATOR_FEE", + "inputs": [ + { + "internalType": "address", + "name": "_validator", + "type": "address" + } + ], + "name": "getStrikes", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "getCurrentCycleStartBlock", + "name": "getValidators", "outputs": [ { + "internalType": "address[]", "name": "", - "type": "uint256" + "type": "address[]" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { - "name": "_validator", + "internalType": "address", + "name": "_initialValidator", "type": "address" } ], - "name": "validatorFee", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { - "constant": true, "inputs": [ { + "internalType": "address", "name": "_validator", "type": "address" }, { + "internalType": "address", "name": "_address", "type": "address" } @@ -411,387 +778,414 @@ "name": "isDelegator", "outputs": [ { + "internalType": "bool", "name": "", "type": "bool" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "currentValidators", + "name": "isFinalized", "outputs": [ { + "internalType": "bool", "name": "", - "type": "address[]" + "type": "bool" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "getCycleDurationBlocks", + "name": "isInitialized", "outputs": [ { + "internalType": "bool", "name": "", - "type": "uint256" + "type": "bool" } ], - "payable": false, - "stateMutability": "pure", + "stateMutability": "view", "type": "function" }, { - "constant": true, - "inputs": [], - "name": "pendingValidators", + "inputs": [ + { + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "isJailed", "outputs": [ { + "internalType": "bool", "name": "", - "type": "address[]" + "type": "bool" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "getCurrentCycleEndBlock", + "name": "isNodeVersionCheckExecuted", "outputs": [ { + "internalType": "bool", "name": "", - "type": "uint256" + "type": "bool" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { + "internalType": "address", "name": "_address", "type": "address" } ], - "name": "stakeAmount", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "MIN_STAKE", + "name": "isPendingValidator", "outputs": [ { + "internalType": "bool", "name": "", - "type": "uint256" + "type": "bool" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { - "name": "_validator", + "internalType": "address", + "name": "_address", "type": "address" } ], - "name": "delegatorsLength", + "name": "isValidator", "outputs": [ { + "internalType": "bool", "name": "", - "type": "uint256" + "type": "bool" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "getNextSnapshotId", + "name": "jailedValidators", "outputs": [ { + "internalType": "address[]", "name": "", - "type": "uint256" + "type": "address[]" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { - "name": "_validator", - "type": "address" - }, - { + "internalType": "uint256", "name": "_p", "type": "uint256" } ], - "name": "delegatorsAtPosition", + "name": "jailedValidatorsAtPosition", "outputs": [ { + "internalType": "address", "name": "", "type": "address" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "getProxyStorage", + "name": "jailedValidatorsLength", "outputs": [ { + "internalType": "uint256", "name": "", - "type": "address" + "type": "uint256" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "shouldEmitInitiateChange", + "name": "maintenance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "newValidatorSet", "outputs": [ { + "internalType": "address[]", "name": "", - "type": "bool" + "type": "address[]" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, - "inputs": [ + "inputs": [], + "name": "newValidatorSetLength", + "outputs": [ { - "name": "_address", - "type": "address" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "name": "isValidator", + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingValidators", "outputs": [ { + "internalType": "address[]", "name": "", - "type": "bool" + "type": "address[]" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ { - "name": "_address", - "type": "address" + "internalType": "uint256", + "name": "_p", + "type": "uint256" } ], - "name": "isPendingValidator", + "name": "pendingValidatorsAtPosition", "outputs": [ { + "internalType": "address", "name": "", - "type": "bool" + "type": "address" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "payable": true, - "stateMutability": "payable", - "type": "fallback" + "inputs": [], + "name": "pendingValidatorsLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": false, - "name": "newSet", - "type": "address[]" + "internalType": "uint256", + "name": "_version", + "type": "uint256" } ], - "name": "ChangeFinalized", - "type": "event" + "name": "reportNodeVersion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [], - "name": "ShouldEmitInitiateChange", - "type": "event" + "name": "requiredSignatures", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, - "name": "parentHash", - "type": "bytes32" + "internalType": "address", + "name": "_newAddress", + "type": "address" + } + ], + "name": "setProxyStorage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_version", + "type": "uint256" }, { - "indexed": false, - "name": "newSet", - "type": "address[]" + "internalType": "uint256", + "name": "_activationBlock", + "type": "uint256" } ], - "name": "InitiateChange", - "type": "event" + "name": "setRequiredNodeVersion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "constant": false, "inputs": [ { - "name": "_initialValidator", - "type": "address" + "internalType": "uint256", + "name": "_amount", + "type": "uint256" } ], - "name": "initialize", + "name": "setValidatorFee", "outputs": [], - "payable": false, "stateMutability": "nonpayable", "type": "function" }, { - "constant": true, "inputs": [], - "name": "getValidators", + "name": "shouldEmitInitiateChange", "outputs": [ { + "internalType": "bool", "name": "", - "type": "address[]" + "type": "bool" } ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": false, - "inputs": [], - "name": "finalizeChange", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, "inputs": [], "name": "stake", "outputs": [], - "payable": true, "stateMutability": "payable", "type": "function" }, { - "constant": false, "inputs": [ { - "name": "_validator", + "internalType": "address", + "name": "_address", "type": "address" } ], - "name": "delegate", - "outputs": [], - "payable": true, - "stateMutability": "payable", + "name": "stakeAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", "type": "function" }, { - "constant": false, - "inputs": [ + "inputs": [], + "name": "totalStakeAmount", + "outputs": [ { - "name": "_amount", + "internalType": "uint256", + "name": "", "type": "uint256" } ], - "name": "withdraw", + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unJail", "outputs": [], - "payable": false, "stateMutability": "nonpayable", "type": "function" }, { - "constant": false, "inputs": [ { + "internalType": "address", "name": "_validator", "type": "address" - }, + } + ], + "name": "validatorFee", + "outputs": [ { - "name": "_amount", + "internalType": "uint256", + "name": "", "type": "uint256" } ], - "name": "withdraw", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "cycle", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { - "constant": false, - "inputs": [], - "name": "emitInitiateChange", + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdraw", "outputs": [], - "payable": false, "stateMutability": "nonpayable", "type": "function" }, { - "constant": false, "inputs": [ { + "internalType": "address", + "name": "_validator", + "type": "address" + }, + { + "internalType": "uint256", "name": "_amount", "type": "uint256" } ], - "name": "setValidatorFee", + "name": "withdraw", "outputs": [], - "payable": false, "stateMutability": "nonpayable", "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" } -] \ No newline at end of file +] diff --git a/app/index.js b/app/index.js index 4295983..1b06657 100644 --- a/app/index.js +++ b/app/index.js @@ -70,6 +70,65 @@ function initBlockRewardContract() { blockReward = new web3.eth.Contract(require(path.join(cwd, 'abi/blockReward')), process.env.BLOCK_REWARD_ADDRESS) } +function encodeNodeVersion(versionString) { + // use the last x.y.z component of the version string, so for a client image tag + // like 1.29.0-v6.0.3 the spec version (6.0.3) is the one reported + const re = /v?(\d+)\.(\d+)\.(\d+)/g + let match, last + while ((match = re.exec(versionString)) !== null) { + last = match + } + if (!last) { + return null + } + return parseInt(last[1]) * 1e6 + parseInt(last[2]) * 1e3 + parseInt(last[3]) +} + +let nodeVersionReported = false + +function reportNodeVersion() { + return new Promise(async (resolve) => { + try { + if (nodeVersionReported || !process.env.NODE_VERSION) { + return resolve() + } + const version = encodeNodeVersion(process.env.NODE_VERSION) + if (!version) { + logger.warn(`could not parse NODE_VERSION "${process.env.NODE_VERSION}", skipping version report`) + nodeVersionReported = true + return resolve() + } + const reported = await consensus.methods.getNodeVersion(account).call() + if (reported.toString() === version.toString()) { + logger.info(`node version ${version} already reported`) + nodeVersionReported = true + return resolve() + } + logger.info(`${account} sending reportNodeVersion(${version}) transaction`) + let nonce = await getNonce() + let gasPrice = await getGasPrice() + consensus.methods.reportNodeVersion(version).send({ from: account, gas: process.env.GAS || 1000000, gasPrice: process.env.GAS_PRICE || gasPrice, nonce: nonce }) + .on('transactionHash', hash => { + logger.info(`transactionHash: ${hash}`) + }) + .on('confirmation', (confirmationNumber, receipt) => { + if (confirmationNumber == 1) { + logger.debug(`receipt: ${JSON.stringify(receipt)}`) + } + nodeVersionReported = true + resolve() + }) + .on('error', error => { + logger.error(error); resolve() + }) + } catch (e) { + // do not crash the cycle loop if the consensus contract does not support version reporting yet + logger.warn(`reportNodeVersion failed: ${e.message}`) + resolve() + } + }) +} + function emitInitiateChange() { return new Promise(async (resolve, reject) => { try { @@ -148,6 +207,9 @@ async function runMain() { if (!blockReward) { initBlockRewardContract() } + // report the node version before the validator check - a version-jailed validator + // is no longer in the current set but must report its new version to be released + await reportNodeVersion() const isValidator = await consensus.methods.isValidator(web3.utils.toChecksumAddress(account)).call() if (!isValidator) { logger.warn(`${account} is not a validator, skipping`) diff --git a/contracts/Consensus.sol b/contracts/Consensus.sol index 3f8017c..7c475da 100644 --- a/contracts/Consensus.sol +++ b/contracts/Consensus.sol @@ -100,6 +100,7 @@ contract Consensus is ConsensusUtils { IVoting(ProxyStorage(getProxyStorage()).getVoting()).onCycleEnd(currentValidators()); _setCurrentCycle(); _checkJail(currentValidators()); + _checkNodeVersions(currentValidators()); address[] memory newSet = pendingValidators(); if (newSet.length > 0) { _setNewValidatorSet(newSet); @@ -136,9 +137,13 @@ contract Consensus is ConsensusUtils { /** * @dev Function to be called by jailed validator, in order to be released from jail + * When a network upgrade is scheduled, running (and reporting) the required node version is a release precondition */ function unJail() external onlyJailedValidator { require(getReleaseBlock(msg.sender) <= getCurrentCycleEndBlock()); + if (getRequiredNodeVersion() != 0) { + require(getNodeVersion(msg.sender) >= getRequiredNodeVersion()); + } _removeFromJail(msg.sender); } diff --git a/contracts/ConsensusUtils.sol b/contracts/ConsensusUtils.sol index bd39e79..40864e9 100644 --- a/contracts/ConsensusUtils.sol +++ b/contracts/ConsensusUtils.sol @@ -20,6 +20,7 @@ abstract contract ConsensusUtils is EternalStorage, ValidatorSet { uint256 public constant VALIDATOR_PRODUCTIVITY_BP = 3000; // 30% uint256 public constant MAX_STRIKE_COUNT = 5; uint256 public constant STRIKE_RESET = 50; // reset strikes after 50 clean cycles + uint256 public constant UPGRADE_QUORUM_BP = 6600; // node version jailing only kicks in once more than 66% of validators have upgraded /** * @dev This event will be emitted after a change to the validator set has been finalized @@ -32,6 +33,29 @@ abstract contract ConsensusUtils is EternalStorage, ValidatorSet { */ event ShouldEmitInitiateChange(); + /** + * @dev This event will be emitted when a validator reports the node version it is running + * @param validator the reporting validator + * @param version the reported version (encoded as major * 1e6 + minor * 1e3 + patch) + */ + event NodeVersionReported(address indexed validator, uint256 version); + + /** + * @dev This event will be emitted when a network upgrade is scheduled + * @param version minimum node version required for the upgrade (0 means the scheduled upgrade was cleared) + * @param activationBlock block at which the new spec activates + */ + event RequiredNodeVersionSet(uint256 version, uint256 activationBlock); + + /** + * @dev This event will be emitted when the node version check has run on the last cycle boundary before an upgrade + * @param requiredVersion minimum node version required + * @param upgradedCount number of current validators which reported the required version (or higher) + * @param totalCount total number of current validators + * @param quorumReached whether more than 66% of validators have upgraded (outdated validators only get jailed if true) + */ + event NodeVersionCheckExecuted(uint256 requiredVersion, uint256 upgradedCount, uint256 totalCount, bool quorumReached); + /** * @dev This modifier verifies that the change initiated has not been finalized yet */ @@ -64,6 +88,14 @@ abstract contract ConsensusUtils is EternalStorage, ValidatorSet { _; } + /** + * @dev This modifier verifies that msg.sender is the voting contract + */ + modifier onlyVoting() { + require(msg.sender == ProxyStorage(getProxyStorage()).getVoting()); + _; + } + /** * @dev This modifier verifies that msg.sender is a validator */ @@ -95,6 +127,9 @@ abstract contract ConsensusUtils is EternalStorage, ValidatorSet { bytes32 internal constant SHOULD_EMIT_INITIATE_CHANGE = keccak256(abi.encodePacked("shouldEmitInitiateChange")); bytes32 internal constant TOTAL_STAKE_AMOUNT = keccak256(abi.encodePacked("totalStakeAmount")); bytes32 internal constant JAILED_VALIDATORS = keccak256(abi.encodePacked("jailedValidators")); + bytes32 internal constant REQUIRED_NODE_VERSION = keccak256(abi.encodePacked("requiredNodeVersion")); + bytes32 internal constant NODE_VERSION_ACTIVATION_BLOCK = keccak256(abi.encodePacked("nodeVersionActivationBlock")); + bytes32 internal constant NODE_VERSION_CHECK_EXECUTED = keccak256(abi.encodePacked("nodeVersionCheckExecuted")); function _delegate(address _staker, uint256 _amount, address _validator) internal { require(_staker != address(0)); @@ -240,6 +275,94 @@ abstract contract ConsensusUtils is EternalStorage, ValidatorSet { } } + /** + * @dev Function to be called by validators (their node app) to report the node/spec version they are running + * @param _version the version encoded as major * 1e6 + minor * 1e3 + patch (e.g. 6.0.3 => 6000003) + */ + function reportNodeVersion(uint256 _version) external { + require(_version != 0); + uintStorage[keccak256(abi.encodePacked("nodeVersion", msg.sender))] = _version; + emit NodeVersionReported(msg.sender, _version); + } + + function getNodeVersion(address _validator) public view returns(uint256) { + return uintStorage[keccak256(abi.encodePacked("nodeVersion", _validator))]; + } + + /** + * @dev Function to be called by the voting contract (on an accepted node version ballot) to schedule + * a network upgrade. On the last cycle boundary before _activationBlock, current validators which + * have not reported at least _version are jailed, provided more than 66% of the current validator + * set has upgraded. + * Should be scheduled at least 2 cycles before the new spec activates. + * Calling with _version == 0 clears a scheduled upgrade. + * @param _version minimum required node version (encoded as major * 1e6 + minor * 1e3 + patch) + * @param _activationBlock block at which the new spec activates + */ + function setRequiredNodeVersion(uint256 _version, uint256 _activationBlock) external onlyVoting { + _setRequiredNodeVersion(_version, _activationBlock); + } + + function _setRequiredNodeVersion(uint256 _version, uint256 _activationBlock) internal { + if (_version != 0) { + require(_activationBlock > block.number); + uintStorage[REQUIRED_NODE_VERSION] = _version; + uintStorage[NODE_VERSION_ACTIVATION_BLOCK] = _activationBlock; + } else { + uintStorage[REQUIRED_NODE_VERSION] = 0; + uintStorage[NODE_VERSION_ACTIVATION_BLOCK] = 0; + } + boolStorage[NODE_VERSION_CHECK_EXECUTED] = false; + emit RequiredNodeVersionSet(_version, _activationBlock); + } + + function getRequiredNodeVersion() public view returns(uint256) { + return uintStorage[REQUIRED_NODE_VERSION]; + } + + function getNodeVersionActivationBlock() public view returns(uint256) { + return uintStorage[NODE_VERSION_ACTIVATION_BLOCK]; + } + + function isNodeVersionCheckExecuted() public view returns(bool) { + return boolStorage[NODE_VERSION_CHECK_EXECUTED]; + } + + /** + * Internal function called on cycle end (after _setCurrentCycle), so getCurrentCycleEndBlock() is the + * end of the upcoming cycle. The check fires once, on the last cycle boundary before the scheduled + * activation block, so outdated validators are excluded from the validator set which is active when + * the new spec comes in. + */ + function _checkNodeVersions(address[] memory _validatorSet) internal { + uint256 required = uintStorage[REQUIRED_NODE_VERSION]; + if (required == 0 || boolStorage[NODE_VERSION_CHECK_EXECUTED]) { + return; + } + if (getCurrentCycleEndBlock() < uintStorage[NODE_VERSION_ACTIVATION_BLOCK]) { + // the upcoming cycle ends before the upgrade activates - too early to check + return; + } + + uint256 upgradedCount = 0; + for (uint256 i = 0; i < _validatorSet.length; i++) { + if (getNodeVersion(_validatorSet[i]) >= required) { + upgradedCount++; + } + } + + bool quorumReached = upgradedCount * 10000 > _validatorSet.length * UPGRADE_QUORUM_BP; + if (quorumReached) { + for (uint256 i = 0; i < _validatorSet.length; i++) { + if (getNodeVersion(_validatorSet[i]) < required) { + _jailValidator(_validatorSet[i]); + } + } + } + boolStorage[NODE_VERSION_CHECK_EXECUTED] = true; + emit NodeVersionCheckExecuted(required, upgradedCount, _validatorSet.length, quorumReached); + } + function getCurrentCycleStartBlock() external view returns(uint256) { return uintStorage[CURRENT_CYCLE_START_BLOCK]; } diff --git a/contracts/Voting.sol b/contracts/Voting.sol index 2f95289..943fee9 100644 --- a/contracts/Voting.sol +++ b/contracts/Voting.sol @@ -29,11 +29,33 @@ contract Voting is VotingUtils { require(_proposedValue != address(0)); require(validContractType(_contractType)); uint256 ballotId = _createBallot(_startAfterNumberOfCycles, _cyclesDuration, _description); + _setBallotType(ballotId, uint256(BallotTypes.ContractAddress)); _setProposedValue(ballotId, _proposedValue); _setContractType(ballotId, _contractType); return ballotId; } + /** + * @dev Function to create a new ballot for scheduling a network upgrade. If accepted, validators which + * have not reported at least the proposed node version get jailed on the last cycle boundary before the + * activation block (see Consensus.setRequiredNodeVersion) + * @param _startAfterNumberOfCycles number of cycles after which the ballot should open for voting + * @param _cyclesDuration number of cycles the ballot will remain open for voting + * @param _version minimum required node version (encoded as major * 1e6 + minor * 1e3 + patch). 0 proposes cancelling a scheduled upgrade + * @param _activationBlock block at which the new spec activates + * @param _description ballot text description + */ + function newNodeVersionBallot(uint256 _startAfterNumberOfCycles, uint256 _cyclesDuration, uint256 _version, uint256 _activationBlock, string calldata _description) external onlyValidVotingKey(msg.sender) onlyValidDuration(_startAfterNumberOfCycles, _cyclesDuration) returns(uint256) { + if (_version != 0) { + require(_activationBlock > block.number); + } + uint256 ballotId = _createBallot(_startAfterNumberOfCycles, _cyclesDuration, _description); + _setBallotType(ballotId, uint256(BallotTypes.NodeVersion)); + _setProposedNodeVersion(ballotId, _version); + _setProposedActivationBlock(ballotId, _activationBlock); + return ballotId; + } + /** * @dev Function to get specific ballot info along with voters involvment on it * @param _id ballot id to get info of diff --git a/contracts/VotingUtils.sol b/contracts/VotingUtils.sol index 9660648..e0f24fc 100644 --- a/contracts/VotingUtils.sol +++ b/contracts/VotingUtils.sol @@ -136,6 +136,30 @@ abstract contract VotingUtils is EternalStorage, VotingBase { uintStorage[keccak256(abi.encodePacked("votingState", _id, "contractType"))] = _value; } + function getBallotType(uint256 _id) public view returns(uint256) { + return uintStorage[keccak256(abi.encodePacked("votingState", _id, "ballotType"))]; + } + + function _setBallotType(uint256 _id, uint256 _value) internal { + uintStorage[keccak256(abi.encodePacked("votingState", _id, "ballotType"))] = _value; + } + + function getProposedNodeVersion(uint256 _id) public view returns(uint256) { + return uintStorage[keccak256(abi.encodePacked("votingState", _id, "proposedNodeVersion"))]; + } + + function _setProposedNodeVersion(uint256 _id, uint256 _value) internal { + uintStorage[keccak256(abi.encodePacked("votingState", _id, "proposedNodeVersion"))] = _value; + } + + function getProposedActivationBlock(uint256 _id) public view returns(uint256) { + return uintStorage[keccak256(abi.encodePacked("votingState", _id, "proposedActivationBlock"))]; + } + + function _setProposedActivationBlock(uint256 _id, uint256 _value) internal { + uintStorage[keccak256(abi.encodePacked("votingState", _id, "proposedActivationBlock"))] = _value; + } + /** * @dev This function is used to create a ballot * @param _startAfterNumberOfCycles number of cycles after which the ballot should open for voting @@ -206,6 +230,15 @@ abstract contract VotingUtils is EternalStorage, VotingBase { } function _finalizeBallot(uint256 _id) internal returns(bool) { + if (getBallotType(_id) == uint256(BallotTypes.NodeVersion)) { + // try/catch so a ballot which can no longer be applied (e.g. stale activation block) + // does not revert onCycleEnd, which would break the cycle/reward flow + try IConsensus(ProxyStorage(getProxyStorage()).getConsensus()).setRequiredNodeVersion(getProposedNodeVersion(_id), getProposedActivationBlock(_id)) { + return true; + } catch { + return false; + } + } return ProxyStorage(getProxyStorage()).setContractAddress(getContractType(_id), getProposedValue(_id)); } diff --git a/contracts/abstracts/VotingBase.sol b/contracts/abstracts/VotingBase.sol index d3d0ee1..eb2f5c5 100644 --- a/contracts/abstracts/VotingBase.sol +++ b/contracts/abstracts/VotingBase.sol @@ -30,6 +30,18 @@ abstract contract VotingBase { Reject } + /** + * @dev Possible ballot types + * @param ContractAddress - ballot to change a network contract implementation (see ProxyStorage.ContractTypes) + * @param NodeVersion - ballot to schedule a network upgrade (required node version + activation block) + * Note: ballots created before ballot types were introduced have type Invalid (0) and are treated as ContractAddress + */ + enum BallotTypes { + Invalid, + ContractAddress, + NodeVersion + } + /** * @dev This event will be emitted every time a new ballot is created * @param id ballot id diff --git a/contracts/interfaces/IConsensus.sol b/contracts/interfaces/IConsensus.sol index 68d9098..643f4c0 100644 --- a/contracts/interfaces/IConsensus.sol +++ b/contracts/interfaces/IConsensus.sol @@ -12,4 +12,5 @@ interface IConsensus { function isFinalized() external view returns(bool); function stakeAmount(address _address) external view returns(uint256); function totalStakeAmount() external view returns(uint256); + function setRequiredNodeVersion(uint256 _version, uint256 _activationBlock) external; } diff --git a/contracts/test/ConsensusMock.sol b/contracts/test/ConsensusMock.sol index 5bab90c..4350d50 100644 --- a/contracts/test/ConsensusMock.sol +++ b/contracts/test/ConsensusMock.sol @@ -91,4 +91,8 @@ contract ConsensusMock is Consensus { function setBlockCounterMock(address _val, uint256 counter) public { uintStorage[keccak256(abi.encodePacked("blockCounter", _val))] = counter; } + + function setRequiredNodeVersionMock(uint256 _version, uint256 _activationBlock) public { + _setRequiredNodeVersion(_version, _activationBlock); + } } diff --git a/nethermind/quickstart.sh b/nethermind/quickstart.sh index bb258a4..597b975 100755 --- a/nethermind/quickstart.sh +++ b/nethermind/quickstart.sh @@ -621,6 +621,7 @@ EOF --net container:$CONTAINER_NAME \ --volume $KEYSTORE_DIR:/config/keys/FuseNetwork \ --volume $KEYSTORE_DIR/pass.pwd:/config/pass.pwd \ + --env NODE_VERSION=$FUSE_CLIENT_DOCKER_IMAGE_VERSION \ --restart always \ $VALIDATOR_DOCKER_IMAGE diff --git a/test/consensus.test.js b/test/consensus.test.js index 5fe9e16..a256897 100644 --- a/test/consensus.test.js +++ b/test/consensus.test.js @@ -3366,6 +3366,209 @@ contract("Consensus", async (accounts) => { }); }); + describe("NodeVersion", async () => { + const SPEC_VERSION = toBN(6000003); // 6.0.3 + let candidates; + + beforeEach(async () => { + await consensus.initialize(initialValidator); + await consensus.setProxyStorage(proxyStorage.address); + candidates = [firstCandidate, secondCandidate, thirdCandidate]; + }); + + const stakeAndActivate = async () => { + for (let candidate of candidates) { + await consensus.sendTransaction({ + from: candidate, + value: MIN_STAKE, + }).should.be.fulfilled; + } + await mockEoC(); + let currentValidators = await consensus.getValidators(); + currentValidators.length.should.be.equal(3); + }; + + const setFullProductivity = async () => { + for (let candidate of candidates) { + await consensus.setBlockCounterMock(candidate, CYCLE_DURATION_BLOCKS); + } + }; + + const advanceToCycleEnd = async () => { + let currentBlockNumber = await web3.eth.getBlockNumber(); + let currentCycleEndBlock = await consensus.getCurrentCycleEndBlock(); + let blocksToAdvance = + currentCycleEndBlock.toNumber() - currentBlockNumber; + if (blocksToAdvance > 0) { + await advanceBlocks(blocksToAdvance); + } + true.should.be.equal(await consensus.hasCycleEnded()); + }; + + it("validators can report their node version", async () => { + ZERO.should.be.bignumber.equal( + await consensus.getNodeVersion(firstCandidate) + ); + let { logs } = await consensus.reportNodeVersion(SPEC_VERSION, { + from: firstCandidate, + }).should.be.fulfilled; + logs[0].event.should.be.equal("NodeVersionReported"); + logs[0].args["validator"].should.be.equal(firstCandidate); + logs[0].args["version"].should.be.bignumber.equal(SPEC_VERSION); + SPEC_VERSION.should.be.bignumber.equal( + await consensus.getNodeVersion(firstCandidate) + ); + await consensus + .reportNodeVersion(ZERO, { from: firstCandidate }) + .should.be.rejectedWith(ERROR_MSG); + }); + + it("scheduling a required node version is only allowed via the voting contract", async () => { + let currentBlockNumber = await web3.eth.getBlockNumber(); + let activationBlock = toBN(currentBlockNumber + 1000); + // direct calls are rejected (even from the owner) - scheduling goes through a voting ballot + await consensus + .setRequiredNodeVersion(SPEC_VERSION, activationBlock, { + from: owner, + }) + .should.be.rejectedWith(ERROR_MSG); + await consensus + .setRequiredNodeVersion(SPEC_VERSION, activationBlock, { + from: nonOwner, + }) + .should.be.rejectedWith(ERROR_MSG); + // activation block must be in the future + await consensus + .setRequiredNodeVersionMock(SPEC_VERSION, toBN(currentBlockNumber)) + .should.be.rejectedWith(ERROR_MSG); + await consensus.setRequiredNodeVersionMock(SPEC_VERSION, activationBlock).should.be.fulfilled; + SPEC_VERSION.should.be.bignumber.equal( + await consensus.getRequiredNodeVersion() + ); + activationBlock.should.be.bignumber.equal( + await consensus.getNodeVersionActivationBlock() + ); + false.should.be.equal(await consensus.isNodeVersionCheckExecuted()); + // clearing a scheduled upgrade + await consensus.setRequiredNodeVersionMock(ZERO, ZERO).should.be + .fulfilled; + ZERO.should.be.bignumber.equal( + await consensus.getRequiredNodeVersion() + ); + ZERO.should.be.bignumber.equal( + await consensus.getNodeVersionActivationBlock() + ); + }); + + it("jails outdated validators on the cycle boundary before activation when more than 66% upgraded", async () => { + await stakeAndActivate(); + // 2 out of 3 validators (66.7% > 66%) report the required version + await consensus.reportNodeVersion(SPEC_VERSION, { from: firstCandidate }); + await consensus.reportNodeVersion(SPEC_VERSION, { + from: secondCandidate, + }); + + // new spec activates in the middle of the upcoming cycle + let currentCycleEndBlock = await consensus.getCurrentCycleEndBlock(); + let activationBlock = currentCycleEndBlock.addn(50); + await consensus.setRequiredNodeVersionMock(SPEC_VERSION, activationBlock).should.be.fulfilled; + + await setFullProductivity(); + await advanceToCycleEnd(); + await blockReward.cycleMock({ from: owner }).should.be.fulfilled; + + true.should.be.equal(await consensus.isNodeVersionCheckExecuted()); + true.should.be.equal(await consensus.isJailed(thirdCandidate)); + false.should.be.equal(await consensus.isPendingValidator(thirdCandidate)); + false.should.be.equal(await consensus.isJailed(firstCandidate)); + false.should.be.equal(await consensus.isJailed(secondCandidate)); + true.should.be.equal(await consensus.isPendingValidator(firstCandidate)); + true.should.be.equal(await consensus.isPendingValidator(secondCandidate)); + }); + + it("does not jail anybody when the 66% upgrade quorum is not met", async () => { + await stakeAndActivate(); + // only 1 out of 3 validators (33%) reports the required version + await consensus.reportNodeVersion(SPEC_VERSION, { from: firstCandidate }); + + let currentCycleEndBlock = await consensus.getCurrentCycleEndBlock(); + let activationBlock = currentCycleEndBlock.addn(50); + await consensus.setRequiredNodeVersionMock(SPEC_VERSION, activationBlock).should.be.fulfilled; + + await setFullProductivity(); + await advanceToCycleEnd(); + await blockReward.cycleMock({ from: owner }).should.be.fulfilled; + + true.should.be.equal(await consensus.isNodeVersionCheckExecuted()); + false.should.be.equal(await consensus.isJailed(secondCandidate)); + false.should.be.equal(await consensus.isJailed(thirdCandidate)); + true.should.be.equal(await consensus.isPendingValidator(secondCandidate)); + true.should.be.equal(await consensus.isPendingValidator(thirdCandidate)); + }); + + it("does not run the check before the cycle preceding activation", async () => { + await stakeAndActivate(); + await consensus.reportNodeVersion(SPEC_VERSION, { from: firstCandidate }); + await consensus.reportNodeVersion(SPEC_VERSION, { + from: secondCandidate, + }); + + // activation is several cycles away + let currentCycleEndBlock = await consensus.getCurrentCycleEndBlock(); + let activationBlock = currentCycleEndBlock.addn( + 3 * CYCLE_DURATION_BLOCKS + ); + await consensus.setRequiredNodeVersionMock(SPEC_VERSION, activationBlock).should.be.fulfilled; + + await setFullProductivity(); + await advanceToCycleEnd(); + await blockReward.cycleMock({ from: owner }).should.be.fulfilled; + + // upcoming cycle still ends before activation - no check yet + false.should.be.equal(await consensus.isNodeVersionCheckExecuted()); + false.should.be.equal(await consensus.isJailed(thirdCandidate)); + + // keep cycling until the boundary before activation is reached + for (let i = 0; i < 3; i++) { + await setFullProductivity(); + await advanceToCycleEnd(); + await blockReward.cycleMock({ from: owner }).should.be.fulfilled; + } + + true.should.be.equal(await consensus.isNodeVersionCheckExecuted()); + true.should.be.equal(await consensus.isJailed(thirdCandidate)); + false.should.be.equal(await consensus.isJailed(firstCandidate)); + false.should.be.equal(await consensus.isJailed(secondCandidate)); + }); + + it("outdated validator can only be released from jail after reporting the required version", async () => { + await stakeAndActivate(); + await consensus.reportNodeVersion(SPEC_VERSION, { from: firstCandidate }); + await consensus.reportNodeVersion(SPEC_VERSION, { + from: secondCandidate, + }); + + let currentCycleEndBlock = await consensus.getCurrentCycleEndBlock(); + let activationBlock = currentCycleEndBlock.addn(50); + await consensus.setRequiredNodeVersionMock(SPEC_VERSION, activationBlock).should.be.fulfilled; + + await setFullProductivity(); + await advanceToCycleEnd(); + await blockReward.cycleMock({ from: owner }).should.be.fulfilled; + true.should.be.equal(await consensus.isJailed(thirdCandidate)); + + // release block has passed, but the validator has not upgraded yet + await consensus + .unJail({ from: thirdCandidate }) + .should.be.rejectedWith(ERROR_MSG); + + await consensus.reportNodeVersion(SPEC_VERSION, { from: thirdCandidate }); + await consensus.unJail({ from: thirdCandidate }).should.be.fulfilled; + false.should.be.equal(await consensus.isJailed(thirdCandidate)); + true.should.be.equal(await consensus.isPendingValidator(thirdCandidate)); + }); + }); + describe("upgradeTo", async () => { let consensusOldImplementation, consensusNew; let proxyStorageStub = accounts[3]; diff --git a/test/voting.test.js b/test/voting.test.js index 70d1c36..178a95b 100644 --- a/test/voting.test.js +++ b/test/voting.test.js @@ -301,6 +301,176 @@ contract("Voting", async (accounts) => { }); }); + describe("newNodeVersionBallot", async () => { + const SPEC_VERSION = toBN(6000003); // 6.0.3 + const BALLOT_TYPES = { INVALID: 0, CONTRACT_ADDRESS: 1, NODE_VERSION: 2 }; + + beforeEach(async () => { + await voting.initialize().should.be.fulfilled; + voteStartAfterNumberOfCycles = 1; + voteCyclesDuration = 2; + }); + + const newNodeVersionBallot = async (version, activationBlock, from) => { + let id = await voting.getNextBallotId(); + await voting.newNodeVersionBallot( + voteStartAfterNumberOfCycles, + voteCyclesDuration, + version, + activationBlock, + "network upgrade", + { from } + ).should.be.fulfilled; + return id; + }; + + const voteAndFinalize = async (id, choices) => { + let currentValidators = await consensus.getValidators(); + let currentBlock = toBN(await web3.eth.getBlockNumber()); + let voteStartBlock = await voting.getStartBlock(id); + await advanceBlocks(voteStartBlock.sub(currentBlock).toNumber() + 1); + for (let [validator, choice] of choices) { + await voting.vote(id, choice, { from: validator }).should.be.fulfilled; + } + currentBlock = toBN(await web3.eth.getBlockNumber()); + let voteEndBlock = await voting.getEndBlock(id); + await advanceBlocks(voteEndBlock.sub(currentBlock).add(toBN(1)).toNumber()); + await voting.setConsensusMock(owner); + await voting.onCycleEnd(currentValidators).should.be.fulfilled; + }; + + it("should be successful", async () => { + let currentBlock = toBN(await web3.eth.getBlockNumber()); + let activationBlock = currentBlock.addn(10000); + let id = await newNodeVersionBallot( + SPEC_VERSION, + activationBlock, + validators[0] + ); + toBN(BALLOT_TYPES.NODE_VERSION).should.be.bignumber.equal( + await voting.getBallotType(id) + ); + SPEC_VERSION.should.be.bignumber.equal( + await voting.getProposedNodeVersion(id) + ); + activationBlock.should.be.bignumber.equal( + await voting.getProposedActivationBlock(id) + ); + }); + + it("should fail if not called by valid voting key", async () => { + let currentBlock = toBN(await web3.eth.getBlockNumber()); + await voting + .newNodeVersionBallot( + voteStartAfterNumberOfCycles, + voteCyclesDuration, + SPEC_VERSION, + currentBlock.addn(10000), + "network upgrade", + { from: owner } + ) + .should.be.rejectedWith(ERROR_MSG); + }); + + it("should fail if activation block is not in the future", async () => { + let currentBlock = toBN(await web3.eth.getBlockNumber()); + await voting + .newNodeVersionBallot( + voteStartAfterNumberOfCycles, + voteCyclesDuration, + SPEC_VERSION, + currentBlock, + "network upgrade", + { from: validators[0] } + ) + .should.be.rejectedWith(ERROR_MSG); + }); + + it("accepted ballot should set the required node version on consensus", async () => { + let currentBlock = toBN(await web3.eth.getBlockNumber()); + let activationBlock = currentBlock.addn(10000); + let id = await newNodeVersionBallot( + SPEC_VERSION, + activationBlock, + validators[0] + ); + await voteAndFinalize(id, [ + [validators[0], ACTION_CHOICES.ACCEPT], + [validators[1], ACTION_CHOICES.ACCEPT], + [validators[2], ACTION_CHOICES.REJECT], + ]); + true.should.be.equal(await voting.getIsFinalized(id)); + toBN(QUORUM_STATES.ACCEPTED).should.be.bignumber.equal( + await voting.getQuorumState(id) + ); + SPEC_VERSION.should.be.bignumber.equal( + await consensus.getRequiredNodeVersion() + ); + activationBlock.should.be.bignumber.equal( + await consensus.getNodeVersionActivationBlock() + ); + }); + + it("rejected ballot should not set the required node version on consensus", async () => { + let currentBlock = toBN(await web3.eth.getBlockNumber()); + let id = await newNodeVersionBallot( + SPEC_VERSION, + currentBlock.addn(10000), + validators[0] + ); + await voteAndFinalize(id, [ + [validators[0], ACTION_CHOICES.ACCEPT], + [validators[1], ACTION_CHOICES.REJECT], + [validators[2], ACTION_CHOICES.REJECT], + ]); + true.should.be.equal(await voting.getIsFinalized(id)); + toBN(QUORUM_STATES.REJECTED).should.be.bignumber.equal( + await voting.getQuorumState(id) + ); + toBN(0).should.be.bignumber.equal( + await consensus.getRequiredNodeVersion() + ); + }); + + it("ballot below turnout should not set the required node version on consensus", async () => { + let currentBlock = toBN(await web3.eth.getBlockNumber()); + let id = await newNodeVersionBallot( + SPEC_VERSION, + currentBlock.addn(10000), + validators[0] + ); + // only 1 of 8 validators votes (12.5% < 20% turnout) + await voteAndFinalize(id, [[validators[0], ACTION_CHOICES.ACCEPT]]); + true.should.be.equal(await voting.getIsFinalized(id)); + toBN(QUORUM_STATES.REJECTED).should.be.bignumber.equal( + await voting.getQuorumState(id) + ); + true.should.be.equal(await voting.getBelowTurnOut(id)); + toBN(0).should.be.bignumber.equal( + await consensus.getRequiredNodeVersion() + ); + }); + + it("accepted ballot with stale activation block should not revert onCycleEnd", async () => { + let currentBlock = toBN(await web3.eth.getBlockNumber()); + // activation block passes before the ballot can be finalized (start + duration is ~3 cycles away) + let id = await newNodeVersionBallot( + SPEC_VERSION, + currentBlock.addn(10), + validators[0] + ); + await voteAndFinalize(id, [ + [validators[0], ACTION_CHOICES.ACCEPT], + [validators[1], ACTION_CHOICES.ACCEPT], + ]); + // the consensus call failed gracefully - ballot is left unfinalized and nothing was scheduled + false.should.be.equal(await voting.getIsFinalized(id)); + toBN(0).should.be.bignumber.equal( + await consensus.getRequiredNodeVersion() + ); + }); + }); + describe("vote", async () => { let id, proposedValue, contractType; beforeEach(async () => {