Make Validator Set Network a first-class property

There already should only be one validator set operating per network. This
formalizes that. Then, validator sets used to be able to operate over multiple
networks. That is no longer possible.

This formalization increases validator set flexibility while also allowing the
ability to formalize the definiton of tokens (which is necessary to define a
gas asset).
This commit is contained in:
Luke Parker
2023-03-25 01:30:53 -04:00
parent 397d79040c
commit 6a981dae6e
10 changed files with 136 additions and 104 deletions

View File

@@ -12,6 +12,8 @@ all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[dependencies]
lazy_static = { version = "1", optional = true }
zeroize = { version = "^1.5", features = ["derive"], optional = true }
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
@@ -23,5 +25,5 @@ sp-core = { git = "https://github.com/serai-dex/substrate", default-features = f
sp-runtime = { git = "https://github.com/serai-dex/substrate", default-features = false }
[features]
std = ["zeroize", "scale/std", "scale-info/std", "serde", "sp-core/std", "sp-runtime/std"]
std = ["lazy_static", "zeroize", "scale/std", "scale-info/std", "serde", "sp-core/std", "sp-runtime/std"]
default = ["std"]

View File

@@ -4,9 +4,25 @@ use zeroize::Zeroize;
use scale::{Encode, Decode, MaxEncodedLen};
use scale_info::TypeInfo;
use sp_core::{ConstU32, bounded::BoundedVec};
#[cfg(feature = "std")]
use serde::{Serialize, Deserialize};
/// The type used to identify networks.
#[derive(Clone, Copy, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)]
#[cfg_attr(feature = "std", derive(Zeroize, Serialize, Deserialize))]
pub struct NetworkId(pub u16);
impl From<u16> for NetworkId {
fn from(network: u16) -> NetworkId {
NetworkId(network)
}
}
pub const BITCOIN_NET_ID: NetworkId = NetworkId(0);
pub const ETHEREUM_NET_ID: NetworkId = NetworkId(1);
pub const MONERO_NET_ID: NetworkId = NetworkId(2);
/// The type used to identify coins.
#[derive(Clone, Copy, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)]
#[cfg_attr(feature = "std", derive(Zeroize, Serialize, Deserialize))]
@@ -22,3 +38,49 @@ pub const BITCOIN: Coin = Coin(1);
pub const ETHER: Coin = Coin(2);
pub const DAI: Coin = Coin(3);
pub const MONERO: Coin = Coin(4);
// Max of 8 coins per network
// Since Serai isn't interested in listing tokens, as on-chain DEXs will almost certainly have
// more liquidity, the only reason we'd have so many coins from a network is if there's no DEX
// on-chain
// There's probably no chain with so many *worthwhile* coins and no on-chain DEX
// This could probably be just 4, yet 8 is a hedge for the unforseen
// If necessary, this can be increased with a fork
pub const MAX_COINS_PER_NETWORK: u32 = 8;
/// Network definition.
#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct Network {
coins: BoundedVec<Coin, ConstU32<{ MAX_COINS_PER_NETWORK }>>,
}
#[cfg(feature = "std")]
impl Zeroize for Network {
fn zeroize(&mut self) {
for coin in self.coins.as_mut() {
coin.zeroize();
}
self.coins.truncate(0);
}
}
impl Network {
#[cfg(feature = "std")]
pub fn new(coins: Vec<Coin>) -> Result<Network, &'static str> {
Ok(Network {
coins: coins.try_into().map_err(|_| "coins length exceeds {MAX_COINS_PER_NETWORK}")?,
})
}
pub fn coins(&self) -> &[Coin] {
&self.coins
}
}
#[cfg(feature = "std")]
lazy_static::lazy_static! {
pub static ref BITCOIN_NET: Network = Network::new(vec![BITCOIN]).unwrap();
pub static ref ETHEREUM_NET: Network = Network::new(vec![ETHER, DAI]).unwrap();
pub static ref MONERO_NET: Network = Network::new(vec![MONERO]).unwrap();
}