Update dependencies.

This commit is contained in:
Andreas Fackler 2018-09-17 12:01:11 +02:00 committed by Andreas Fackler
parent 6a20b3d91f
commit 0f11a72e2d
7 changed files with 719 additions and 821 deletions

1042
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -7,12 +7,13 @@ description = "Read POA voting records and rank voters by how many ballots they
[dependencies]
clap = "2.31.2"
colored = "1.6.0"
error-chain = { version = "0.11", default-features = false }
ethabi = "5.1.1"
ethabi-contract = "5.1.0"
ethabi-derive = "5.1.2"
error-chain = { version = "0.12", default-features = false }
ethabi = "6.0.1"
ethabi-contract = "6.0.0"
ethabi-derive = "6.0.2"
parse_duration = "1.0.1"
serde = "1.0.36"
serde_derive = "1.0.36"
serde_json = "1.0.13"
web3 = { version = "0.3.0", default-features = false, features = ["http", "tls"] }
# TODO: Remove ws once https://github.com/tomusdrw/rust-web3/issues/157 is fixed.
web3 = { version = "0.4.0", default-features = false, features = ["http", "tls", "ws"] }

View File

@ -1,386 +0,0 @@
[
{
"constant": true,
"inputs": [
{
"name": "",
"type": "uint256"
}
],
"name": "pendingList",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "getCurrentValidatorsLength",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_newAddress",
"type": "address"
}
],
"name": "setProxyStorage",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_validator",
"type": "address"
},
{
"name": "_shouldFireEvent",
"type": "bool"
}
],
"name": "addValidator",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "currentValidatorsLength",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "address"
}
],
"name": "validatorsState",
"outputs": [
{
"name": "isValidator",
"type": "bool"
},
{
"name": "index",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "getPendingList",
"outputs": [
{
"name": "",
"type": "address[]"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "getVotingToChangeKeys",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [],
"name": "finalizeChange",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_newKey",
"type": "address"
},
{
"name": "_oldKey",
"type": "address"
}
],
"name": "swapValidatorKey",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "uint256"
}
],
"name": "currentValidators",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "getKeysManager",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "isMasterOfCeremonyInitialized",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "proxyStorage",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "finalized",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "getValidators",
"outputs": [
{
"name": "",
"type": "address[]"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "systemAddress",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_validator",
"type": "address"
},
{
"name": "_shouldFireEvent",
"type": "bool"
}
],
"name": "removeValidator",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "masterOfCeremony",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_someone",
"type": "address"
}
],
"name": "isValidator",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"name": "_masterOfCeremony",
"type": "address"
},
{
"name": "validators",
"type": "address[]"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "parentHash",
"type": "bytes32"
},
{
"indexed": false,
"name": "newSet",
"type": "address[]"
}
],
"name": "InitiateChange",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"name": "newSet",
"type": "address[]"
}
],
"name": "ChangeFinalized",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"name": "nameOfContract",
"type": "string"
},
{
"indexed": false,
"name": "newAddress",
"type": "address"
}
],
"name": "ChangeReference",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"name": "proxyStorage",
"type": "address"
}
],
"name": "MoCInitializedProxyStorage",
"type": "event"
}
]

View File

