Restore a runtime which compiles

Adds BABE, GRANDPA, to the runtime definition and a few stubs for not yet
implemented interfaces.
This commit is contained in:
Luke Parker
2025-09-21 13:16:43 -04:00
parent d373d2a4c9
commit e63acf3f67
23 changed files with 517 additions and 1136 deletions

394
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -22,12 +22,12 @@ workspace = true
borsh = { version = "1", default-features = false, features = ["derive", "de_strict_order"] }
bitvec = { version = "1", default-features = false, features = ["alloc"] }
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
serde = { version = "1", default-features = false, features = ["derive"], optional = true }
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"], optional = true }
sp-runtime = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false, features = ["serde"], optional = true }
frame-support = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false, optional = true }
sp-runtime = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false, features = ["serde"], optional = true }
frame-support = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false, optional = true }
serai-primitives = { path = "../primitives", version = "0.1", default-features = false }

View File

@@ -47,6 +47,8 @@ pub enum Call {
stand_against {
/// The signal to stand against.
signal: Signal,
/// The network this validator is standing against the signal on behalf of.
with_network: NetworkId,
},
}

View File

@@ -13,8 +13,8 @@ use serai_primitives::{
pub enum Call {
/// Set the keys for a validator set.
set_keys {
/// The validator set which is setting their keys.
validator_set: ExternalValidatorSet,
/// The network whose latest decided validator set is setting their keys..
network: ExternalNetworkId,
/// The keys being set.
key_pair: KeyPair,
/// The participants in the validator set who signed off on these keys.
@@ -29,8 +29,8 @@ pub enum Call {
},
/// Report a validator set's slashes onto Serai.
report_slashes {
/// The validator set which is setting their keys.
validator_set: ExternalValidatorSet,
/// The network whose latest retired validator set is reporting their slashes.
network: ExternalNetworkId,
/// The slashes they're reporting.
slashes: SlashReport,
/// The signature confirming the validity of this slash report.

View File

@@ -31,9 +31,9 @@ serde_json = { version = "1", optional = true }
serai-abi = { path = "../abi", version = "0.1" }
multiaddr = { version = "0.18", optional = true }
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", optional = true }
sp-runtime = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", optional = true }
frame-system = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", optional = true }
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", optional = true }
sp-runtime = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", optional = true }
frame-system = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", optional = true }
async-lock = "3"

View File

@@ -18,10 +18,10 @@ workspace = true
[dependencies]
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
frame-system = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
frame-support = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
frame-system = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
frame-support = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
serai-abi = { path = "../abi", default-features = false, features = ["substrate"] }
serai-core-pallet = { path = "../core", default-features = false }
@@ -29,7 +29,7 @@ serai-core-pallet = { path = "../core", default-features = false }
[dev-dependencies]
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
sp-io = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false, features = ["std"] }
sp-io = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false, features = ["std"] }
[features]
std = [

View File

@@ -49,10 +49,12 @@ mod pallet {
/// The instance used to represent coins on the Serai network.
///
/// This would either be SRI itself or the sriXYZ coins swappable via pools.
#[derive(Default)]
pub struct CoinsInstance;
/// The instance used to represent liquidity tokens on the Serai network.
///
/// Coin::XYZ would be considered as the liquidity token for the Coin::SRI - Coin::XYZ pool.
#[derive(Default)]
pub struct LiquidityTokensInstance;
/// The configuration of this pallet.
@@ -66,7 +68,7 @@ mod pallet {
/// The genesis state to use for this pallet.
#[pallet::genesis_config]
#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode)]
#[derive(Clone, Debug)]
pub struct GenesisConfig<T: Config<I>, I: 'static = ()> {
/// The balances to initiate the state with.
///
@@ -76,10 +78,9 @@ mod pallet {
/// PhantomData to bind `I`.
pub _instance: PhantomData<I>,
}
impl<T: Config<I>, I: 'static> Default for GenesisConfig<T, I> {
fn default() -> Self {
GenesisConfig { accounts: Default::default(), _instance: Default::default() }
Self { accounts: Default::default(), _instance: PhantomData }
}
}

View File

@@ -20,10 +20,10 @@ borsh = { version = "1", default-features = false, features = ["derive", "de_str
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
frame-system = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
frame-support = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
frame-system = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
frame-support = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
serai-abi = { path = "../abi", default-features = false, features = ["substrate"] }

View File

@@ -21,15 +21,15 @@ workspace = true
[dependencies]
scale = { package = "parity-scale-codec", version = "3.6.1", default-features = false }
sp-std = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-io = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-api = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-runtime = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-std = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
sp-io = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
sp-api = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
sp-runtime = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
frame-system = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
frame-support = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
frame-benchmarking = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false, optional = true }
frame-system = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
frame-support = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
frame-benchmarking = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false, optional = true }
coins-pallet = { package = "serai-coins-pallet", path = "../coins", default-features = false }

View File

@@ -21,8 +21,8 @@ workspace = true
[dependencies]
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
frame-system = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
frame-support = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
frame-system = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
frame-support = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
dex-pallet = { package = "serai-dex-pallet", path = "../dex", default-features = false }
coins-pallet = { package = "serai-coins-pallet", path = "../coins", default-features = false }
@@ -30,16 +30,16 @@ coins-pallet = { package = "serai-coins-pallet", path = "../coins", default-feat
serai-primitives = { path = "../primitives", default-features = false }
[dev-dependencies]
pallet-babe = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
pallet-grandpa = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
pallet-timestamp = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
pallet-babe = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
pallet-grandpa = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
pallet-timestamp = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
validator-sets-pallet = { package = "serai-validator-sets-pallet", path = "../validator-sets", default-features = false }
sp-io = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-runtime = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-consensus-babe = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-io = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
sp-runtime = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
sp-consensus-babe = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
[features]
std = [

View File

@@ -21,11 +21,11 @@ workspace = true
[dependencies]
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
frame-system = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
frame-support = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
frame-system = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
frame-support = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
sp-std = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-runtime = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-std = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
sp-runtime = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
coins-pallet = { package = "serai-coins-pallet", path = "../coins", default-features = false }
validator-sets-pallet = { package = "serai-validator-sets-pallet", path = "../validator-sets", default-features = false }

View File

@@ -21,12 +21,12 @@ workspace = true
[dependencies]
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
frame-system = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
frame-support = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
frame-system = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
frame-support = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
sp-std = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-application-crypto = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-std = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
sp-application-crypto = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
dex-pallet = { package = "serai-dex-pallet", path = "../dex", default-features = false }
coins-pallet = { package = "serai-coins-pallet", path = "../coins", default-features = false }

View File

@@ -24,14 +24,14 @@ bitvec = { version = "1", default-features = false, features = ["alloc"] }
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive", "max-encoded-len"] }
sp-std = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-application-crypto = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-io = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-runtime = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-std = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
sp-application-crypto = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
sp-io = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
sp-runtime = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
frame-system = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
frame-support = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
frame-system = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
frame-support = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
serai-primitives = { path = "../primitives", default-features = false }
@@ -42,9 +42,9 @@ genesis-liquidity-pallet = { package = "serai-genesis-liquidity-pallet", path =
emissions-pallet = { package = "serai-emissions-pallet", path = "../emissions", default-features = false }
[dev-dependencies]
pallet-babe = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
pallet-grandpa = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
pallet-timestamp = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
pallet-babe = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
pallet-grandpa = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
pallet-timestamp = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
economic-security-pallet = { package = "serai-economic-security-pallet", path = "../economic-security", default-features = false }

View File

@@ -34,16 +34,16 @@ secq256k1 = { path = "../../crypto/secq256k1" }
libp2p = "0.56"
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7" }
sp-keystore = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7" }
sp-timestamp = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7" }
sp-io = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7" }
sp-blockchain = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7" }
sp-api = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7" }
sp-block-builder = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7" }
sp-consensus-babe = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7" }
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9" }
sp-keystore = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9" }
sp-timestamp = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9" }
sp-io = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9" }
sp-blockchain = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9" }
sp-api = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9" }
sp-block-builder = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9" }
sp-consensus-babe = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9" }
frame-benchmarking = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7" }
frame-benchmarking = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9" }
serai-runtime = { path = "../runtime", features = ["std"] }
@@ -55,24 +55,24 @@ jsonrpsee = { version = "0.24", features = ["server"] }
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
sc-transaction-pool = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7" }
sc-transaction-pool-api = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7" }
sc-basic-authorship = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7" }
sc-executor = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7" }
sc-service = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7" }
sc-client-api = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7" }
sc-network-common = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7" }
sc-network = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sc-transaction-pool = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9" }
sc-transaction-pool-api = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9" }
sc-basic-authorship = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9" }
sc-executor = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9" }
sc-service = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9" }
sc-client-api = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9" }
sc-network-common = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9" }
sc-network = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
sc-consensus = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7" }
sc-consensus-babe = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7" }
sc-consensus-grandpa = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7" }
sc-authority-discovery = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7" }
sc-consensus = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9" }
sc-consensus-babe = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9" }
sc-consensus-grandpa = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9" }
sc-authority-discovery = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9" }
sc-telemetry = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7" }
sc-cli = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false, features = ["rocksdb"] }
sc-telemetry = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9" }
sc-cli = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false, features = ["rocksdb"] }
sc-rpc-api = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7" }
sc-rpc-api = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9" }
serai-env = { path = "../../common/env" }

View File

@@ -21,7 +21,7 @@ borsh = { version = "1", default-features = false, features = ["derive", "de_str
bitvec = { version = "1", default-features = false, features = ["alloc"] }
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"], optional = true }
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
ciphersuite = { path = "../../crypto/ciphersuite", default-features = false, features = ["alloc"] }
schnorr-signatures = { path = "../../crypto/schnorr", default-features = false }

View File

@@ -20,16 +20,22 @@ workspace = true
[dependencies]
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-version = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-runtime = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-api = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
sp-session = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
sp-version = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
sp-runtime = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
sp-api = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
serai-abi = { path = "../abi", default-features = false, features = ["substrate"] }
frame-system = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
frame-support = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
frame-executive = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
frame-system = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
frame-support = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
frame-executive = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
pallet-timestamp = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
pallet-session = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
pallet-babe = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
pallet-grandpa = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
serai-core-pallet = { path = "../core", default-features = false }
serai-coins-pallet = { path = "../coins", default-features = false }
@@ -37,13 +43,14 @@ serai-validator-sets-pallet = { path = "../validator-sets", default-features = f
serai-signals-pallet = { path = "../signals", default-features = false }
[build-dependencies]
substrate-wasm-builder = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7" }
substrate-wasm-builder = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9" }
[features]
std = [
"scale/std",
"sp-core/std",
"sp-session/std",
"sp-version/std",
"sp-runtime/std",
"sp-api/std",
@@ -54,6 +61,10 @@ std = [
"frame-support/std",
"frame-executive/std",
"pallet-session/std",
"pallet-babe/std",
"pallet-grandpa/std",
"serai-core-pallet/std",
"serai-coins-pallet/std",
"serai-validator-sets-pallet/std",
@@ -69,6 +80,10 @@ try-runtime = [
"frame-support/try-runtime",
"frame-executive/try-runtime",
"pallet-session/try-runtime",
"pallet-babe/try-runtime",
"pallet-grandpa/try-runtime",
"serai-core-pallet/try-runtime",
"serai-coins-pallet/try-runtime",
"serai-validator-sets-pallet/try-runtime",
@@ -81,6 +96,10 @@ runtime-benchmarks = [
"frame-system/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"pallet-babe/runtime-benchmarks",
"pallet-grandpa/runtime-benchmarks",
"pallet-session/runtime-benchmarks",
"serai-core-pallet/runtime-benchmarks",
"serai-coins-pallet/runtime-benchmarks",
"serai-validator-sets-pallet/runtime-benchmarks",

View File

@@ -8,13 +8,17 @@ extern crate alloc;
use alloc::borrow::Cow;
use sp_core::sr25519::Public;
use sp_core::{ConstU32, ConstU64, sr25519::Public};
use sp_runtime::{Perbill, Weight};
use sp_version::RuntimeVersion;
#[rustfmt::skip]
use serai_abi::{
primitives::address::SeraiAddress, SubstrateHeader as Header, SubstrateBlock,
primitives::{
network_id::{ExternalNetworkId, NetworkId},
balance::{Amount, ExternalBalance},
address::SeraiAddress,
},
SubstrateHeader as Header, SubstrateBlock,
};
use serai_coins_pallet::{CoinsInstance, LiquidityTokensInstance};
@@ -79,13 +83,22 @@ mod runtime {
pub type Coins = serai_coins_pallet::Pallet<Runtime, CoinsInstance>;
#[runtime::pallet_index(3)]
pub type LiquidityTokens = serai_coins_pallet::Pallet<Runtime, LiquidityTokensInstance>;
#[runtime::pallet_index(4)]
pub type ValidatorSets = serai_validator_sets_pallet::Pallet<Runtime>;
#[runtime::pallet_index(5)]
#[runtime::pallet_index(4)]
pub type Signals = serai_signals_pallet::Pallet<Runtime>;
#[runtime::pallet_index(5)]
pub type LiquidityTokens = serai_coins_pallet::Pallet<Runtime, LiquidityTokensInstance>;
#[runtime::pallet_index(0xfd)]
pub type Session = pallet_session::Pallet<Runtime>;
#[runtime::pallet_index(0xfe)]
pub type Babe = pallet_babe::Pallet<Runtime>;
#[runtime::pallet_index(0xff)]
pub type Grandpa = pallet_grandpa::Pallet<Runtime>;
}
impl frame_system::Config for Runtime {
@@ -104,7 +117,7 @@ impl frame_system::Config for Runtime {
type Block = Block;
// Don't track old block hashes within the System pallet
// We use not a number -> hash index, but a hash -> () index, in our own pallet
type BlockHashCount = sp_core::ConstU64<1>;
type BlockHashCount = ConstU64<1>;
type DbWeight = frame_support::weights::constants::RocksDbWeight;
type Version = Version;
type PalletInfo = PalletInfo;
@@ -118,7 +131,7 @@ impl frame_system::Config for Runtime {
// We don't invoke any hooks on-set-code as we don't perform upgrades via the blockchain yet via
// nodes, ensuring everyone who upgrades consents to the rules they upgrade to
type OnSetCode = ();
type MaxConsumers = sp_core::ConstU32<{ u32::MAX }>;
type MaxConsumers = ConstU32<{ u32::MAX }>;
// No migrations set
type SingleBlockMigrations = ();
type MultiBlockMigrator = ();
@@ -133,15 +146,84 @@ impl serai_core_pallet::Config for Runtime {}
impl serai_coins_pallet::Config<CoinsInstance> for Runtime {
type AllowMint = serai_coins_pallet::AlwaysAllowMint; // TODO
}
impl serai_coins_pallet::Config<LiquidityTokensInstance> for Runtime {
type AllowMint = serai_coins_pallet::AlwaysAllowMint;
#[doc(hidden)]
pub struct EconomicSecurity; // TODO
impl serai_abi::economic_security::EconomicSecurity for EconomicSecurity {
fn achieved_economic_security(_network: ExternalNetworkId) -> bool {
false
}
fn sri_value(_balance: ExternalBalance) -> Amount {
Amount(0)
}
}
impl serai_validator_sets_pallet::Config for Runtime {
type ShouldEndSession = Babe;
type EconomicSecurity = EconomicSecurity;
}
impl serai_signals_pallet::Config for Runtime {
type RetirementValidityDuration = sp_core::ConstU64<0>; // TODO
type RetirementLockInDuration = sp_core::ConstU64<0>; // TODO
type RetirementValidityDuration = ConstU64<0>; // TODO
type RetirementLockInDuration = ConstU64<0>; // TODO
}
impl serai_coins_pallet::Config<LiquidityTokensInstance> for Runtime {
type AllowMint = serai_coins_pallet::AlwaysAllowMint;
}
/*
`pallet-babe` requires we implement `pallet-timestamp` for the associated constants. It does not
actually require we offer the timestamp pallet however, and we don't as we follow our methodology
(using the block header for timestamps, not an inherent transaction).
TODO: Set timestamp when executing a block.
*/
impl pallet_timestamp::Config for Runtime {
type Moment = u64;
type OnTimestampSet = Babe;
type MinimumPeriod = ConstU64<0>; // TODO
type WeightInfo = ();
}
#[doc(hidden)]
pub struct GetCurrentSessionForSubstrate;
impl pallet_session::GetCurrentSessionForSubstrate for GetCurrentSessionForSubstrate {
fn get() -> u32 {
serai_validator_sets_pallet::Pallet::<Runtime>::current_session(NetworkId::Serai)
.map(|session| session.0)
.unwrap_or(0)
}
}
impl pallet_session::Config for Runtime {
type Session = GetCurrentSessionForSubstrate;
}
type MaxAuthorities =
ConstU32<{ serai_abi::primitives::validator_sets::KeyShares::MAX_PER_SET_U32 }>;
impl pallet_babe::Config for Runtime {
type EpochDuration = ConstU64<0>; // TODO
type ExpectedBlockTime = ConstU64<0>; // TODO
type EpochChangeTrigger = pallet_babe::ExternalTrigger;
type WeightInfo = ();
type MaxAuthorities = MaxAuthorities;
type MaxNominators = ConstU32<1>;
// TODO: https://github.com/serai-dex/serai/issues/657
type DisabledValidators = ();
type KeyOwnerProof = sp_session::MembershipProof;
type EquivocationReportSystem = ();
}
impl pallet_grandpa::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type WeightInfo = ();
type MaxAuthorities = MaxAuthorities;
type MaxNominators = ConstU32<1>;
// TODO: https://github.com/serai-dex/serai/issues/657
type MaxSetIdSessionEntries = ConstU64<0>;
type KeyOwnerProof = sp_session::MembershipProof;
type EquivocationReportSystem = ();
}
impl From<Option<SeraiAddress>> for RuntimeOrigin {
@@ -158,36 +240,54 @@ impl From<serai_abi::Call> for RuntimeCall {
match call {
serai_abi::Call::Coins(call) => {
use serai_abi::coins::Call;
match call {
Call::transfer { to, coins } => {
RuntimeCall::Coins(serai_coins_pallet::Call::transfer { to: to.into(), coins })
}
Call::burn { coins } => RuntimeCall::Coins(serai_coins_pallet::Call::burn { coins }),
use serai_coins_pallet::Call as Scall;
RuntimeCall::Coins(match call {
Call::transfer { to, coins } => Scall::transfer { to: to.into(), coins },
Call::burn { coins } => Scall::burn { coins },
Call::burn_with_instruction { instruction } => {
RuntimeCall::Coins(serai_coins_pallet::Call::burn_with_instruction { instruction })
}
Scall::burn_with_instruction { instruction }
}
})
}
serai_abi::Call::ValidatorSets(call) => {
use serai_abi::validator_sets::Call;
match call {
Call::set_keys { .. } |
Call::report_slashes { .. } |
Call::set_embedded_elliptic_curve_keys { .. } |
Call::allocate { .. } |
Call::deallocate { .. } |
Call::claim_deallocation { .. } => todo!("TODO"),
use serai_validator_sets_pallet::Call as Scall;
RuntimeCall::ValidatorSets(match call {
Call::set_keys { network, key_pair, signature_participants, signature } => {
Scall::set_keys { network, key_pair, signature_participants, signature }
}
Call::report_slashes { network, slashes, signature } => {
Scall::report_slashes { network, slashes, signature }
}
Call::set_embedded_elliptic_curve_keys { keys } => {
Scall::set_embedded_elliptic_curve_keys { keys }
}
Call::allocate { network, amount } => Scall::allocate { network, amount },
Call::deallocate { network, amount } => Scall::deallocate { network, amount },
Call::claim_deallocation { deallocation } => Scall::claim_deallocation {
network: deallocation.network,
session: deallocation.session,
},
})
}
serai_abi::Call::Signals(call) => {
use serai_abi::signals::Call;
match call {
Call::register_retirement_signal { .. } |
Call::revoke_retirement_signal { .. } |
Call::favor { .. } |
Call::revoke_favor { .. } |
Call::stand_against { .. } => todo!("TODO"),
use serai_signals_pallet::Call as Scall;
RuntimeCall::Signals(match call {
Call::register_retirement_signal { in_favor_of } => {
Scall::register_retirement_signal { in_favor_of }
}
Call::revoke_retirement_signal { was_in_favor_of } => {
Scall::revoke_retirement_signal { retirement_signal: was_in_favor_of }
}
Call::favor { signal, with_network } => Scall::favor { signal, with_network },
Call::revoke_favor { signal, with_network } => {
Scall::revoke_favor { signal, with_network }
}
Call::stand_against { signal, with_network } => {
Scall::stand_against { signal, with_network }
}
})
}
serai_abi::Call::Dex(call) => {
use serai_abi::dex::Call;
@@ -331,9 +431,6 @@ pub use in_instructions_pallet as in_instructions;
pub use signals_pallet as signals;
pub use pallet_babe as babe;
pub use pallet_grandpa as grandpa;
pub use genesis_liquidity_pallet as genesis_liquidity;
pub use emissions_pallet as emissions;
@@ -492,43 +589,9 @@ impl pallet_authorship::Config for Runtime {
type EventHandler = ();
}
// Maximum number of authorities per session.
pub type MaxAuthorities = ConstU32<{ validator_sets::primitives::MAX_KEY_SHARES_PER_SET_U32 }>;
/// Longevity of an offence report.
pub type ReportLongevity = <Runtime as pallet_babe::Config>::EpochDuration;
impl babe::Config for Runtime {
#[cfg(feature = "fast-epoch")]
type EpochDuration = ConstU64<{ FAST_EPOCH_DURATION }>;
#[cfg(not(feature = "fast-epoch"))]
type EpochDuration = ConstU64<{ 4 * 7 * DAYS }>;
type ExpectedBlockTime = ConstU64<{ TARGET_BLOCK_TIME * 1000 }>;
type EpochChangeTrigger = babe::ExternalTrigger;
type DisabledValidators = ValidatorSets;
type WeightInfo = ();
type MaxAuthorities = MaxAuthorities;
type KeyOwnerProof = MembershipProof<Self>;
type EquivocationReportSystem =
babe::EquivocationReportSystem<Self, ValidatorSets, ValidatorSets, ReportLongevity>;
}
impl grandpa::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type WeightInfo = ();
type MaxAuthorities = MaxAuthorities;
type MaxSetIdSessionEntries = ConstU64<0>;
type KeyOwnerProof = MembershipProof<Self>;
type EquivocationReportSystem =
grandpa::EquivocationReportSystem<Self, ValidatorSets, ValidatorSets, ReportLongevity>;
}
construct_runtime!(
pub enum Runtime {
System: system exclude_parts { Call },

View File

@@ -21,10 +21,10 @@ workspace = true
[dependencies]
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
frame-system = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
frame-support = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
frame-system = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
frame-support = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
serai-abi = { path = "../abi", default-features = false, features = ["substrate"] }

View File

@@ -36,13 +36,13 @@ pub mod pallet {
}
#[pallet::genesis_config]
#[derive(Debug, Encode, Decode)]
#[derive(Clone, Debug)]
pub struct GenesisConfig<T: Config> {
_config: PhantomData<T>,
}
impl<T: Config> Default for GenesisConfig<T> {
fn default() -> Self {
GenesisConfig { _config: PhantomData }
Self { _config: PhantomData }
}
}
#[pallet::genesis_build]
@@ -221,20 +221,16 @@ pub mod pallet {
fn revoke_favor_internal(
validator: T::AccountId,
signal: Signal,
for_network: NetworkId,
with_network: NetworkId,
) -> DispatchResult {
if !Favors::<T>::contains_key((signal, for_network), validator) {
if !Favors::<T>::contains_key((signal, with_network), validator) {
Err::<(), _>(Error::<T>::RevokingNonExistentFavor)?;
}
Favors::<T>::remove((signal, for_network), validator);
Core::<T>::emit_event(Event::FavorRevoked {
signal,
by: validator.into(),
with_network: for_network,
});
Favors::<T>::remove((signal, with_network), validator);
Core::<T>::emit_event(Event::FavorRevoked { signal, by: validator.into(), with_network });
// Update the tally for this network
Self::tally_for_network(signal, for_network);
Self::tally_for_network(signal, with_network);
Ok(())
}
@@ -342,7 +338,7 @@ pub mod pallet {
/// Favor a signal.
#[pallet::call_index(2)]
#[pallet::weight((0, DispatchClass::Normal))] // TODO
pub fn favor(origin: OriginFor<T>, signal: Signal, for_network: NetworkId) -> DispatchResult {
pub fn favor(origin: OriginFor<T>, signal: Signal, with_network: NetworkId) -> DispatchResult {
let validator = ensure_signed(origin)?;
// Perform the relevant checks for this class of signal
@@ -373,21 +369,17 @@ pub mod pallet {
Signal::Halt { .. } => {}
}
if Favors::<T>::contains_key((signal, for_network), validator) {
if Favors::<T>::contains_key((signal, with_network), validator) {
Err::<(), _>(Error::<T>::AlreadyInFavor)?;
}
// Set the validator as in favor
Favors::<T>::set((signal, for_network), validator, Some(()));
Favors::<T>::set((signal, with_network), validator, Some(()));
Core::<T>::emit_event(Event::SignalFavored {
signal,
by: validator.into(),
with_network: for_network,
});
Core::<T>::emit_event(Event::SignalFavored { signal, by: validator.into(), with_network });
// Check if the network is in favor
let network_in_favor = Self::tally_for_network(signal, for_network);
let network_in_favor = Self::tally_for_network(signal, with_network);
// If this network is in favor, check if enough networks are
if network_in_favor && Self::tally_for_all_networks(signal) {
@@ -416,7 +408,7 @@ pub mod pallet {
pub fn revoke_favor(
origin: OriginFor<T>,
signal: Signal,
for_network: NetworkId,
with_network: NetworkId,
) -> DispatchResult {
match signal {
Signal::Retire { .. } => {
@@ -428,7 +420,7 @@ pub mod pallet {
}
let validator = ensure_signed(origin)?;
Self::revoke_favor_internal(validator, signal, for_network)
Self::revoke_favor_internal(validator, signal, with_network)
}
/// Emit an event standing against the signal.
@@ -442,7 +434,7 @@ pub mod pallet {
pub fn stand_against(
origin: OriginFor<T>,
signal: Signal,
for_network: NetworkId,
with_network: NetworkId,
) -> DispatchResult {
match signal {
Signal::Retire { .. } => {
@@ -455,8 +447,8 @@ pub mod pallet {
let validator = ensure_signed(origin)?;
// If currently in favor, revoke the favor
if Favors::<T>::contains_key((signal, for_network), validator) {
Self::revoke_favor_internal(validator, signal, for_network)?;
if Favors::<T>::contains_key((signal, with_network), validator) {
Self::revoke_favor_internal(validator, signal, with_network)?;
} else {
// Check this Signal exists (which would've been implied by `Favors` for it existing)
match signal {
@@ -472,7 +464,7 @@ pub mod pallet {
Core::<T>::emit_event(Event::AgainstSignal {
signal,
account: validator.into(),
with_network: for_network,
with_network,
});
Ok(())

View File

@@ -20,17 +20,17 @@ bitvec = { version = "1", default-features = false, features = ["alloc", "serde"
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive", "bit-vec"] }
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-application-crypto = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-io = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-api = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
sp-application-crypto = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
sp-io = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
sp-api = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
frame-system = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
frame-support = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
frame-system = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
frame-support = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
pallet-session = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
pallet-babe = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
pallet-grandpa = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "16336c737dbe833e9d138a256af99698aba637c7", default-features = false }
pallet-session = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
pallet-babe = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
pallet-grandpa = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "ef18bfc7029d4a3d7c27e1d0b84da5091628a7d9", default-features = false }
serai-abi = { path = "../abi", default-features = false, features = ["substrate"] }

View File

@@ -3,7 +3,7 @@
#![cfg_attr(not(feature = "std"), no_std)]
extern crate alloc;
use alloc::vec::Vec;
use alloc::{vec, vec::Vec};
mod embedded_elliptic_curve_keys;
use embedded_elliptic_curve_keys::*;
@@ -65,11 +65,16 @@ mod pallet {
}
#[pallet::genesis_config]
#[derive(Clone, PartialEq, Eq, Debug)]
#[derive(Clone, Debug)]
pub struct GenesisConfig<T: Config> {
/// List of participants to place in the initial validator sets.
pub participants: Vec<(T::AccountId, Vec<SignedEmbeddedEllipticCurveKeys>)>,
}
impl<T: Config> Default for GenesisConfig<T> {
fn default() -> Self {
Self { participants: Default::default() }
}
}
#[pallet::pallet]
pub struct Pallet<T>(PhantomData<T>);

View File

@@ -1,217 +0,0 @@
//! Test environment for ValidatorSets pallet.
use super::*;
use std::collections::HashMap;
use frame_support::{
construct_runtime,
traits::{ConstU16, ConstU32, ConstU64},
};
use sp_core::{
H256, Pair as PairTrait,
sr25519::{Public, Pair},
};
use sp_runtime::{
traits::{BlakeTwo256, IdentityLookup},
BuildStorage,
};
use serai_abi::primitives::*;
use validator_sets::{primitives::MAX_KEY_SHARES_PER_SET_U32, MembershipProof};
pub use crate as validator_sets;
pub use serai_coins_pallet as coins;
pub use dex_pallet as dex;
pub use pallet_babe as babe;
pub use pallet_grandpa as grandpa;
pub use pallet_timestamp as timestamp;
type Block = frame_system::mocking::MockBlock<Test>;
// Maximum number of authorities per session.
pub type MaxAuthorities = ConstU32<{ MAX_KEY_SHARES_PER_SET_U32 }>;
pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4);
pub const BABE_GENESIS_EPOCH_CONFIG: sp_consensus_babe::BabeEpochConfiguration =
sp_consensus_babe::BabeEpochConfiguration {
c: PRIMARY_PROBABILITY,
allowed_slots: sp_consensus_babe::AllowedSlots::PrimaryAndSecondaryPlainSlots,
};
pub const MEDIAN_PRICE_WINDOW_LENGTH: u16 = 10;
construct_runtime!(
pub enum Test
{
System: frame_system,
Timestamp: timestamp,
Coins: coins,
LiquidityTokens: coins::<Instance1>::{Pallet, Call, Storage, Event<T>},
ValidatorSets: validator_sets,
Dex: dex,
Babe: babe,
Grandpa: grandpa,
}
);
impl frame_system::Config for Test {
type BaseCallFilter = frame_support::traits::Everything;
type BlockWeights = ();
type BlockLength = ();
type RuntimeOrigin = RuntimeOrigin;
type RuntimeCall = RuntimeCall;
type Nonce = u64;
type Hash = H256;
type Hashing = BlakeTwo256;
type AccountId = Public;
type Lookup = IdentityLookup<Self::AccountId>;
type Block = Block;
type RuntimeEvent = RuntimeEvent;
type BlockHashCount = ConstU64<250>;
type DbWeight = ();
type Version = ();
type PalletInfo = PalletInfo;
type AccountData = ();
type OnNewAccount = ();
type OnKilledAccount = ();
type SystemWeightInfo = ();
type SS58Prefix = ();
type OnSetCode = ();
type MaxConsumers = ConstU32<16>;
}
impl timestamp::Config for Test {
type Moment = u64;
type OnTimestampSet = Babe;
type MinimumPeriod = ConstU64<{ (TARGET_BLOCK_TIME * 1000) / 2 }>;
type WeightInfo = ();
}
impl babe::Config for Test {
type EpochDuration = ConstU64<{ FAST_EPOCH_DURATION }>;
type ExpectedBlockTime = ConstU64<{ TARGET_BLOCK_TIME * 1000 }>;
type EpochChangeTrigger = babe::ExternalTrigger;
type DisabledValidators = ValidatorSets;
type WeightInfo = ();
type MaxAuthorities = MaxAuthorities;
type KeyOwnerProof = MembershipProof<Self>;
type EquivocationReportSystem = ();
}
impl grandpa::Config for Test {
type RuntimeEvent = RuntimeEvent;
type WeightInfo = ();
type MaxAuthorities = MaxAuthorities;
type MaxSetIdSessionEntries = ConstU64<0>;
type KeyOwnerProof = MembershipProof<Self>;
type EquivocationReportSystem = ();
}
impl coins::Config for Test {
type RuntimeEvent = RuntimeEvent;
type AllowMint = ValidatorSets;
}
impl coins::Config<coins::Instance1> for Test {
type RuntimeEvent = RuntimeEvent;
type AllowMint = ();
}
impl dex::Config for Test {
type RuntimeEvent = RuntimeEvent;
type LPFee = ConstU32<3>; // 0.3%
type MintMinLiquidity = ConstU64<10000>;
type MaxSwapPathLength = ConstU32<3>; // coin1 -> SRI -> coin2
type MedianPriceWindowLength = ConstU16<{ MEDIAN_PRICE_WINDOW_LENGTH }>;
type WeightInfo = dex::weights::SubstrateWeight<Test>;
}
impl Config for Test {
type RuntimeEvent = RuntimeEvent;
type ShouldEndSession = Babe;
}
// For a const we can't define
pub fn genesis_participants() -> Vec<Pair> {
vec![
insecure_pair_from_name("Alice"),
insecure_pair_from_name("Bob"),
insecure_pair_from_name("Charlie"),
insecure_pair_from_name("Dave"),
]
}
// Amounts for single key share per network
pub fn key_shares() -> HashMap<NetworkId, Amount> {
HashMap::from([
(NetworkId::Serai, Amount(50_000 * 10_u64.pow(8))),
(NetworkId::External(ExternalNetworkId::Bitcoin), Amount(1_000_000 * 10_u64.pow(8))),
(NetworkId::External(ExternalNetworkId::Ethereum), Amount(1_000_000 * 10_u64.pow(8))),
(NetworkId::External(ExternalNetworkId::Monero), Amount(100_000 * 10_u64.pow(8))),
])
}
pub(crate) fn new_test_ext() -> sp_io::TestExternalities {
let mut t = frame_system::GenesisConfig::<Test>::default().build_storage().unwrap();
let networks: Vec<(NetworkId, Amount)> = key_shares().into_iter().collect::<Vec<_>>();
coins::GenesisConfig::<Test> {
accounts: genesis_participants()
.clone()
.into_iter()
.map(|a| (a.public(), Balance { coin: Coin::Serai, amount: Amount(1 << 60) }))
.collect(),
_ignore: Default::default(),
}
.assimilate_storage(&mut t)
.unwrap();
#[expect(unused_variables, unreachable_code, clippy::diverging_sub_expression)]
validator_sets::GenesisConfig::<Test> {
networks,
participants: genesis_participants()
.into_iter()
.map(|p| {
let keys: crate::AllEmbeddedEllipticCurveKeysAtGenesis = todo!("TODO");
(p.public(), keys)
})
.collect(),
}
.assimilate_storage(&mut t)
.unwrap();
babe::GenesisConfig::<Test> {
authorities: genesis_participants()
.into_iter()
.map(|validator| (validator.public().into(), 1))
.collect(),
epoch_config: Some(BABE_GENESIS_EPOCH_CONFIG),
_config: PhantomData,
}
.assimilate_storage(&mut t)
.unwrap();
grandpa::GenesisConfig::<Test> {
authorities: genesis_participants()
.into_iter()
.map(|validator| (validator.public().into(), 1))
.collect(),
_config: PhantomData,
}
.assimilate_storage(&mut t)
.unwrap();
let mut ext = sp_io::TestExternalities::new(t);
ext.execute_with(|| System::set_block_number(0));
ext
}

View File

@@ -1,558 +0,0 @@
use crate::{mock::*, primitives::*};
use std::collections::HashMap;
use ciphersuite::{WrappedGroup, GroupIo};
use dkg_musig::musig;
use schnorrkel::{frost::curve::Ristretto, Schnorrkel};
use zeroize::Zeroizing;
use rand_core::OsRng;
use frame_support::{
assert_noop, assert_ok,
pallet_prelude::{InvalidTransaction, TransactionSource},
traits::{OnFinalize, OnInitialize},
};
use frame_system::RawOrigin;
use sp_core::{
sr25519::{Public, Pair, Signature},
Pair as PairTrait,
};
use sp_runtime::traits::ValidateUnsigned;
use serai_abi::primitives::*;
fn active_network_validators(network: NetworkId) -> Vec<(Public, u64)> {
if network == NetworkId::Serai {
Babe::authorities().into_iter().map(|(id, key_share)| (id.into_inner(), key_share)).collect()
} else {
ValidatorSets::participants_for_latest_decided_set(network).unwrap().into_inner()
}
}
fn verify_session_and_active_validators(network: NetworkId, participants: &[Public], session: u32) {
let mut validators: Vec<Public> = active_network_validators(network)
.into_iter()
.map(|(p, ks)| {
assert_eq!(ks, 1);
p
})
.collect();
validators.sort();
assert_eq!(ValidatorSets::session(network).unwrap(), Session(session));
assert_eq!(participants, validators);
// TODO: how to make sure block finalizations work as usual here?
}
fn get_session_at_which_changes_activate(network: NetworkId) -> u32 {
let current_session = ValidatorSets::session(network).unwrap().0;
// changes should be active in the next session
if network == NetworkId::Serai {
// it takes 1 extra session for serai net to make the changes active.
current_session + 2
} else {
current_session + 1
}
}
fn set_keys_for_session(network: ExternalNetworkId) {
ValidatorSets::set_keys(
RawOrigin::None.into(),
network,
KeyPair(insecure_pair_from_name("Alice").public(), vec![].try_into().unwrap()),
vec![].try_into().unwrap(),
Signature([0u8; 64]),
)
.unwrap();
}
fn set_keys_signature(set: &ExternalValidatorSet, key_pair: &KeyPair, pairs: &[Pair]) -> Signature {
let mut pub_keys = vec![];
for pair in pairs {
let public_key =
<Ristretto as GroupIo>::read_G::<&[u8]>(&mut pair.public().0.as_ref()).unwrap();
pub_keys.push(public_key);
}
let mut threshold_keys = vec![];
for i in 0 .. pairs.len() {
let secret_key = <Ristretto as GroupIo>::read_F::<&[u8]>(
&mut pairs[i].as_ref().secret.to_bytes()[.. 32].as_ref(),
)
.unwrap();
assert_eq!(Ristretto::generator() * secret_key, pub_keys[i]);
threshold_keys.push(
musig::<Ristretto>(musig_context((*set).into()), Zeroizing::new(secret_key), &pub_keys)
.unwrap(),
);
}
let mut musig_keys = HashMap::new();
for threshold_keys in threshold_keys {
musig_keys.insert(threshold_keys.params().i(), threshold_keys);
}
let sig = frost::tests::sign_without_caching(
&mut OsRng,
frost::tests::algorithm_machines(&mut OsRng, &Schnorrkel::new(b"substrate"), &musig_keys),
&set_keys_message(set, key_pair),
);
Signature(sig.to_bytes())
}
fn get_ordered_keys(network: NetworkId, participants: &[Pair]) -> Vec<Pair> {
// retrieve the current session validators so that we know the order of the keys
// that is necessary for the correct musig signature.
let validators = ValidatorSets::participants_for_latest_decided_set(network).unwrap();
// collect the pairs of the validators
let mut pairs = vec![];
for (v, _) in validators {
let p = participants.iter().find(|pair| pair.public() == v).unwrap().clone();
pairs.push(p);
}
pairs
}
fn rotate_session_until(network: NetworkId, session: u32) {
let mut current = ValidatorSets::session(network).unwrap().0;
while current < session {
Babe::on_initialize(System::block_number() + 1);
ValidatorSets::rotate_session();
if let NetworkId::External(n) = network {
set_keys_for_session(n);
}
ValidatorSets::retire_set(ValidatorSet { session: Session(current), network });
current += 1;
}
assert_eq!(current, session);
}
#[test]
fn rotate_session() {
new_test_ext().execute_with(|| {
let genesis_participants: Vec<Public> =
genesis_participants().into_iter().map(|p| p.public()).collect();
let key_shares = key_shares();
let mut participants = HashMap::from([
(NetworkId::Serai, genesis_participants.clone()),
(NetworkId::External(ExternalNetworkId::Bitcoin), genesis_participants.clone()),
(NetworkId::External(ExternalNetworkId::Ethereum), genesis_participants.clone()),
(NetworkId::External(ExternalNetworkId::Monero), genesis_participants),
]);
// rotate session
for network in NETWORKS {
let participants = participants.get_mut(&network).unwrap();
// verify for session 0
participants.sort();
if let NetworkId::External(n) = network {
set_keys_for_session(n);
}
verify_session_and_active_validators(network, participants, 0);
// add 1 participant
let new_participant = insecure_pair_from_name("new-guy").public();
Coins::mint(new_participant, Balance { coin: Coin::Serai, amount: key_shares[&network] })
.unwrap();
ValidatorSets::allocate(
RawOrigin::Signed(new_participant).into(),
network,
key_shares[&network],
)
.unwrap();
participants.push(new_participant);
// move network to the activation session
let activation_session = get_session_at_which_changes_activate(network);
rotate_session_until(network, activation_session);
// verify
participants.sort();
verify_session_and_active_validators(network, participants, activation_session);
// remove 1 participant
let participant_to_remove = participants[0];
ValidatorSets::deallocate(
RawOrigin::Signed(participant_to_remove).into(),
network,
key_shares[&network],
)
.unwrap();
participants
.swap_remove(participants.iter().position(|k| *k == participant_to_remove).unwrap());
// check pending deallocations
let pending = ValidatorSets::pending_deallocations(
(network, participant_to_remove),
Session(if network == NetworkId::Serai {
activation_session + 3
} else {
activation_session + 2
}),
);
assert_eq!(pending, Some(key_shares[&network]));
// move network to the activation session
let activation_session = get_session_at_which_changes_activate(network);
rotate_session_until(network, activation_session);
// verify
participants.sort();
verify_session_and_active_validators(network, participants, activation_session);
}
})
}
#[test]
fn allocate() {
new_test_ext().execute_with(|| {
let genesis_participants: Vec<Public> =
genesis_participants().into_iter().map(|p| p.public()).collect();
let key_shares = key_shares();
let participant = insecure_pair_from_name("random1").public();
let network = NetworkId::External(ExternalNetworkId::Ethereum);
// check genesis TAS
set_keys_for_session(network.try_into().unwrap());
assert_eq!(
ValidatorSets::total_allocated_stake(network).unwrap().0,
key_shares[&network].0 * u64::try_from(genesis_participants.len()).unwrap()
);
// we can't allocate less than a key share
let amount = Amount(key_shares[&network].0 * 3);
Coins::mint(participant, Balance { coin: Coin::Serai, amount }).unwrap();
assert_noop!(
ValidatorSets::allocate(
RawOrigin::Signed(participant).into(),
network,
Amount(key_shares[&network].0 - 1)
),
validator_sets::Error::<Test>::InsufficientAllocation
);
// we can't allocate too much that the net exhibits the ability to handle any single node
// becoming byzantine
assert_noop!(
ValidatorSets::allocate(RawOrigin::Signed(participant).into(), network, amount),
validator_sets::Error::<Test>::AllocationWouldRemoveFaultTolerance
);
// we should be allocate a proper amount
assert_ok!(ValidatorSets::allocate(
RawOrigin::Signed(participant).into(),
network,
key_shares[&network]
));
assert_eq!(Coins::balance(participant, Coin::Serai).0, amount.0 - key_shares[&network].0);
// check new amount is reflected on TAS on new session
rotate_session_until(network, 1);
assert_eq!(
ValidatorSets::total_allocated_stake(network).unwrap().0,
key_shares[&network].0 * (u64::try_from(genesis_participants.len()).unwrap() + 1)
);
// check that new participants match
let mut active_participants: Vec<Public> =
active_network_validators(network).into_iter().map(|(p, _)| p).collect();
let mut current_participants = genesis_participants.clone();
current_participants.push(participant);
current_participants.sort();
active_participants.sort();
assert_eq!(current_participants, active_participants);
})
}
#[test]
fn deallocate_pending() {
new_test_ext().execute_with(|| {
let genesis_participants: Vec<Public> =
genesis_participants().into_iter().map(|p| p.public()).collect();
let key_shares = key_shares();
let participant = insecure_pair_from_name("random1").public();
let network = NetworkId::External(ExternalNetworkId::Bitcoin);
// check genesis TAS
set_keys_for_session(network.try_into().unwrap());
assert_eq!(
ValidatorSets::total_allocated_stake(network).unwrap().0,
key_shares[&network].0 * u64::try_from(genesis_participants.len()).unwrap()
);
// allocate some amount
Coins::mint(participant, Balance { coin: Coin::Serai, amount: key_shares[&network] }).unwrap();
assert_ok!(ValidatorSets::allocate(
RawOrigin::Signed(participant).into(),
network,
key_shares[&network]
));
assert_eq!(Coins::balance(participant, Coin::Serai).0, 0);
// move to next session
let mut current_session = ValidatorSets::session(network).unwrap().0;
current_session += 1;
rotate_session_until(network, current_session);
assert_eq!(
ValidatorSets::total_allocated_stake(network).unwrap().0,
key_shares[&network].0 * (u64::try_from(genesis_participants.len()).unwrap() + 1)
);
// we can deallocate all of our allocation
assert_ok!(ValidatorSets::deallocate(
RawOrigin::Signed(participant).into(),
network,
key_shares[&network]
));
// check pending deallocations
let pending_session =
if network == NetworkId::Serai { current_session + 3 } else { current_session + 2 };
assert_eq!(
ValidatorSets::pending_deallocations((network, participant), Session(pending_session)),
Some(key_shares[&network])
);
// we can't claim it immediately
assert_noop!(
ValidatorSets::claim_deallocation(
RawOrigin::Signed(participant).into(),
network,
Session(pending_session),
),
validator_sets::Error::<Test>::NonExistentDeallocation
);
// we should be able to claim it in the pending session
rotate_session_until(network, pending_session);
assert_ok!(ValidatorSets::claim_deallocation(
RawOrigin::Signed(participant).into(),
network,
Session(pending_session),
));
})
}
#[test]
fn deallocate_immediately() {
new_test_ext().execute_with(|| {
let genesis_participants: Vec<Public> =
genesis_participants().into_iter().map(|p| p.public()).collect();
let key_shares = key_shares();
let participant = insecure_pair_from_name("random1").public();
let network = NetworkId::External(ExternalNetworkId::Monero);
// check genesis TAS
set_keys_for_session(network.try_into().unwrap());
assert_eq!(
ValidatorSets::total_allocated_stake(network).unwrap().0,
key_shares[&network].0 * u64::try_from(genesis_participants.len()).unwrap()
);
// we can't deallocate when we don't have an allocation
assert_noop!(
ValidatorSets::deallocate(
RawOrigin::Signed(participant).into(),
network,
key_shares[&network]
),
validator_sets::Error::<Test>::NonExistentValidator
);
// allocate some amount
Coins::mint(participant, Balance { coin: Coin::Serai, amount: key_shares[&network] }).unwrap();
assert_ok!(ValidatorSets::allocate(
RawOrigin::Signed(participant).into(),
network,
key_shares[&network]
));
assert_eq!(Coins::balance(participant, Coin::Serai).0, 0);
// we can't deallocate more than our allocation
assert_noop!(
ValidatorSets::deallocate(
RawOrigin::Signed(participant).into(),
network,
Amount(key_shares[&network].0 + 1)
),
validator_sets::Error::<Test>::NotEnoughAllocated
);
// we can't deallocate an amount that would left us less than a key share as long as it isn't 0
assert_noop!(
ValidatorSets::deallocate(
RawOrigin::Signed(participant).into(),
network,
Amount(key_shares[&network].0 / 2)
),
validator_sets::Error::<Test>::DeallocationWouldRemoveParticipant
);
// we can deallocate all of our allocation
assert_ok!(ValidatorSets::deallocate(
RawOrigin::Signed(participant).into(),
network,
key_shares[&network]
));
// It should be immediately deallocated since we are not yet in an active set
assert_eq!(Coins::balance(participant, Coin::Serai), key_shares[&network]);
assert!(ValidatorSets::pending_deallocations((network, participant), Session(1)).is_none());
// allocate again
assert_ok!(ValidatorSets::allocate(
RawOrigin::Signed(participant).into(),
network,
key_shares[&network]
));
assert_eq!(Coins::balance(participant, Coin::Serai).0, 0);
// make a pool so that we have security oracle value for the coin
let liq_acc = insecure_pair_from_name("liq-acc").public();
let coin = ExternalCoin::Monero;
let balance = ExternalBalance { coin, amount: Amount(2 * key_shares[&network].0) };
Coins::mint(liq_acc, balance.into()).unwrap();
Coins::mint(liq_acc, Balance { coin: Coin::Serai, amount: balance.amount }).unwrap();
Dex::add_liquidity(
RawOrigin::Signed(liq_acc).into(),
coin,
balance.amount.0 / 2,
balance.amount.0 / 2,
1,
1,
liq_acc,
)
.unwrap();
Dex::on_finalize(1);
assert!(Dex::security_oracle_value(coin).unwrap().0 > 0);
// we can't deallocate if it would break economic security
// The reason we don't have economic security for the network now is that we just set
// the value for coin/SRI to 1:1 when making the pool and we minted 2 * key_share amount
// of coin but we only allocated 1 key_share of SRI for the network although we need more than
// 3 for the same amount of coin.
assert_noop!(
ValidatorSets::deallocate(
RawOrigin::Signed(participant).into(),
network,
key_shares[&network]
),
validator_sets::Error::<Test>::DeallocationWouldRemoveEconomicSecurity
);
})
}
#[test]
fn set_keys_keys_exist() {
new_test_ext().execute_with(|| {
let network = ExternalNetworkId::Monero;
// set the keys first
ValidatorSets::set_keys(
RawOrigin::None.into(),
network,
KeyPair(insecure_pair_from_name("name").public(), Vec::new().try_into().unwrap()),
vec![].try_into().unwrap(),
Signature([0u8; 64]),
)
.unwrap();
let call = validator_sets::Call::<Test>::set_keys {
network,
key_pair: KeyPair(insecure_pair_from_name("name").public(), Vec::new().try_into().unwrap()),
signature_participants: vec![].try_into().unwrap(),
signature: Signature([0u8; 64]),
};
assert_eq!(
ValidatorSets::validate_unsigned(TransactionSource::External, &call),
InvalidTransaction::Stale.into()
);
})
}
#[test]
fn set_keys_invalid_signature() {
new_test_ext().execute_with(|| {
let network = ExternalNetworkId::Ethereum;
let mut participants = get_ordered_keys(network.into(), &genesis_participants());
// we can't have invalid set
let mut set = ExternalValidatorSet { network, session: Session(1) };
let key_pair =
KeyPair(insecure_pair_from_name("name").public(), Vec::new().try_into().unwrap());
let signature = set_keys_signature(&set, &key_pair, &participants);
let call = validator_sets::Call::<Test>::set_keys {
network,
key_pair: key_pair.clone(),
signature_participants: vec![].try_into().unwrap(),
signature,
};
assert_eq!(
ValidatorSets::validate_unsigned(TransactionSource::External, &call),
InvalidTransaction::BadProof.into()
);
// fix the set
set.session = Session(0);
// participants should match
participants.push(insecure_pair_from_name("random1"));
let signature = set_keys_signature(&set, &key_pair, &participants);
let call = validator_sets::Call::<Test>::set_keys {
network,
key_pair: key_pair.clone(),
signature_participants: vec![].try_into().unwrap(),
signature,
};
assert_eq!(
ValidatorSets::validate_unsigned(TransactionSource::External, &call),
InvalidTransaction::BadProof.into()
);
// fix the participants
participants.pop();
// msg key pair and the key pair to set should match
let key_pair2 =
KeyPair(insecure_pair_from_name("name2").public(), Vec::new().try_into().unwrap());
let signature = set_keys_signature(&set, &key_pair2, &participants);
let call = validator_sets::Call::<Test>::set_keys {
network,
key_pair: key_pair.clone(),
signature_participants: vec![].try_into().unwrap(),
signature,
};
assert_eq!(
ValidatorSets::validate_unsigned(TransactionSource::External, &call),
InvalidTransaction::BadProof.into()
);
// use the same key pair
let signature = set_keys_signature(&set, &key_pair, &participants);
let call = validator_sets::Call::<Test>::set_keys {
network,
key_pair,
signature_participants: vec![].try_into().unwrap(),
signature,
};
ValidatorSets::validate_unsigned(TransactionSource::External, &call).unwrap();
})
}
// TODO: add report_slashes tests when the feature is complete.