feat(core): Chain impls and refactoring (#1909)

* sort

* derive Default

* use u64 for conversions and add impl

* one impl block and comments
This commit is contained in:
DaniPopes 2022-11-30 22:19:05 +01:00 committed by GitHub
parent 17addcfd91
commit 866d30593a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 227 additions and 225 deletions

View File

@ -1,4 +1,4 @@
use crate::types::U256;
use super::U256;
use serde::Deserialize;
use std::{
convert::{TryFrom, TryInto},
@ -13,69 +13,257 @@ use thiserror::Error;
#[error("Failed to parse chain: {0}")]
pub struct ParseChainError(String);
/// Enum for all known chains
///
/// When adding a new chain:
/// 1. add new variant
/// 2. update Display/FromStr impl
/// 3. add etherscan_keys if supported
// When adding a new chain:
// 1. add new variant to the Chain enum;
// 2. update Display/FromStr impl;
// 3. add etherscan_keys if supported.
/// Enum for all known chains.
#[repr(u64)]
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Deserialize, EnumVariantNames)]
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, Deserialize, EnumVariantNames)]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "kebab-case")]
pub enum Chain {
#[default]
Mainnet = 1,
Morden = 2,
Ropsten = 3,
Rinkeby = 4,
Goerli = 5,
Kovan = 42,
#[strum(serialize = "gnosis")]
XDai = 100,
Chiado = 10200,
Polygon = 137,
Fantom = 250,
Dev = 1337,
AnvilHardhat = 31337,
FantomTestnet = 4002,
PolygonMumbai = 80001,
Avalanche = 43114,
AvalancheFuji = 43113,
Sepolia = 11155111,
Moonbeam = 1284,
Moonbase = 1287,
MoonbeamDev = 1281,
Moonriver = 1285,
Optimism = 10,
OptimismGoerli = 420,
OptimismKovan = 69,
Arbitrum = 42161,
ArbitrumTestnet = 421611,
ArbitrumGoerli = 421613,
Cronos = 25,
CronosTestnet = 338,
Rsk = 30,
Kovan = 42,
#[strum(serialize = "bsc")]
BinanceSmartChain = 56,
OptimismKovan = 69,
Sokol = 77,
#[strum(serialize = "bsc-testnet")]
BinanceSmartChainTestnet = 97,
Poa = 99,
Sokol = 77,
Rsk = 30,
Oasis = 26863,
Emerald = 42262,
EmeraldTestnet = 42261,
Evmos = 9001,
#[strum(serialize = "gnosis")]
XDai = 100,
Polygon = 137,
Fantom = 250,
CronosTestnet = 338,
OptimismGoerli = 420,
MoonbeamDev = 1281,
Moonbeam = 1284,
Moonriver = 1285,
Moonbase = 1287,
Dev = 1337,
FantomTestnet = 4002,
EvmosTestnet = 9000,
Evmos = 9001,
Chiado = 10200,
Oasis = 26863,
AnvilHardhat = 31337,
Arbitrum = 42161,
EmeraldTestnet = 42261,
Emerald = 42262,
AvalancheFuji = 43113,
Avalanche = 43114,
PolygonMumbai = 80001,
ArbitrumTestnet = 421611,
ArbitrumGoerli = 421613,
Sepolia = 11155111,
Aurora = 1313161554,
AuroraTestnet = 1313161555,
}
// === impl Chain ===
impl fmt::Display for Chain {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let chain = match self {
Chain::Mainnet => "mainnet",
Chain::Morden => "morden",
Chain::Ropsten => "ropsten",
Chain::Rinkeby => "rinkeby",
Chain::Goerli => "goerli",
Chain::Kovan => "kovan",
Chain::XDai => "gnosis",
Chain::Chiado => "chiado",
Chain::Polygon => "polygon",
Chain::PolygonMumbai => "mumbai",
Chain::Avalanche => "avalanche",
Chain::AvalancheFuji => "fuji",
Chain::Sepolia => "sepolia",
Chain::Moonbeam => "moonbeam",
Chain::Moonbase => "moonbase",
Chain::MoonbeamDev => "moonbeam-dev",
Chain::Moonriver => "moonriver",
Chain::Optimism => "optimism",
Chain::OptimismGoerli => "optimism-goerli",
Chain::OptimismKovan => "optimism-kovan",
Chain::Fantom => "fantom",
Chain::Dev => "dev",
Chain::FantomTestnet => "fantom-testnet",
Chain::BinanceSmartChain => "bsc",
Chain::BinanceSmartChainTestnet => "bsc-testnet",
Chain::Arbitrum => "arbitrum",
Chain::ArbitrumTestnet => "arbitrum-testnet",
Chain::ArbitrumGoerli => "arbitrum-goerli",
Chain::Cronos => "cronos",
Chain::CronosTestnet => "cronos-testnet",
Chain::Poa => "poa",
Chain::Sokol => "sokol",
Chain::Rsk => "rsk",
Chain::Oasis => "oasis",
Chain::Emerald => "emerald",
Chain::EmeraldTestnet => "emerald-testnet",
Chain::AnvilHardhat => "anvil-hardhat",
Chain::Evmos => "evmos",
Chain::EvmosTestnet => "evmos-testnet",
Chain::Aurora => "aurora",
Chain::AuroraTestnet => "aurora-testnet",
};
f.pad(chain)
}
}
impl From<Chain> for u32 {
fn from(chain: Chain) -> Self {
chain as u32
}
}
impl From<Chain> for u64 {
fn from(chain: Chain) -> Self {
chain as u64
}
}
impl From<Chain> for U256 {
fn from(chain: Chain) -> Self {
u64::from(chain).into()
}
}
impl TryFrom<u32> for Chain {
type Error = ParseChainError;
fn try_from(chain: u32) -> Result<Chain, Self::Error> {
(chain as u64).try_into()
}
}
impl TryFrom<u64> for Chain {
type Error = ParseChainError;
fn try_from(chain: u64) -> Result<Chain, Self::Error> {
Ok(match chain {
1 => Chain::Mainnet,
2 => Chain::Morden,
3 => Chain::Ropsten,
4 => Chain::Rinkeby,
5 => Chain::Goerli,
42 => Chain::Kovan,
100 => Chain::XDai,
10200 => Chain::Chiado,
137 => Chain::Polygon,
1337 => Chain::Dev,
31337 => Chain::AnvilHardhat,
250 => Chain::Fantom,
4002 => Chain::FantomTestnet,
80001 => Chain::PolygonMumbai,
43114 => Chain::Avalanche,
43113 => Chain::AvalancheFuji,
11155111 => Chain::Sepolia,
1284 => Chain::Moonbeam,
1287 => Chain::Moonbase,
1281 => Chain::MoonbeamDev,
1285 => Chain::Moonriver,
10 => Chain::Optimism,
420 => Chain::OptimismGoerli,
69 => Chain::OptimismKovan,
56 => Chain::BinanceSmartChain,
97 => Chain::BinanceSmartChainTestnet,
42161 => Chain::Arbitrum,
421611 => Chain::ArbitrumTestnet,
421613 => Chain::ArbitrumGoerli,
25 => Chain::Cronos,
338 => Chain::CronosTestnet,
99 => Chain::Poa,
77 => Chain::Sokol,
30 => Chain::Rsk,
26863 => Chain::Oasis,
42262 => Chain::Emerald,
42261 => Chain::EmeraldTestnet,
9001 => Chain::Evmos,
9000 => Chain::EvmosTestnet,
1313161554 => Chain::Aurora,
1313161555 => Chain::AuroraTestnet,
_ => return Err(ParseChainError(chain.to_string())),
})
}
}
impl TryFrom<U256> for Chain {
type Error = ParseChainError;
fn try_from(chain: U256) -> Result<Chain, Self::Error> {
if chain.bits() > 64 {
return Err(ParseChainError(chain.to_string()))
}
chain.as_u64().try_into()
}
}
impl FromStr for Chain {
type Err = ParseChainError;
fn from_str(chain: &str) -> Result<Self, Self::Err> {
Ok(match chain {
"mainnet" => Chain::Mainnet,
"morden" => Chain::Morden,
"ropsten" => Chain::Ropsten,
"rinkeby" => Chain::Rinkeby,
"goerli" => Chain::Goerli,
"kovan" => Chain::Kovan,
"xdai" | "gnosis" | "gnosis-chain" => Chain::XDai,
"chiado" => Chain::Chiado,
"polygon" => Chain::Polygon,
"mumbai" | "polygon-mumbai" => Chain::PolygonMumbai,
"avalanche" => Chain::Avalanche,
"fuji" | "avalanche-fuji" => Chain::AvalancheFuji,
"sepolia" => Chain::Sepolia,
"moonbeam" => Chain::Moonbeam,
"moonbase" => Chain::Moonbase,
"moonbeam-dev" => Chain::MoonbeamDev,
"moonriver" => Chain::Moonriver,
"optimism" => Chain::Optimism,
"optimism-goerli" => Chain::OptimismGoerli,
"optimism-kovan" => Chain::OptimismKovan,
"fantom" => Chain::Fantom,
"fantom-testnet" => Chain::FantomTestnet,
"dev" => Chain::Dev,
"anvil" | "hardhat" | "anvil-hardhat" => Chain::AnvilHardhat,
"bsc" => Chain::BinanceSmartChain,
"bsc-testnet" => Chain::BinanceSmartChainTestnet,
"arbitrum" => Chain::Arbitrum,
"arbitrum-testnet" => Chain::ArbitrumTestnet,
"arbitrum-goerli" => Chain::ArbitrumGoerli,
"cronos" => Chain::Cronos,
"cronos-testnet" => Chain::CronosTestnet,
"poa" => Chain::Poa,
"sokol" => Chain::Sokol,
"rsk" => Chain::Rsk,
"oasis" => Chain::Oasis,
"emerald" => Chain::Emerald,
"emerald-testnet" => Chain::EmeraldTestnet,
"aurora" => Chain::Aurora,
"aurora-testnet" => Chain::AuroraTestnet,
_ => return Err(ParseChainError(chain.to_owned())),
})
}
}
impl Chain {
/// The blocktime varies from chain to chain
/// The blocktime varies from chain to chain.
///
/// It can be beneficial to know the average blocktime to adjust the polling of an Http provider
/// It can be beneficial to know the average blocktime to adjust the polling of an HTTP provider
/// for example.
///
/// **Note:** this will not return the accurate average depending on the time but is rather a
@ -223,187 +411,7 @@ impl Chain {
Some(urls)
}
}
impl fmt::Display for Chain {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
let chain = match self {
Chain::Mainnet => "mainnet",
Chain::Morden => "morden",
Chain::Ropsten => "ropsten",
Chain::Rinkeby => "rinkeby",
Chain::Goerli => "goerli",
Chain::Kovan => "kovan",
Chain::XDai => "gnosis",
Chain::Chiado => "chiado",
Chain::Polygon => "polygon",
Chain::PolygonMumbai => "mumbai",
Chain::Avalanche => "avalanche",
Chain::AvalancheFuji => "fuji",
Chain::Sepolia => "sepolia",
Chain::Moonbeam => "moonbeam",
Chain::Moonbase => "moonbase",
Chain::MoonbeamDev => "moonbeam-dev",
Chain::Moonriver => "moonriver",
Chain::Optimism => "optimism",
Chain::OptimismGoerli => "optimism-goerli",
Chain::OptimismKovan => "optimism-kovan",
Chain::Fantom => "fantom",
Chain::Dev => "dev",
Chain::FantomTestnet => "fantom-testnet",
Chain::BinanceSmartChain => "bsc",
Chain::BinanceSmartChainTestnet => "bsc-testnet",
Chain::Arbitrum => "arbitrum",
Chain::ArbitrumTestnet => "arbitrum-testnet",
Chain::ArbitrumGoerli => "arbitrum-goerli",
Chain::Cronos => "cronos",
Chain::CronosTestnet => "cronos-testnet",
Chain::Poa => "poa",
Chain::Sokol => "sokol",
Chain::Rsk => "rsk",
Chain::Oasis => "oasis",
Chain::Emerald => "emerald",
Chain::EmeraldTestnet => "emerald-testnet",
Chain::AnvilHardhat => "anvil-hardhat",
Chain::Evmos => "evmos",
Chain::EvmosTestnet => "evmos-testnet",
Chain::Aurora => "aurora",
Chain::AuroraTestnet => "aurora-testnet",
};
write!(formatter, "{chain}")
}
}
impl From<Chain> for u32 {
fn from(chain: Chain) -> Self {
chain as u32
}
}
impl From<Chain> for U256 {
fn from(chain: Chain) -> Self {
u32::from(chain).into()
}
}
impl From<Chain> for u64 {
fn from(chain: Chain) -> Self {
u32::from(chain).into()
}
}
impl TryFrom<u64> for Chain {
type Error = ParseChainError;
fn try_from(chain: u64) -> Result<Chain, Self::Error> {
Ok(match chain {
1 => Chain::Mainnet,
2 => Chain::Morden,
3 => Chain::Ropsten,
4 => Chain::Rinkeby,
5 => Chain::Goerli,
42 => Chain::Kovan,
100 => Chain::XDai,
10200 => Chain::Chiado,
137 => Chain::Polygon,
1337 => Chain::Dev,
31337 => Chain::AnvilHardhat,
250 => Chain::Fantom,
4002 => Chain::FantomTestnet,
80001 => Chain::PolygonMumbai,
43114 => Chain::Avalanche,
43113 => Chain::AvalancheFuji,
11155111 => Chain::Sepolia,
1284 => Chain::Moonbeam,
1287 => Chain::Moonbase,
1281 => Chain::MoonbeamDev,
1285 => Chain::Moonriver,
10 => Chain::Optimism,
420 => Chain::OptimismGoerli,
69 => Chain::OptimismKovan,
56 => Chain::BinanceSmartChain,
97 => Chain::BinanceSmartChainTestnet,
42161 => Chain::Arbitrum,
421611 => Chain::ArbitrumTestnet,
421613 => Chain::ArbitrumGoerli,
25 => Chain::Cronos,
338 => Chain::CronosTestnet,
99 => Chain::Poa,
77 => Chain::Sokol,
30 => Chain::Rsk,
26863 => Chain::Oasis,
42262 => Chain::Emerald,
42261 => Chain::EmeraldTestnet,
9001 => Chain::Evmos,
9000 => Chain::EvmosTestnet,
1313161554 => Chain::Aurora,
1313161555 => Chain::AuroraTestnet,
_ => return Err(ParseChainError(chain.to_string())),
})
}
}
impl TryFrom<U256> for Chain {
type Error = ParseChainError;
fn try_from(chain: U256) -> Result<Chain, Self::Error> {
if chain.bits() > 64 {
return Err(ParseChainError(chain.to_string()))
}
chain.as_u64().try_into()
}
}
impl FromStr for Chain {
type Err = ParseChainError;
fn from_str(chain: &str) -> Result<Self, Self::Err> {
Ok(match chain {
"mainnet" => Chain::Mainnet,
"morden" => Chain::Morden,
"ropsten" => Chain::Ropsten,
"rinkeby" => Chain::Rinkeby,
"goerli" => Chain::Goerli,
"kovan" => Chain::Kovan,
"xdai" | "gnosis" | "gnosis-chain" => Chain::XDai,
"chiado" => Chain::Chiado,
"polygon" => Chain::Polygon,
"mumbai" | "polygon-mumbai" => Chain::PolygonMumbai,
"avalanche" => Chain::Avalanche,
"fuji" | "avalanche-fuji" => Chain::AvalancheFuji,
"sepolia" => Chain::Sepolia,
"moonbeam" => Chain::Moonbeam,
"moonbase" => Chain::Moonbase,
"moonbeam-dev" => Chain::MoonbeamDev,
"moonriver" => Chain::Moonriver,
"optimism" => Chain::Optimism,
"optimism-goerli" => Chain::OptimismGoerli,
"optimism-kovan" => Chain::OptimismKovan,
"fantom" => Chain::Fantom,
"fantom-testnet" => Chain::FantomTestnet,
"dev" => Chain::Dev,
"anvil" | "hardhat" | "anvil-hardhat" => Chain::AnvilHardhat,
"bsc" => Chain::BinanceSmartChain,
"bsc-testnet" => Chain::BinanceSmartChainTestnet,
"arbitrum" => Chain::Arbitrum,
"arbitrum-testnet" => Chain::ArbitrumTestnet,
"arbitrum-goerli" => Chain::ArbitrumGoerli,
"cronos" => Chain::Cronos,
"cronos-testnet" => Chain::CronosTestnet,
"poa" => Chain::Poa,
"sokol" => Chain::Sokol,
"rsk" => Chain::Rsk,
"oasis" => Chain::Oasis,
"emerald" => Chain::Emerald,
"emerald-testnet" => Chain::EmeraldTestnet,
"aurora" => Chain::Aurora,
"aurora-testnet" => Chain::AuroraTestnet,
_ => return Err(ParseChainError(chain.to_owned())),
})
}
}
impl Chain {
/// Helper function for checking if a chainid corresponds to a legacy chainid
/// without eip1559
pub fn is_legacy(&self) -> bool {
@ -428,12 +436,6 @@ impl Chain {
}
}
impl Default for Chain {
fn default() -> Self {
Chain::Mainnet
}
}
#[test]
fn test_default_chain() {
assert_eq!(Chain::default(), Chain::Mainnet);