@ -1,7 +1,9 @@
use colored::{Color, Colorize};
use contracts::{key_mgr, val_meta, voting};
use contracts::key_mgr::events::voting_key_changed;
use contracts::val_meta::functions::{get_mining_by_voting_key, validators as validators_fn};
use contracts::voting::events::{ballot_created, vote};
use error::{Error, ErrorKind};
use ethabi::Address;
use ethabi::{Address, Bytes, FunctionOutputDecoder};
use stats::Stats;
use std::collections::BTreeSet;
use std::default::Default;
@ -84,18 +86,10 @@ impl Counter {
// Calls `println!` if `verbose` is `true`.
macro_rules! vprintln { ($($arg:tt)*) => { if self.verbose { println!($($arg)*); } } }
let voting_contract = voting::VotingToChangeKeys::default();
let val_meta_contract = val_meta::ValidatorMetadata::default();
let key_mgr_contract = key_mgr::KeysManager::default();
let ballot_event = voting_contract.events().ballot_created();
let vote_event = voting_contract.events().vote();
let change_event = key_mgr_contract.events().voting_key_changed();
// Find all ballots and voter changes. We don't filter by contract address, so we can make
// a single pass. Contract addresses are checked inside the loop.
let ballot_or_change_filter =
(ballot_event.create_filter(None, None, None)).or(change_event.create_filter(None));
(ballot_created::filter(None, None, None)).or(voting_key_changed::filter(None));
let mut voters: BTreeSet<Address> = BTreeSet::new();
let mut stats = Stats::default();
@ -107,7 +101,7 @@ impl Counter {
for log in ballot_or_change_filter.logs(&self.web3)? {
event_found = true;
let block_num = log.block_number.expect(ERR_BLOCK_NUM).into();
if let Ok(change) = change_event.parse_log(log.clone().into_raw()) {
if let Ok(change) = voting_key_changed::parse_log(log.clone().into_raw()) {
if log.address != self.key_mgr_addr {
continue; // Event from another contract instance.
}
@ -122,7 +116,7 @@ impl Counter {
}
_ => vprintln!(" Unexpected key change action."),
}
} else if let Ok(ballot) = ballot_event.parse_log(log.clone().into_raw()) {
} else if let Ok(ballot) = ballot_created::parse_log(log.clone().into_raw()) {
if log.address != self.voting_addr {
continue; // Event from another contract instance.
}
@ -136,8 +130,8 @@ impl Counter {
let mut unexpected = BTreeSet::new();
let mut voted = BTreeSet::new();
let mut votes = Vec::new();
for vote_log in vote_event.create_filter(ballot.id, None).logs(&self.web3)? {
let vote = vote_event.parse_log(vote_log.into_raw())?;
for vote_log in vote::filter(ballot.id, None).logs(&self.web3)? {
let vote = vote::parse_log(vote_log.into_raw())?;
if voters.insert(vote.voter) {
unexpected.insert(vote.voter);
} else {
@ -170,11 +164,8 @@ impl Counter {
vprintln!(""); // Add a new line between event log and table.
// Finally, gather the metadata for all voters.
let raw_call = util::raw_call(self.val_meta_addr, self.web3.eth());
let get_mining_by_voting_key_fn = val_meta_contract.functions().get_mining_by_voting_key();
let validators_fn = val_meta_contract.functions().validators();
for voter in voters {
let mining_key = match get_mining_by_voting_key_fn.call(voter, &*raw_call) {
let mining_key = match self.call_val_meta(get_mining_by_voting_key::call(voter)) {
Err(err) => {
eprintln!("Failed to find mining key for voter {}: {:?}", voter, err);
continue;
@ -185,12 +176,20 @@ impl Counter {
eprintln!("Mining key for voter {} is zero. Skipping.", voter);
continue;
}
let validator = validators_fn.call(mining_key, &*raw_call)?.into();
let validator = self.call_val_meta(validators_fn::call(mining_key))?.into();
stats.set_metadata(&voter, mining_key, validator);
}
Ok(stats)
}
/// Calls a function of the `ValidatorMetadata` contract and returns the decoded result.
fn call_val_meta<D>(&self, fn_call: (Bytes, D)) -> Result<D::Output, web3::contract::Error>
where
D: FunctionOutputDecoder,
{
util::raw_call(self.val_meta_addr, &self.web3.eth(), fn_call)
}
/// Returns `true` if the block with the given number is older than `start_time`.
fn is_block_too_old(&self, block_num: u64) -> bool {
self.is_block_older_than(
@ -210,7 +209,8 @@ impl Counter {
/// Returns `true` if the block with the given number was created before the given time.
fn is_block_older_than(&self, number: web3::types::BlockNumber, time: &SystemTime) -> bool {
let id = web3::types::BlockId::Number(number);
let block = self.web3.eth().block(id).wait().expect(ERR_BLOCK);
let block_result = self.web3.eth().block(id).wait();
let block = block_result.expect(ERR_BLOCK).expect(ERR_BLOCK);
let seconds = time.duration_since(UNIX_EPOCH).expect(ERR_EPOCH).as_secs();
block.timestamp < seconds.into()
}

View File

@ -30,21 +30,11 @@ use std::time::SystemTime;
allow(too_many_arguments, redundant_closure, needless_update)
)]
mod contracts {
use_contract!(
voting,
"VotingToChangeKeys",
"abi/VotingToChangeKeys.abi.json"
);
use_contract!(
val_meta,
"ValidatorMetadata",
"abi/ValidatorMetadata.abi.json"
);
use_contract!(key_mgr, "KeysManager", "abi/KeysManager.abi.json");
use_contract!(voting, "abi/VotingToChangeKeys.abi.json");
use_contract!(val_meta, "abi/ValidatorMetadata.abi.json");
use_contract!(key_mgr, "abi/KeysManager.abi.json");
}
use contracts::*;
fn main() {
let matches = cli::get_matches();

View File

@ -1,9 +1,9 @@
use colored::{Color, Colorize};
use contracts::voting;
use ethabi::Address;
use std::collections::HashMap;
use std::fmt::{self, Display, Formatter};
use validator::Validator;
use voting;
/// The count of ballots and cast votes, as well as metadata for a particular voter.
#[derive(Clone, Default)]

View File

@ -1,10 +1,10 @@
use colored::{Color, Colorize};
use ethabi::{self, Address, Bytes};
use ethabi::{self, Address, Bytes, FunctionOutputDecoder};
use std::str::FromStr;
use std::{fmt, u8};
use web3;
use web3::futures::Future;
use web3::helpers::CallResult;
use web3::helpers::CallFuture;
// TODO: Evaluate whether any of these would make sense to include in `web3`.
@ -16,25 +16,24 @@ pub fn parse_address(mut s: &str) -> Option<Address> {
Address::from_str(s).ok()
}
/// Returns a wrapper of a contract address, to make function calls using the latest block.
pub fn raw_call<T: web3::Transport + 'static>(
/// Executes a function call on the latest block and returns the decoded output.
pub fn raw_call<T: web3::Transport, D: FunctionOutputDecoder>(
to: Address,
eth: web3::api::Eth<T>,
) -> Box<Fn(Bytes) -> Result<Bytes, String>> {
Box::new(move |bytes: Bytes| -> Result<Bytes, String> {
let req = web3::types::CallRequest {
from: None,
to,
gas: None,
gas_price: None,
value: None,
data: Some(bytes.into()),
};
eth.call(req, Some(web3::types::BlockNumber::Latest))
.wait()
.map(|bytes| bytes.0)
.map_err(|err| err.to_string())
})
eth: &web3::api::Eth<T>,
(bytes, decoder): (Bytes, D),
) -> Result<D::Output, web3::contract::Error> {
let req = web3::types::CallRequest {
from: None,
to,
gas: None,
gas_price: None,
value: None,
data: Some(bytes.into()),
};
let bytes = eth
.call(req, Some(web3::types::BlockNumber::Latest))
.wait()?;
Ok(decoder.decode(&bytes.0)?)
}
trait TopicExt<T> {
@ -117,7 +116,7 @@ impl TopicFilterExt for ethabi::TopicFilter {
// TODO: Once a version with https://github.com/tomusdrw/rust-web3/pull/122 is available:
// self.transport.logs(self.to_filter_builder().build())
let filter = web3::helpers::serialize(&self.to_filter_builder().build());
CallResult::new(web3.transport().execute("eth_getLogs", vec![filter])).wait()
CallFuture::new(web3.transport().execute("eth_getLogs", vec![filter])).wait()
}
}