138 lines
5.5 KiB
Rust
138 lines
5.5 KiB
Rust
|
use chrono::{DateTime, NaiveDateTime, Utc};
|
||
|
use ethabi;
|
||
|
use web3::types::{Address, H256, U256};
|
||
|
|
||
|
use error::{Error, Result};
|
||
|
|
||
|
/// Converts a `U256` timestamp to a UTC `DateTime`.
|
||
|
pub fn u256_to_datetime(uint: U256) -> DateTime<Utc> {
|
||
|
let timestamp = uint.low_u64() as i64;
|
||
|
let naive = NaiveDateTime::from_timestamp(timestamp, 0);
|
||
|
DateTime::from_utc(naive, Utc)
|
||
|
}
|
||
|
|
||
|
/// Identifies what type of key is being voted on by the `votingToChangeKeys.sol` contract. This
|
||
|
/// enum is used in the V1 and V2 Keys contracts.
|
||
|
///
|
||
|
/// V1 Keys Contract (`KeyType` is used within the contract's `votingState`):
|
||
|
/// https://github.com/poanetwork/poa-network-consensus-contracts/blob/aa45e19ca50f7cae308c1281d950245b0c65182a/contracts/VotingToChangeKeys.sol#L11
|
||
|
///
|
||
|
/// V2 `KeyTypes` enum (used by the V2 Keys Contract's `ballotInfo`):
|
||
|
/// https://github.com/poanetwork/poa-network-consensus-contracts/blob/ec307069302fdf6647e8b1bdc13093960913b266/contracts/abstracts/EnumKeyTypes.sol#L5
|
||
|
#[derive(Clone, Debug)]
|
||
|
pub enum KeyType {
|
||
|
InvalidKey,
|
||
|
MiningKey,
|
||
|
VotingKey,
|
||
|
PayoutKey,
|
||
|
}
|
||
|
|
||
|
impl From<U256> for KeyType {
|
||
|
fn from(key_type: U256) -> Self {
|
||
|
match key_type.low_u64() {
|
||
|
0 => KeyType::InvalidKey,
|
||
|
1 => KeyType::MiningKey,
|
||
|
2 => KeyType::VotingKey,
|
||
|
3 => KeyType::PayoutKey,
|
||
|
n => unreachable!("unrecognized `KeyType`: {}", n),
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// V1 Keys Contract (used in `BallotCreated` event and within the `votingState`):
|
||
|
/// https://github.com/poanetwork/poa-network-consensus-contracts/blob/aa45e19ca50f7cae308c1281d950245b0c65182a/contracts/VotingToChangeKeys.sol#L10
|
||
|
///
|
||
|
/// V1 Threshold Contract (used in `BallotCreated` event):
|
||
|
/// https://github.com/poanetwork/poa-network-consensus-contracts/blob/aa45e19ca50f7cae308c1281d950245b0c65182a/contracts/VotingToChangeMinThreshold.sol#L89
|
||
|
///
|
||
|
/// V1 Proxy Contract (used in `BallotCreated` event):
|
||
|
/// https://github.com/poanetwork/poa-network-consensus-contracts/blob/aa45e19ca50f7cae308c1281d950245b0c65182a/contracts/VotingToChangeProxyAddress.sol#L85
|
||
|
///
|
||
|
/// Note: V1 contracts do not use the `Emission` variant.
|
||
|
///
|
||
|
/// V2 - all contracts use the same enum:
|
||
|
/// https://github.com/poanetwork/poa-network-consensus-contracts/blob/ec307069302fdf6647e8b1bdc13093960913b266/contracts/abstracts/EnumBallotTypes.sol#L5
|
||
|
#[derive(Clone, Copy, Debug)]
|
||
|
pub enum BallotType {
|
||
|
InvalidKey,
|
||
|
AddKey,
|
||
|
RemoveKey,
|
||
|
SwapKey,
|
||
|
Threshold,
|
||
|
Proxy,
|
||
|
Emission,
|
||
|
}
|
||
|
|
||
|
/// Converts a `U256` (from a V2 keys contract's voting-state) into a `BallotType`.
|
||
|
impl From<U256> for BallotType {
|
||
|
fn from(uint: U256) -> Self {
|
||
|
BallotType::from(H256::from(uint))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// Converts an `H256` from a `web3::types::Log`'s `topics` vector to a `BallotType`.
|
||
|
impl From<H256> for BallotType {
|
||
|
fn from(topic: H256) -> Self {
|
||
|
match topic.low_u64() {
|
||
|
0 => BallotType::InvalidKey,
|
||
|
1 => BallotType::AddKey,
|
||
|
2 => BallotType::RemoveKey,
|
||
|
3 => BallotType::SwapKey,
|
||
|
4 => BallotType::Threshold,
|
||
|
5 => BallotType::Proxy,
|
||
|
6 => BallotType::Emission,
|
||
|
n => unreachable!("unrecognized `BallotType`: {}", n),
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// A parsed `BallotCreated` event log. All V1 and V2 contracts use the same `BallotCreated` event.
|
||
|
///
|
||
|
/// V1 Keys Contract's `BallotCreated` event:
|
||
|
/// https://github.com/poanetwork/poa-network-consensus-contracts/blob/aa45e19ca50f7cae308c1281d950245b0c65182a/contracts/VotingToChangeKeys.sol#L45
|
||
|
///
|
||
|
/// V1 Threshold Contract's `BallotCreated` event:
|
||
|
/// https://github.com/poanetwork/poa-network-consensus-contracts/blob/aa45e19ca50f7cae308c1281d950245b0c65182a/contracts/VotingToChangeMinThreshold.sol#L40
|
||
|
///
|
||
|
/// V1 Proxy Contract's `BallotCreated` event:
|
||
|
/// https://github.com/poanetwork/poa-network-consensus-contracts/blob/aa45e19ca50f7cae308c1281d950245b0c65182a/contracts/VotingToChangeMinThreshold.sol#L40
|
||
|
///
|
||
|
/// V2 - all contracts use the same `BallotCreated` event:
|
||
|
/// https://github.com/poanetwork/poa-network-consensus-contracts/blob/ec307069302fdf6647e8b1bdc13093960913b266/contracts/abstracts/VotingTo.sol#L30
|
||
|
#[derive(Clone, Copy, Debug)]
|
||
|
pub struct BallotCreatedLog {
|
||
|
pub block_number: U256,
|
||
|
pub ballot_id: U256,
|
||
|
pub ballot_type: BallotType,
|
||
|
pub creator: Address,
|
||
|
}
|
||
|
|
||
|
impl BallotCreatedLog {
|
||
|
pub fn from_ethabi_log(log: ethabi::Log, block_number: U256) -> Result<Self> {
|
||
|
let mut ballot_id: Option<U256> = None;
|
||
|
let mut ballot_type: Option<BallotType> = None;
|
||
|
let mut creator: Option<Address> = None;
|
||
|
for ethabi::LogParam { name, value } in log.params {
|
||
|
match name.as_ref() {
|
||
|
"id" => ballot_id = value.to_uint(),
|
||
|
"ballotType" => ballot_type = value.to_uint().map(BallotType::from),
|
||
|
"creator" => creator = value.to_address(),
|
||
|
name => unreachable!("Found unknown `BallotCreated` event log field: {}", name),
|
||
|
};
|
||
|
}
|
||
|
let ballot_id = match ballot_id {
|
||
|
Some(id) => id,
|
||
|
None => return Err(Error::FailedToParseBallotCreatedLog("missing `id`".into())),
|
||
|
};
|
||
|
let ballot_type = match ballot_type {
|
||
|
Some(ballot_type) => ballot_type,
|
||
|
None => return Err(Error::FailedToParseBallotCreatedLog("missing `ballot_type`".into())),
|
||
|
};
|
||
|
let creator = match creator {
|
||
|
Some(creator) => creator,
|
||
|
None => return Err(Error::FailedToParseBallotCreatedLog("missing `creator`".into())),
|
||
|
};
|
||
|
Ok(BallotCreatedLog { ballot_id, ballot_type, creator, block_number })
|
||
|
}
|
||
|
}
|