Also show validators with no votes, add check.
We now compare the collected keys to the full current validator list before printing the results.
This commit is contained in:
parent
744c5bda28
commit
fdb0741ff6
|
@ -1,6 +1,13 @@
|
|||
# Changelog
|
||||
All notable changes to the project will be documented in this file.
|
||||
|
||||
|
||||
## Unreleased
|
||||
|
||||
- Migrate to Rust 2018. At least version 1.31.0 required.
|
||||
- Show new validators in the list, even if there was no ballot since they were added.
|
||||
|
||||
|
||||
## [0.4.0] - 2018-10-15
|
||||
|
||||
- Support new contracts (hard fork 2).
|
||||
|
|
|
@ -0,0 +1,462 @@
|
|||
[
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "pendingList",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"signature": "0x03aca792"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "getCurrentValidatorsLength",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"signature": "0x0eaba26a"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_newAddress",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "setProxyStorage",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function",
|
||||
"signature": "0x10855269"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_validator",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_shouldFireEvent",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"name": "addValidator",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function",
|
||||
"signature": "0x21a3fb85"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "isMasterOfCeremonyRemovedPending",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"signature": "0x273cb593"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "isMasterOfCeremonyRemoved",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"signature": "0x379fed9a"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "validatorsState",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "isValidator",
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"name": "isValidatorFinalized",
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"name": "index",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"signature": "0x4110a489"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "getPendingList",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"signature": "0x45199e0a"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [],
|
||||
"name": "finalizeChange",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function",
|
||||
"signature": "0x75286211"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_newKey",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_oldKey",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "swapValidatorKey",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function",
|
||||
"signature": "0x879736b2"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_someone",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "isValidatorFinalized",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"signature": "0x8f2eabe1"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "currentValidators",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"signature": "0x900eb5a8"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "getKeysManager",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"signature": "0x9a573786"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "wasProxyStorageSet",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"signature": "0xa5f8b874"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "getCurrentValidatorsLengthWithoutMoC",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"signature": "0xa8756337"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "proxyStorage",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"signature": "0xae4b1b5b"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "finalized",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"signature": "0xb3f05b97"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "getValidators",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"signature": "0xb7ab4db5"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "systemAddress",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"signature": "0xd3e848f1"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "masterOfCeremonyPending",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"signature": "0xec7de1e9"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_validator",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_shouldFireEvent",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"name": "removeValidator",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function",
|
||||
"signature": "0xf89a77b1"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "masterOfCeremony",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"signature": "0xfa81b200"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_someone",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "isValidator",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"signature": "0xfacd743b"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_masterOfCeremony",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "validators",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor",
|
||||
"signature": "constructor"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "parentHash",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "newSet",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"name": "InitiateChange",
|
||||
"type": "event",
|
||||
"signature": "0x55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "newSet",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"name": "ChangeFinalized",
|
||||
"type": "event",
|
||||
"signature": "0x8564cd629b15f47dc310d45bcbfc9bcf5420b0d51bf0659a16c67f91d2763253"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "proxyStorage",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "MoCInitializedProxyStorage",
|
||||
"type": "event",
|
||||
"signature": "0x600bcf04a13e752d1e3670a5a9f1c21177ca2a93c6f5391d4f1298d098097c22"
|
||||
}
|
||||
]
|
|
@ -11,6 +11,7 @@ pub mod v2 {
|
|||
use_contract!(key_mgr, "abi/v2/KeysManager.abi.json");
|
||||
use_contract!(val_meta, "abi/v2/ValidatorMetadata.abi.json");
|
||||
use_contract!(voting, "abi/v2/VotingToChangeKeys.abi.json");
|
||||
use_contract!(consensus, "abi/v2/PoaNetworkConsensus.abi.json");
|
||||
}
|
||||
|
||||
// The `use_contract!` macro triggers several Clippy warnings.
|
||||
|
@ -25,6 +26,7 @@ pub struct ContractV1V2Addresses {
|
|||
pub metadata_address: Address,
|
||||
pub keys_manager_address: Address,
|
||||
pub voting_to_change_keys_address: Address,
|
||||
pub poa_address: Address,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
use crate::contracts::v1::voting::events::{ballot_created as ballot_created_v1, vote as vote_v1};
|
||||
use crate::contracts::v2::consensus::functions::get_validators as get_validators_fn;
|
||||
use crate::contracts::v2::key_mgr::events::voting_key_changed;
|
||||
use crate::contracts::v2::key_mgr::functions::get_mining_key_by_voting;
|
||||
use crate::contracts::v2::key_mgr::functions::{
|
||||
get_mining_key_by_voting as get_mining_key_by_voting_fn,
|
||||
get_voting_by_mining as get_voting_by_mining_fn,
|
||||
};
|
||||
use crate::contracts::v2::val_meta::functions::validators as validators_fn;
|
||||
use crate::contracts::v2::voting::events::{ballot_created, vote};
|
||||
use crate::contracts::ContractAddresses;
|
||||
|
@ -132,11 +136,22 @@ impl Counter {
|
|||
return Err(ErrorKind::NoEventsFound.into());
|
||||
}
|
||||
|
||||
// Add all voters we haven't encountered so far.
|
||||
let mining_keys: Vec<Address> = self.call_poa(get_validators_fn::call())?;
|
||||
for mining_key in mining_keys {
|
||||
let voter = self.call_key_mgr(get_voting_by_mining_fn::call(mining_key))?;
|
||||
if voter.is_zero() {
|
||||
vprintln!("Voting key for {} is zero. Skipping.", mining_key);
|
||||
} else if voters.insert(voter) {
|
||||
eprintln!("Unexpected voter {} (mining key {})", voter, mining_key);
|
||||
}
|
||||
}
|
||||
|
||||
vprintln!(""); // Add a new line between event log and table.
|
||||
|
||||
// Finally, gather the metadata for all voters.
|
||||
for voter in voters {
|
||||
let mining_key = match self.call_key_mgr(get_mining_key_by_voting::call(voter)) {
|
||||
let mining_key = match self.call_key_mgr(get_mining_key_by_voting_fn::call(voter)) {
|
||||
Err(err) => {
|
||||
eprintln!("Failed to find mining key for voter {}: {:?}", voter, err);
|
||||
continue;
|
||||
|
@ -196,6 +211,14 @@ impl Counter {
|
|||
)
|
||||
}
|
||||
|
||||
/// Calls a function of the `PoaNetworkConsensus` contract and returns the decoded result.
|
||||
fn call_poa<D>(&self, fn_call: (Bytes, D)) -> Result<D::Output, web3::contract::Error>
|
||||
where
|
||||
D: FunctionOutputDecoder,
|
||||
{
|
||||
util::raw_call(self.addrs.v2.poa_address, &self.web3.eth(), fn_call)
|
||||
}
|
||||
|
||||
fn voters_for_ballot(&self, id: Uint) -> Result<Vec<Address>, Error> {
|
||||
let vote_filter = vote::filter(id, None).or(vote_v1::filter(id, None));
|
||||
let is_voting = |log: &web3::types::Log| self.addrs.is_voting(&log.address);
|
||||
|
|
18
src/stats.rs
18
src/stats.rs
|
@ -43,20 +43,10 @@ impl Stats {
|
|||
}
|
||||
|
||||
/// Inserts metadata about a voter: the mining key and the `Validator` information.
|
||||
pub fn set_metadata(
|
||||
&mut self,
|
||||
voter: &Address,
|
||||
mining_key: Address,
|
||||
validator: Validator,
|
||||
) -> bool {
|
||||
match self.voter_stats.get_mut(voter) {
|
||||
None => false,
|
||||
Some(vs) => {
|
||||
vs.validator = Some(validator);
|
||||
vs.mining_key = Some(mining_key);
|
||||
true
|
||||
}
|
||||
}
|
||||
pub fn set_metadata(&mut self, voter: &Address, mining_key: Address, validator: Validator) {
|
||||
let vs = self.voter_stats.entry(*voter).or_default();
|
||||
vs.validator = Some(validator);
|
||||
vs.mining_key = Some(mining_key);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue