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:
parent
17addcfd91
commit
866d30593a
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue