diff --git a/Cargo.lock b/Cargo.lock index dea47253..adc08520 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5085,6 +5085,38 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-session" +version = "4.0.0-dev" +source = "git+https://github.com/serai-dex/substrate#176b4e8cfc110f339d88ebd414602bc3833da3c3" +dependencies = [ + "frame-support", + "frame-system", + "impl-trait-for-tuples", + "log", + "pallet-timestamp", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-session", + "sp-staking", + "sp-std", + "sp-trie", +] + +[[package]] +name = "pallet-tendermint" +version = "0.1.0" +dependencies = [ + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "sp-application-crypto", +] + [[package]] name = "pallet-timestamp" version = "4.0.0-dev" @@ -7389,6 +7421,7 @@ dependencies = [ "async-trait", "futures", "log", + "pallet-session", "sc-basic-authorship", "sc-client-api", "sc-consensus", @@ -7404,6 +7437,7 @@ dependencies = [ "sp-core", "sp-inherents", "sp-runtime", + "sp-staking", "sp-timestamp", "substrate-prometheus-endpoint", "tendermint-machine", @@ -7505,18 +7539,20 @@ dependencies = [ "pallet-contracts", "pallet-contracts-primitives", "pallet-randomness-collective-flip", + "pallet-session", + "pallet-tendermint", "pallet-timestamp", "pallet-transaction-payment", "pallet-transaction-payment-rpc-runtime-api", "parity-scale-codec", "scale-info", "sp-api", + "sp-application-crypto", "sp-block-builder", "sp-core", "sp-inherents", "sp-offchain", "sp-runtime", - "sp-session", "sp-std", "sp-transaction-pool", "sp-version", diff --git a/Cargo.toml b/Cargo.toml index c5721b0d..0ceceae6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,8 +16,11 @@ members = [ "processor", - "substrate/runtime", "substrate/tendermint", + + "substrate/pallet-tendermint", + "substrate/runtime", + "substrate/consensus", "substrate/node", diff --git a/substrate/consensus/Cargo.toml b/substrate/consensus/Cargo.toml index e5e398cc..06bde9f1 100644 --- a/substrate/consensus/Cargo.toml +++ b/substrate/consensus/Cargo.toml @@ -24,6 +24,7 @@ sp-core = { git = "https://github.com/serai-dex/substrate" } sp-application-crypto = { git = "https://github.com/serai-dex/substrate" } sp-inherents = { git = "https://github.com/serai-dex/substrate" } sp-timestamp = { git = "https://github.com/serai-dex/substrate" } +sp-staking = { git = "https://github.com/serai-dex/substrate" } sp-blockchain = { git = "https://github.com/serai-dex/substrate" } sp-runtime = { git = "https://github.com/serai-dex/substrate" } sp-api = { git = "https://github.com/serai-dex/substrate" } @@ -37,6 +38,8 @@ sc-service = { git = "https://github.com/serai-dex/substrate" } sc-client-api = { git = "https://github.com/serai-dex/substrate" } sc-consensus = { git = "https://github.com/serai-dex/substrate" } +pallet-session = { git = "https://github.com/serai-dex/substrate" } + substrate-prometheus-endpoint = { git = "https://github.com/serai-dex/substrate" } tendermint-machine = { path = "../tendermint", features = ["substrate"] } diff --git a/substrate/pallet-tendermint/Cargo.toml b/substrate/pallet-tendermint/Cargo.toml new file mode 100644 index 00000000..6b3228c8 --- /dev/null +++ b/substrate/pallet-tendermint/Cargo.toml @@ -0,0 +1,37 @@ +[package] +name = "pallet-tendermint" +version = "0.1.0" +description = "Tendermint pallet for Substrate" +license = "AGPL-3.0-only" +repository = "https://github.com/serai-dex/serai/tree/develop/substrate/pallet-tendermint" +authors = ["Luke Parker "] +edition = "2021" + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] + +[dependencies] + +parity-scale-codec = { version = "3", default-features = false, features = ["derive"] } +scale-info = { version = "2", default-features = false, features = ["derive"] } + +sp-application-crypto = { git = "https://github.com/serai-dex/substrate", default-features = false } + +frame-system = { git = "https://github.com/serai-dex/substrate", default-features = false } +frame-support = { git = "https://github.com/serai-dex/substrate", default-features = false } + +[features] +std = [ + "sp-application-crypto/std", + + "frame-system/std", + "frame-support/std", +] + +runtime-benchmarks = [ + "frame-system/runtime-benchmarks", + "frame-support/runtime-benchmarks", +] + +default = ["std"] diff --git a/substrate/pallet-tendermint/src/lib.rs b/substrate/pallet-tendermint/src/lib.rs new file mode 100644 index 00000000..f5a1b91c --- /dev/null +++ b/substrate/pallet-tendermint/src/lib.rs @@ -0,0 +1,60 @@ +#![cfg_attr(not(feature = "std"), no_std)] + +use frame_support::traits::OneSessionHandler; + +#[frame_support::pallet] +pub mod pallet { + use frame_support::pallet_prelude::*; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(PhantomData); +} + +pub use pallet::*; + +pub mod crypto { + use sp_application_crypto::{KeyTypeId, app_crypto, sr25519}; + app_crypto!(sr25519, KeyTypeId(*b"tend")); + + impl sp_application_crypto::BoundToRuntimeAppPublic for crate::Pallet { + type Public = Public; + } + + sp_application_crypto::with_pair! { + pub type AuthorityPair = Pair; + } + pub type AuthoritySignature = Signature; + pub type AuthorityId = Public; +} + +impl OneSessionHandler for Pallet { + type Key = crypto::Public; + + fn on_genesis_session<'a, I: 'a>(_validators: I) + where + I: Iterator, + V: 'a, + { + } + + fn on_new_session<'a, I: 'a>(_changed: bool, _validators: I, _queued: I) + where + I: Iterator, + V: 'a, + { + /* + if !changed { + return; + } + + for validator in validators { + ... + } + */ + } + + fn on_disabled(_validator_index: u32) {} +} diff --git a/substrate/runtime/Cargo.toml b/substrate/runtime/Cargo.toml index 76b42541..62f13bd3 100644 --- a/substrate/runtime/Cargo.toml +++ b/substrate/runtime/Cargo.toml @@ -18,11 +18,11 @@ codec = { package = "parity-scale-codec", version = "3", default-features = fals scale-info = { version = "2", default-features = false, features = ["derive"] } sp-core = { git = "https://github.com/serai-dex/substrate", default-features = false } +sp-application-crypto = { git = "https://github.com/serai-dex/substrate", default-features = false } sp-std = { git = "https://github.com/serai-dex/substrate", default-features = false } sp-version = { git = "https://github.com/serai-dex/substrate", default-features = false } sp-inherents = { git = "https://github.com/serai-dex/substrate", default-features = false } sp-offchain = { git = "https://github.com/serai-dex/substrate", default-features = false } -sp-session = { git = "https://github.com/serai-dex/substrate", default-features = false } sp-transaction-pool = { git = "https://github.com/serai-dex/substrate", default-features = false } sp-block-builder = { git = "https://github.com/serai-dex/substrate", default-features = false} sp-runtime = { git = "https://github.com/serai-dex/substrate", default-features = false } @@ -41,6 +41,9 @@ pallet-transaction-payment = { git = "https://github.com/serai-dex/substrate", d pallet-contracts-primitives = { git = "https://github.com/serai-dex/substrate", default-features = false } pallet-contracts = { git = "https://github.com/serai-dex/substrate", default-features = false } +pallet-session = { git = "https://github.com/serai-dex/substrate", default-features = false } +pallet-tendermint = { path = "../pallet-tendermint", default-features = false } + frame-system-rpc-runtime-api = { git = "https://github.com/serai-dex/substrate", default-features = false } pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/serai-dex/substrate", default-features = false } @@ -53,11 +56,11 @@ std = [ "scale-info/std", "sp-core/std", + "sp-application-crypto/std", "sp-std/std", "sp-version/std", "sp-inherents/std", "sp-offchain/std", - "sp-session/std", "sp-transaction-pool/std", "sp-block-builder/std", "sp-runtime/std", @@ -75,6 +78,9 @@ std = [ "pallet-contracts/std", "pallet-contracts-primitives/std", + "pallet-session/std", + "pallet-tendermint/std", + "frame-system-rpc-runtime-api/std", "pallet-transaction-payment-rpc-runtime-api/std", ] @@ -90,6 +96,8 @@ runtime-benchmarks = [ "pallet-timestamp/runtime-benchmarks", "pallet-balances/runtime-benchmarks", + + "pallet-tendermint/runtime-benchmarks", ] default = ["std"] diff --git a/substrate/runtime/src/lib.rs b/substrate/runtime/src/lib.rs index 09d7b90e..95c528c5 100644 --- a/substrate/runtime/src/lib.rs +++ b/substrate/runtime/src/lib.rs @@ -4,11 +4,11 @@ #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); -use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; -pub use sp_core::sr25519::Signature; +use sp_core::OpaqueMetadata; +pub use sp_core::sr25519::{Public, Signature}; use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, - traits::{IdentityLookup, BlakeTwo256, Block as BlockT}, + traits::{Convert, OpaqueKeys, IdentityLookup, BlakeTwo256, Block as BlockT}, transaction_validity::{TransactionSource, TransactionValidity}, ApplyExtrinsicResult, Perbill, }; @@ -32,11 +32,13 @@ pub use pallet_timestamp::Call as TimestampCall; pub use pallet_balances::Call as BalancesCall; use pallet_transaction_payment::CurrencyAdapter; +use pallet_session::PeriodicSessions; + /// An index to a block. pub type BlockNumber = u32; /// Account ID type, equivalent to a public key -pub type AccountId = sp_core::sr25519::Public; +pub type AccountId = Public; /// Balance of an account. pub type Balance = u64; @@ -57,10 +59,14 @@ pub mod opaque { pub type BlockId = generic::BlockId; impl_opaque_keys! { - pub struct SessionKeys {} + pub struct SessionKeys { + pub tendermint: Tendermint, + } } } +use opaque::SessionKeys; + #[sp_version::runtime_version] pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("serai"), @@ -206,6 +212,30 @@ impl pallet_contracts::Config for Runtime { type MaxStorageKeyLen = ConstU32<128>; } +impl pallet_tendermint::Config for Runtime {} + +const SESSION_LENGTH: BlockNumber = 5 * DAYS; +type Sessions = PeriodicSessions, ConstU32<{ SESSION_LENGTH }>>; + +pub struct IdentityValidatorIdOf; +impl Convert> for IdentityValidatorIdOf { + fn convert(key: Public) -> Option { + Some(key) + } +} + +impl pallet_session::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type ValidatorId = AccountId; + type ValidatorIdOf = IdentityValidatorIdOf; + type ShouldEndSession = Sessions; + type NextSessionRotation = Sessions; + type SessionManager = (); + type SessionHandler = ::KeyTypeIdProviders; + type Keys = SessionKeys; + type WeightInfo = pallet_session::weights::SubstrateWeight; +} + pub type Address = AccountId; pub type Header = generic::Header; pub type Block = generic::Block; @@ -242,6 +272,8 @@ construct_runtime!( Balances: pallet_balances, TransactionPayment: pallet_transaction_payment, Contracts: pallet_contracts, + Session: pallet_session, + Tendermint: pallet_tendermint, } ); @@ -317,18 +349,6 @@ sp_api::impl_runtime_apis! { } } - impl sp_session::SessionKeys for Runtime { - fn generate_session_keys(seed: Option>) -> Vec { - opaque::SessionKeys::generate(seed) - } - - fn decode_session_keys( - encoded: Vec, - ) -> Option, KeyTypeId)>> { - opaque::SessionKeys::decode_into_raw_public_keys(&encoded) - } - } - impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { fn account_nonce(account: AccountId) -> Index { System::account_nonce(account)