Fixed how the blockchain iterator was initailized via the --latest CLI flag.

This commit is contained in:
Peter van Nostrand 2018-04-25 16:24:23 -04:00
parent 555f3b8c38
commit 13140faa0f
3 changed files with 63 additions and 57 deletions

View File

@ -7,7 +7,6 @@ use std::time::Duration;
use dotenv::dotenv;
use ethabi::{Contract, Event, Function};
use ethereum_types::Address;
use web3::types::BlockNumber;
use cli::Cli;
use utils::hex_string_to_u64;
@ -73,40 +72,29 @@ impl ContractType {
}
#[derive(Clone, Copy, Debug)]
pub struct StartBlock {
pub block: BlockNumber,
pub tail: u64
}
impl StartBlock {
fn latest() -> Self {
StartBlock { block: BlockNumber::Latest, tail: 0 }
}
fn earliest() -> Self {
StartBlock { block: BlockNumber::Earliest, tail: 0 }
}
fn tail(tail: u64) -> Self {
StartBlock { block: BlockNumber::Latest, tail }
}
pub enum StartBlock {
Earliest,
Latest,
Number(u64),
Tail(u64)
}
impl<'a> From<&'a str> for StartBlock {
fn from(s: &'a str) -> Self {
let mut start_block = StartBlock::latest();
if s.starts_with("-") {
start_block.tail = s[1..].parse().expect("Invalid start-block");
} else if s == "earliest" {
start_block.block = BlockNumber::Number(0);
if s == "earliest" {
StartBlock::Earliest
} else if s == "latest" {
StartBlock::Latest
} else if s.starts_with('-') {
let tail: u64 = s[1..].parse().expect("Invalid tail start-block");
StartBlock::Tail(tail)
} else if s.starts_with("0x") {
start_block.block = hex_string_to_u64(s).expect("Invalid start-block").into();
} else if s != "latest" {
start_block.block = s.parse::<u64>().expect("Invalid start-block").into();
let block_number = hex_string_to_u64(s).expect("Invalid hex start-block");
StartBlock::Number(block_number)
} else {
let block_number: u64 = s.parse().expect("Invaild decimal start-block");
StartBlock::Number(block_number)
}
start_block
}
}
@ -231,11 +219,11 @@ impl Config {
let start_block = if let Some(s) = cli.value_of("start_block") {
s.into()
} else if cli.is_present("earliest") {
StartBlock::earliest()
StartBlock::Earliest
} else if cli.is_present("latest") {
StartBlock::latest()
StartBlock::Latest
} else if let Some(s) = cli.value_of("tail") {
StartBlock::tail(s.parse().expect("Invalid tail value"))
StartBlock::Tail(s.parse().expect("Invalid tail value"))
} else {
env::var("START_BLOCK").unwrap().as_str().into()
};

View File

@ -25,18 +25,17 @@ mod utils;
use config::Config;
use notify::Notifier;
use rpc::{BlockWindows, RpcClient};
use rpc::{BlockchainIter, RpcClient};
fn main() {
let config = Config::load();
let client = RpcClient::new(&config.endpoint);
let block_windows = BlockWindows::new(&client, config.avg_block_time);
let mut notifier = Notifier::new(&config).unwrap();
for (start, stop) in block_windows {
for (start_block, stop_block) in BlockchainIter::new(&client, &config) {
for contract in &config.contracts {
let ballot_created_logs = client
.get_ballot_created_logs(contract, start, stop)
.get_ballot_created_logs(contract, start_block, stop_block)
.unwrap();
for log in &ballot_created_logs {

View File

@ -13,7 +13,7 @@ use reqwest;
use serde_json as json;
use web3::types::{BlockNumber, Bytes, CallRequest, Filter, FilterBuilder, Log};
use config::{ContractType, PoaContract};
use config::{Config, ContractType, PoaContract, StartBlock};
use utils::{hex_string_to_u64, u256_to_datetime};
const JSONRPC_VERSION: rpc::Version = rpc::Version::V2;
@ -321,41 +321,60 @@ impl From<Vec<Token>> for ProxyVotingData {
}
}
pub struct BlockWindows<'a> {
pub struct BlockchainIter<'a> {
client: &'a RpcClient,
block_time: Duration,
start_block: u64,
stop_block: u64,
on_first_iteration: bool,
start: u64,
stop: u64
avg_block_time: Duration
}
impl<'a> BlockWindows<'a> {
pub fn new(client: &'a RpcClient, block_time: Duration) -> Self {
let start = 0;
let stop = 0;
let on_first_iteration = true;
BlockWindows { client, block_time, start, stop, on_first_iteration }
impl<'a> BlockchainIter<'a> {
pub fn new(client: &'a RpcClient, config: &Config) -> Self {
let latest = client.latest_block_number().unwrap();
let start_block = match config.start_block {
StartBlock::Earliest => 0,
StartBlock::Latest => latest,
StartBlock::Number(block_number) => block_number,
StartBlock::Tail(tail) => latest - tail
};
if start_block > latest {
panic!(
"Provided start-block ({}) exceeds latest mined block number ({})",
start_block,
latest
);
}
BlockchainIter {
client,
start_block,
stop_block: latest,
on_first_iteration: true,
avg_block_time: config.avg_block_time
}
}
}
impl<'a> Iterator for BlockWindows<'a> {
impl<'a> Iterator for BlockchainIter<'a> {
type Item = (BlockNumber, BlockNumber);
fn next(&mut self) -> Option<Self::Item> {
if self.on_first_iteration {
self.stop = self.client.latest_block_number().unwrap();
self.on_first_iteration = false;
} else {
self.start = self.stop + 1;
while self.start >= self.stop {
thread::sleep(self.block_time);
self.stop = self.client.latest_block_number().unwrap();
self.start_block = self.stop_block + 1;
while self.start_block >= self.stop_block {
thread::sleep(self.avg_block_time);
self.stop_block = self.client.latest_block_number().unwrap();
}
}
Some((
BlockNumber::Number(self.start),
BlockNumber::Number(self.stop)
BlockNumber::Number(self.start_block),
BlockNumber::Number(self.stop_block)
))
}
}