From 866d30593a033a32922e8898627560c5dd1c9c0b Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Wed, 30 Nov 2022 22:19:05 +0100 Subject: [PATCH] feat(core): Chain impls and refactoring (#1909) * sort * derive Default * use u64 for conversions and add impl * one impl block and comments --- ethers-core/src/types/chain.rs | 452 +++++++++++++++++---------------- 1 file changed, 227 insertions(+), 225 deletions(-) diff --git a/ethers-core/src/types/chain.rs b/ethers-core/src/types/chain.rs index f5cab58b..1e395091 100644 --- a/ethers-core/src/types/chain.rs +++ b/ethers-core/src/types/chain.rs @@ -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 for u32 { + fn from(chain: Chain) -> Self { + chain as u32 + } +} + +impl From for u64 { + fn from(chain: Chain) -> Self { + chain as u64 + } +} + +impl From for U256 { + fn from(chain: Chain) -> Self { + u64::from(chain).into() + } +} + +impl TryFrom for Chain { + type Error = ParseChainError; + + fn try_from(chain: u32) -> Result { + (chain as u64).try_into() + } +} + +impl TryFrom for Chain { + type Error = ParseChainError; + + fn try_from(chain: u64) -> Result { + 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 for Chain { + type Error = ParseChainError; + + fn try_from(chain: U256) -> Result { + 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 { + 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 for u32 { - fn from(chain: Chain) -> Self { - chain as u32 - } -} - -impl From for U256 { - fn from(chain: Chain) -> Self { - u32::from(chain).into() - } -} - -impl From for u64 { - fn from(chain: Chain) -> Self { - u32::from(chain).into() - } -} - -impl TryFrom for Chain { - type Error = ParseChainError; - - fn try_from(chain: u64) -> Result { - 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 for Chain { - type Error = ParseChainError; - - fn try_from(chain: U256) -> Result { - 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 { - 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);