mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-09 04:39:24 +00:00
Round out the runtime
Ensures the block's size limit is respected. Defines a policy for weights. While I'm unsure I want to commit to this forever, I do want to acknowledge it's valid and well-defined. Cleans up the `serai-runtime` crate a bit with further modules in the `wasm` folder.
This commit is contained in:
@@ -63,6 +63,11 @@ pub struct HeaderV1 {
|
|||||||
pub consensus_commitment: [u8; 32],
|
pub consensus_commitment: [u8; 32],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl HeaderV1 {
|
||||||
|
/// The size of a serialized V1 header.
|
||||||
|
pub const SIZE: usize = 8 + 32 + 8 + 32 + 32 + 32;
|
||||||
|
}
|
||||||
|
|
||||||
/// A header for a block.
|
/// A header for a block.
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, BorshSerialize, BorshDeserialize)]
|
#[derive(Clone, Copy, PartialEq, Eq, Debug, BorshSerialize, BorshDeserialize)]
|
||||||
pub enum Header {
|
pub enum Header {
|
||||||
@@ -71,6 +76,9 @@ pub enum Header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Header {
|
impl Header {
|
||||||
|
/// The size of a serialized header.
|
||||||
|
pub const SIZE: usize = 1 + HeaderV1::SIZE;
|
||||||
|
|
||||||
/// Get the hash of the header.
|
/// Get the hash of the header.
|
||||||
pub fn number(&self) -> u64 {
|
pub fn number(&self) -> u64 {
|
||||||
match self {
|
match self {
|
||||||
@@ -109,8 +117,8 @@ impl Header {
|
|||||||
|
|
||||||
/// A block.
|
/// A block.
|
||||||
///
|
///
|
||||||
/// This does not guarantee consistency. The header's `transactions_root` may not match the
|
/// This does not guarantee consistency nor validity. The header's `transactions_root` may not
|
||||||
/// contained transactions.
|
/// match the contained transactions, among other ill effects.
|
||||||
#[derive(Clone, PartialEq, Eq, Debug, BorshSerialize, BorshDeserialize)]
|
#[derive(Clone, PartialEq, Eq, Debug, BorshSerialize, BorshDeserialize)]
|
||||||
pub struct Block {
|
pub struct Block {
|
||||||
/// The block's header.
|
/// The block's header.
|
||||||
@@ -119,6 +127,13 @@ pub struct Block {
|
|||||||
pub transactions: Vec<Transaction>,
|
pub transactions: Vec<Transaction>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Block {
|
||||||
|
/// The size limit for a block.
|
||||||
|
///
|
||||||
|
/// This is not enforced upon deserialization. Be careful accordingly.
|
||||||
|
pub const SIZE_LIMIT: usize = 1024 * 1024;
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "substrate")]
|
#[cfg(feature = "substrate")]
|
||||||
mod substrate {
|
mod substrate {
|
||||||
use core::fmt::Debug;
|
use core::fmt::Debug;
|
||||||
@@ -133,7 +148,7 @@ mod substrate {
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
// Add `serde` implementations which treat self as a `Vec<u8>`
|
// Add `serde` implementations which treat `self` as a `Vec<u8>`
|
||||||
impl sp_core::serde::Serialize for Transaction {
|
impl sp_core::serde::Serialize for Transaction {
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where
|
where
|
||||||
|
|||||||
@@ -279,12 +279,13 @@ mod substrate {
|
|||||||
/// The implicit context to verify transactions with.
|
/// The implicit context to verify transactions with.
|
||||||
fn implicit_context() -> ImplicitContext;
|
fn implicit_context() -> ImplicitContext;
|
||||||
|
|
||||||
|
/// The size of the current block.
|
||||||
|
fn current_block_size(&self) -> usize;
|
||||||
|
|
||||||
/// If a block is present in the blockchain.
|
/// If a block is present in the blockchain.
|
||||||
fn block_is_present_in_blockchain(&self, hash: &BlockHash) -> bool;
|
fn block_is_present_in_blockchain(&self, hash: &BlockHash) -> bool;
|
||||||
/// The time embedded into the current block.
|
/// The time embedded into the current block.
|
||||||
///
|
fn current_time(&self) -> u64;
|
||||||
/// Returns `None` if the time has yet to be set.
|
|
||||||
fn current_time(&self) -> Option<u64>;
|
|
||||||
/// Get the next nonce for an account.
|
/// Get the next nonce for an account.
|
||||||
fn next_nonce(&self, signer: &SeraiAddress) -> u32;
|
fn next_nonce(&self, signer: &SeraiAddress) -> u32;
|
||||||
/// If the signer can pay the SRI fee.
|
/// If the signer can pay the SRI fee.
|
||||||
@@ -295,7 +296,7 @@ mod substrate {
|
|||||||
) -> Result<(), TransactionValidityError>;
|
) -> Result<(), TransactionValidityError>;
|
||||||
|
|
||||||
/// Begin execution of a transaction.
|
/// Begin execution of a transaction.
|
||||||
fn start_transaction(&self);
|
fn start_transaction(&self, len: usize);
|
||||||
/// Consume the next nonce for an account.
|
/// Consume the next nonce for an account.
|
||||||
///
|
///
|
||||||
/// This MUST NOT be called if the next nonce is `u32::MAX`. The caller MAY panic in that case.
|
/// This MUST NOT be called if the next nonce is `u32::MAX`. The caller MAY panic in that case.
|
||||||
@@ -390,9 +391,14 @@ mod substrate {
|
|||||||
impl<Context: TransactionContext> TransactionWithContext<Context> {
|
impl<Context: TransactionContext> TransactionWithContext<Context> {
|
||||||
fn validate_except_fee<V: ValidateUnsigned<Call = Context::RuntimeCall>>(
|
fn validate_except_fee<V: ValidateUnsigned<Call = Context::RuntimeCall>>(
|
||||||
&self,
|
&self,
|
||||||
|
len: usize,
|
||||||
source: TransactionSource,
|
source: TransactionSource,
|
||||||
mempool_priority_if_signed: u64,
|
mempool_priority_if_signed: u64,
|
||||||
) -> TransactionValidity {
|
) -> TransactionValidity {
|
||||||
|
if self.1.current_block_size().saturating_add(len) > crate::Block::SIZE_LIMIT {
|
||||||
|
Err(TransactionValidityError::Invalid(InvalidTransaction::ExhaustsResources))?;
|
||||||
|
}
|
||||||
|
|
||||||
match &self.0 {
|
match &self.0 {
|
||||||
Transaction::Unsigned { call } => {
|
Transaction::Unsigned { call } => {
|
||||||
let ValidTransaction { priority: _, requires, provides, longevity: _, propagate: _ } =
|
let ValidTransaction { priority: _, requires, provides, longevity: _, propagate: _ } =
|
||||||
@@ -417,13 +423,8 @@ mod substrate {
|
|||||||
Err(TransactionValidityError::Unknown(UnknownTransaction::CannotLookup))?;
|
Err(TransactionValidityError::Unknown(UnknownTransaction::CannotLookup))?;
|
||||||
}
|
}
|
||||||
if let Some(include_by) = *include_by {
|
if let Some(include_by) = *include_by {
|
||||||
if let Some(current_time) = self.1.current_time() {
|
if self.1.current_time() >= u64::from(include_by) {
|
||||||
if current_time >= u64::from(include_by) {
|
// Since this transaction has a time bound which has passed, error
|
||||||
// Since this transaction has a time bound which has passed, error
|
|
||||||
Err(TransactionValidityError::Invalid(InvalidTransaction::Stale))?;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Since this transaction has a time bound, yet we don't know the time, error
|
|
||||||
Err(TransactionValidityError::Invalid(InvalidTransaction::Stale))?;
|
Err(TransactionValidityError::Invalid(InvalidTransaction::Stale))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -471,7 +472,7 @@ mod substrate {
|
|||||||
&self,
|
&self,
|
||||||
source: TransactionSource,
|
source: TransactionSource,
|
||||||
info: &DispatchInfo,
|
info: &DispatchInfo,
|
||||||
_len: usize,
|
len: usize,
|
||||||
) -> TransactionValidity {
|
) -> TransactionValidity {
|
||||||
let mempool_priority_if_signed = match &self.0 {
|
let mempool_priority_if_signed = match &self.0 {
|
||||||
Transaction::Unsigned { .. } => {
|
Transaction::Unsigned { .. } => {
|
||||||
@@ -493,19 +494,19 @@ mod substrate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
self.validate_except_fee::<V>(source, mempool_priority_if_signed)
|
self.validate_except_fee::<V>(len, source, mempool_priority_if_signed)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply<V: ValidateUnsigned<Call = Context::RuntimeCall>>(
|
fn apply<V: ValidateUnsigned<Call = Context::RuntimeCall>>(
|
||||||
self,
|
self,
|
||||||
_info: &DispatchInfo,
|
_info: &DispatchInfo,
|
||||||
_len: usize,
|
len: usize,
|
||||||
) -> sp_runtime::ApplyExtrinsicResultWithInfo<PostDispatchInfo> {
|
) -> sp_runtime::ApplyExtrinsicResultWithInfo<PostDispatchInfo> {
|
||||||
// We use 0 for the mempool priority, as this is no longer in the mempool so it's irrelevant
|
// We use 0 for the mempool priority, as this is no longer in the mempool so it's irrelevant
|
||||||
self.validate_except_fee::<V>(TransactionSource::InBlock, 0)?;
|
self.validate_except_fee::<V>(len, TransactionSource::InBlock, 0)?;
|
||||||
|
|
||||||
// Start the transaction
|
// Start the transaction
|
||||||
self.1.start_transaction();
|
self.1.start_transaction(len);
|
||||||
|
|
||||||
let transaction_hash = self.0.hash();
|
let transaction_hash = self.0.hash();
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ impl frame_system::Config for Test {
|
|||||||
type AccountId = sp_core::sr25519::Public;
|
type AccountId = sp_core::sr25519::Public;
|
||||||
type Lookup = frame_support::sp_runtime::traits::IdentityLookup<Self::AccountId>;
|
type Lookup = frame_support::sp_runtime::traits::IdentityLookup<Self::AccountId>;
|
||||||
type Block = frame_system::mocking::MockBlock<Test>;
|
type Block = frame_system::mocking::MockBlock<Test>;
|
||||||
|
type BlockLength = serai_core_pallet::Limits;
|
||||||
|
type BlockWeights = serai_core_pallet::Limits;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive_impl(pallet_timestamp::config_preludes::TestDefaultConfig)]
|
#[derive_impl(pallet_timestamp::config_preludes::TestDefaultConfig)]
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ pub type CoinsEvent = serai_abi::coins::Event;
|
|||||||
#[test]
|
#[test]
|
||||||
fn mint() {
|
fn mint() {
|
||||||
new_test_ext().execute_with(|| {
|
new_test_ext().execute_with(|| {
|
||||||
Core::start_transaction();
|
Core::start_transaction(0);
|
||||||
|
|
||||||
// minting u64::MAX should work
|
// minting u64::MAX should work
|
||||||
let coin = Coin::Serai;
|
let coin = Coin::Serai;
|
||||||
@@ -51,7 +51,7 @@ fn mint() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn burn_with_instruction() {
|
fn burn_with_instruction() {
|
||||||
new_test_ext().execute_with(|| {
|
new_test_ext().execute_with(|| {
|
||||||
Core::start_transaction();
|
Core::start_transaction(0);
|
||||||
|
|
||||||
// mint some coin
|
// mint some coin
|
||||||
let coin = Coin::External(ExternalCoin::Bitcoin);
|
let coin = Coin::External(ExternalCoin::Bitcoin);
|
||||||
@@ -106,7 +106,7 @@ fn burn_with_instruction() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn transfer() {
|
fn transfer() {
|
||||||
new_test_ext().execute_with(|| {
|
new_test_ext().execute_with(|| {
|
||||||
Core::start_transaction();
|
Core::start_transaction(0);
|
||||||
|
|
||||||
// mint some coin
|
// mint some coin
|
||||||
let coin = Coin::External(ExternalCoin::Bitcoin);
|
let coin = Coin::External(ExternalCoin::Bitcoin);
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ extern crate alloc;
|
|||||||
|
|
||||||
use frame_support::traits::{PreInherents, PostTransactions};
|
use frame_support::traits::{PreInherents, PostTransactions};
|
||||||
|
|
||||||
|
mod limits;
|
||||||
|
pub use limits::Limits;
|
||||||
|
|
||||||
mod iumt;
|
mod iumt;
|
||||||
pub use iumt::*;
|
pub use iumt::*;
|
||||||
|
|
||||||
@@ -83,7 +86,8 @@ pub mod pallet {
|
|||||||
|
|
||||||
#[pallet::config]
|
#[pallet::config]
|
||||||
pub trait Config:
|
pub trait Config:
|
||||||
frame_system::Config<Hash: Into<[u8; 32]>> + pallet_timestamp::Config<Moment = u64>
|
frame_system::Config<Hash: Into<[u8; 32]>, BlockLength = Limits, BlockWeights = Limits>
|
||||||
|
+ pallet_timestamp::Config<Moment = u64>
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,7 +124,7 @@ pub mod pallet {
|
|||||||
BlockTransactionsCommitmentMerkle::<T>::new_expecting_none();
|
BlockTransactionsCommitmentMerkle::<T>::new_expecting_none();
|
||||||
BlockEventsCommitmentMerkle::<T>::new_expecting_none();
|
BlockEventsCommitmentMerkle::<T>::new_expecting_none();
|
||||||
|
|
||||||
Self::start_transaction();
|
Self::start_transaction(0);
|
||||||
<_>::build(config);
|
<_>::build(config);
|
||||||
Self::end_transaction([0; 32]);
|
Self::end_transaction([0; 32]);
|
||||||
|
|
||||||
@@ -130,7 +134,15 @@ pub mod pallet {
|
|||||||
/// The code to run when beginning execution of a transaction.
|
/// The code to run when beginning execution of a transaction.
|
||||||
///
|
///
|
||||||
/// The caller MUST ensure two transactions aren't simultaneously started.
|
/// The caller MUST ensure two transactions aren't simultaneously started.
|
||||||
pub fn start_transaction() {
|
pub fn start_transaction(len: usize) {
|
||||||
|
{
|
||||||
|
let existing_len = frame_system::AllExtrinsicsLen::<T>::get().unwrap_or(0);
|
||||||
|
let new_len = existing_len.saturating_add(u32::try_from(len).unwrap_or(u32::MAX));
|
||||||
|
// We panic here as this should've been caught earlier during validation
|
||||||
|
assert!(new_len <= u32::try_from(serai_abi::Block::SIZE_LIMIT).unwrap());
|
||||||
|
frame_system::AllExtrinsicsLen::<T>::set(Some(new_len));
|
||||||
|
}
|
||||||
|
|
||||||
TransactionEventsMerkle::<T>::new_expecting_none();
|
TransactionEventsMerkle::<T>::new_expecting_none();
|
||||||
Self::deposit_event(Event::BeginTransaction);
|
Self::deposit_event(Event::BeginTransaction);
|
||||||
}
|
}
|
||||||
@@ -192,7 +204,21 @@ impl<T: Config> PreInherents for StartOfBlock<T> {
|
|||||||
BlockTransactionsCommitmentMerkle::<T>::new_expecting_none();
|
BlockTransactionsCommitmentMerkle::<T>::new_expecting_none();
|
||||||
BlockEventsCommitmentMerkle::<T>::new_expecting_none();
|
BlockEventsCommitmentMerkle::<T>::new_expecting_none();
|
||||||
|
|
||||||
Pallet::<T>::start_transaction();
|
/*
|
||||||
|
We assign the implicit transaction with the block the length of the block itself: its
|
||||||
|
header's length and the length of the length-prefix for the list of transactions.
|
||||||
|
|
||||||
|
The length-prefix will be a little-endian `u32`, as `Block` will be borsh-serialized
|
||||||
|
(https://borsh.io).
|
||||||
|
|
||||||
|
The length of each actual transaction is expected to be accurate as the SCALE implementation
|
||||||
|
defers to the `borsh` serialization.
|
||||||
|
*/
|
||||||
|
assert!(
|
||||||
|
frame_system::AllExtrinsicsLen::<T>::get().is_none(),
|
||||||
|
"AllExtrinsicsLen wasn't killed at the end of the last block"
|
||||||
|
);
|
||||||
|
Pallet::<T>::start_transaction(serai_abi::Header::SIZE + 4);
|
||||||
|
|
||||||
// Handle the `SeraiPreExecutionDigest`
|
// Handle the `SeraiPreExecutionDigest`
|
||||||
/*
|
/*
|
||||||
@@ -220,7 +246,7 @@ impl<T: Config> PreInherents for StartOfBlock<T> {
|
|||||||
pub struct EndOfBlock<T: Config>(PhantomData<T>);
|
pub struct EndOfBlock<T: Config>(PhantomData<T>);
|
||||||
impl<T: Config> PostTransactions for EndOfBlock<T> {
|
impl<T: Config> PostTransactions for EndOfBlock<T> {
|
||||||
fn post_transactions() {
|
fn post_transactions() {
|
||||||
Pallet::<T>::start_transaction();
|
Pallet::<T>::start_transaction(0);
|
||||||
|
|
||||||
// Other modules' `PostTransactions`
|
// Other modules' `PostTransactions`
|
||||||
|
|
||||||
@@ -229,6 +255,8 @@ impl<T: Config> PostTransactions for EndOfBlock<T> {
|
|||||||
end_of_block_transaction_hash[.. 16].copy_from_slice(&[0xff; 16]);
|
end_of_block_transaction_hash[.. 16].copy_from_slice(&[0xff; 16]);
|
||||||
Pallet::<T>::end_transaction(end_of_block_transaction_hash);
|
Pallet::<T>::end_transaction(end_of_block_transaction_hash);
|
||||||
|
|
||||||
|
frame_system::AllExtrinsicsLen::<T>::kill();
|
||||||
|
|
||||||
use serai_abi::SeraiExecutionDigest;
|
use serai_abi::SeraiExecutionDigest;
|
||||||
frame_system::Pallet::<T>::deposit_log(
|
frame_system::Pallet::<T>::deposit_log(
|
||||||
frame_support::sp_runtime::generic::DigestItem::Consensus(
|
frame_support::sp_runtime::generic::DigestItem::Consensus(
|
||||||
|
|||||||
34
substrate/core/src/limits.rs
Normal file
34
substrate/core/src/limits.rs
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
use sp_core::Get;
|
||||||
|
use frame_support::weights::Weight;
|
||||||
|
use frame_system::limits::{BlockLength, BlockWeights};
|
||||||
|
|
||||||
|
/// The limits for the Serai protocol.
|
||||||
|
pub struct Limits;
|
||||||
|
impl Get<BlockLength> for Limits {
|
||||||
|
fn get() -> BlockLength {
|
||||||
|
/*
|
||||||
|
We do not reserve an allocation for mandatory/operational transactions, assuming they'll be
|
||||||
|
prioritized in the mempool. This does technically give block producers an inventive to
|
||||||
|
misbehave by on-purposely favoring paying non-operational transactions over operational
|
||||||
|
transactions, but ensures the entire block is available to the transactions actually present
|
||||||
|
in the mempool.
|
||||||
|
*/
|
||||||
|
BlockLength::max(u32::try_from(serai_abi::Block::SIZE_LIMIT).unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Get<BlockWeights> for Limits {
|
||||||
|
fn get() -> BlockWeights {
|
||||||
|
/*
|
||||||
|
While Serai does limit the size of a block, every transaction is expected to operate in
|
||||||
|
complexity constant to the current state size, regardless of what the state is. Accordingly,
|
||||||
|
the most efficient set of transactions (basic transfers?) is expected to be within an order
|
||||||
|
of magnitude of the most expensive transactions (multi-pool swaps?).
|
||||||
|
|
||||||
|
Instead of engaging with the complexity within the consensus protocol of metering both
|
||||||
|
bandwidth and computation, we do not define limits for weights. We do, however, still use the
|
||||||
|
weight system in order to determine fee rates and ensure prioritization to
|
||||||
|
computationally-cheaper transactions. That solely serves as mempool policy however.
|
||||||
|
*/
|
||||||
|
BlockWeights::simple_max(Weight::MAX)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,6 +25,8 @@ impl frame_system::Config for Test {
|
|||||||
type AccountId = sp_core::sr25519::Public;
|
type AccountId = sp_core::sr25519::Public;
|
||||||
type Lookup = frame_support::sp_runtime::traits::IdentityLookup<Self::AccountId>;
|
type Lookup = frame_support::sp_runtime::traits::IdentityLookup<Self::AccountId>;
|
||||||
type Block = frame_system::mocking::MockBlock<Test>;
|
type Block = frame_system::mocking::MockBlock<Test>;
|
||||||
|
type BlockLength = serai_core_pallet::Limits;
|
||||||
|
type BlockWeights = serai_core_pallet::Limits;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive_impl(pallet_timestamp::config_preludes::TestDefaultConfig)]
|
#[derive_impl(pallet_timestamp::config_preludes::TestDefaultConfig)]
|
||||||
|
|||||||
127
substrate/runtime/src/wasm/map.rs
Normal file
127
substrate/runtime/src/wasm/map.rs
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
use super::*;
|
||||||
|
|
||||||
|
impl From<Option<SeraiAddress>> for RuntimeOrigin {
|
||||||
|
fn from(signer: Option<SeraiAddress>) -> Self {
|
||||||
|
match signer {
|
||||||
|
None => RuntimeOrigin::none(),
|
||||||
|
Some(signer) => RuntimeOrigin::signed(signer.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<serai_abi::Call> for RuntimeCall {
|
||||||
|
fn from(call: serai_abi::Call) -> Self {
|
||||||
|
match call {
|
||||||
|
serai_abi::Call::Coins(call) => {
|
||||||
|
use serai_abi::coins::Call;
|
||||||
|
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 } => {
|
||||||
|
Scall::burn_with_instruction { instruction }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
serai_abi::Call::ValidatorSets(call) => {
|
||||||
|
use serai_abi::validator_sets::Call;
|
||||||
|
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;
|
||||||
|
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;
|
||||||
|
RuntimeCall::Dex(match call {
|
||||||
|
Call::add_liquidity {
|
||||||
|
external_coin,
|
||||||
|
sri_intended,
|
||||||
|
external_coin_intended,
|
||||||
|
sri_minimum,
|
||||||
|
external_coin_minimum,
|
||||||
|
} => serai_dex_pallet::Call::add_liquidity {
|
||||||
|
external_coin,
|
||||||
|
sri_intended,
|
||||||
|
external_coin_intended,
|
||||||
|
sri_minimum,
|
||||||
|
external_coin_minimum,
|
||||||
|
},
|
||||||
|
Call::transfer_liquidity { to, liquidity_tokens } => {
|
||||||
|
serai_dex_pallet::Call::transfer_liquidity { to, liquidity_tokens }
|
||||||
|
}
|
||||||
|
Call::remove_liquidity { liquidity_tokens, sri_minimum, external_coin_minimum } => {
|
||||||
|
serai_dex_pallet::Call::remove_liquidity {
|
||||||
|
liquidity_tokens,
|
||||||
|
sri_minimum,
|
||||||
|
external_coin_minimum,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Call::swap { coins_to_swap, minimum_to_receive } => {
|
||||||
|
serai_dex_pallet::Call::swap { coins_to_swap, minimum_to_receive }
|
||||||
|
}
|
||||||
|
Call::swap_for { coins_to_receive, maximum_to_swap } => {
|
||||||
|
serai_dex_pallet::Call::swap_for { coins_to_receive, maximum_to_swap }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
serai_abi::Call::GenesisLiquidity(call) => {
|
||||||
|
use serai_abi::genesis_liquidity::Call;
|
||||||
|
RuntimeCall::GenesisLiquidity(match call {
|
||||||
|
Call::oraclize_values { values, signature } => {
|
||||||
|
serai_genesis_liquidity_pallet::Call::oraclize_values { values, signature }
|
||||||
|
}
|
||||||
|
Call::transfer_genesis_liquidity { to, genesis_liquidity } => {
|
||||||
|
serai_genesis_liquidity_pallet::Call::transfer_genesis_liquidity {
|
||||||
|
to,
|
||||||
|
genesis_liquidity,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Call::remove_genesis_liquidity { genesis_liquidity } => {
|
||||||
|
serai_genesis_liquidity_pallet::Call::remove_genesis_liquidity { genesis_liquidity }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
serai_abi::Call::InInstructions(call) => {
|
||||||
|
use serai_abi::in_instructions::Call;
|
||||||
|
RuntimeCall::InInstructions(match call {
|
||||||
|
Call::execute_batch { batch } => {
|
||||||
|
serai_in_instructions_pallet::Call::execute_batch { batch }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use alloc::{borrow::Cow, vec, vec::Vec};
|
use alloc::{borrow::Cow, vec, vec::Vec};
|
||||||
|
|
||||||
use sp_core::{ConstU32, ConstU64, sr25519::Public};
|
use sp_core::{Get, ConstU32, ConstU64, sr25519::Public};
|
||||||
use sp_runtime::{
|
use sp_runtime::{
|
||||||
Perbill, Weight,
|
Perbill, Weight,
|
||||||
traits::{Header as _, Block as _},
|
traits::{Header as _, Block as _},
|
||||||
@@ -21,51 +21,10 @@ use serai_abi::{
|
|||||||
|
|
||||||
use serai_coins_pallet::{CoinsInstance, LiquidityTokensInstance};
|
use serai_coins_pallet::{CoinsInstance, LiquidityTokensInstance};
|
||||||
|
|
||||||
/// The lookup for a SeraiAddress -> Public.
|
/// Maps `serai_abi` types into the types expected within the Substrate runtime
|
||||||
pub struct Lookup;
|
mod map;
|
||||||
impl sp_runtime::traits::StaticLookup for Lookup {
|
/// The configuration for `frame_system`.
|
||||||
type Source = SeraiAddress;
|
mod system;
|
||||||
type Target = Public;
|
|
||||||
fn lookup(source: SeraiAddress) -> Result<Public, sp_runtime::traits::LookupError> {
|
|
||||||
Ok(source.into())
|
|
||||||
}
|
|
||||||
fn unlookup(source: Public) -> SeraiAddress {
|
|
||||||
source.into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Remove
|
|
||||||
#[sp_version::runtime_version]
|
|
||||||
pub const VERSION: RuntimeVersion = RuntimeVersion {
|
|
||||||
spec_name: Cow::Borrowed("serai"),
|
|
||||||
impl_name: Cow::Borrowed("core"),
|
|
||||||
authoring_version: 0,
|
|
||||||
spec_version: 0,
|
|
||||||
impl_version: 0,
|
|
||||||
apis: RUNTIME_API_VERSIONS,
|
|
||||||
transaction_version: 0,
|
|
||||||
system_version: 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
frame_support::parameter_types! {
|
|
||||||
pub const Version: RuntimeVersion = VERSION;
|
|
||||||
|
|
||||||
// TODO
|
|
||||||
pub BlockLength: frame_system::limits::BlockLength =
|
|
||||||
frame_system::limits::BlockLength::max_with_normal_ratio(
|
|
||||||
100 * 1024,
|
|
||||||
Perbill::from_percent(75),
|
|
||||||
);
|
|
||||||
// TODO
|
|
||||||
pub BlockWeights: frame_system::limits::BlockWeights =
|
|
||||||
frame_system::limits::BlockWeights::with_sensible_defaults(
|
|
||||||
Weight::from_parts(
|
|
||||||
2u64 * frame_support::weights::constants::WEIGHT_REF_TIME_PER_SECOND,
|
|
||||||
u64::MAX,
|
|
||||||
),
|
|
||||||
Perbill::from_percent(75),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[frame_support::runtime]
|
#[frame_support::runtime]
|
||||||
mod runtime {
|
mod runtime {
|
||||||
@@ -113,45 +72,6 @@ mod runtime {
|
|||||||
pub type Grandpa = pallet_grandpa::Pallet<Runtime>;
|
pub type Grandpa = pallet_grandpa::Pallet<Runtime>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl frame_system::Config for Runtime {
|
|
||||||
type RuntimeEvent = RuntimeEvent;
|
|
||||||
type BaseCallFilter = frame_support::traits::Everything;
|
|
||||||
type BlockWeights = BlockWeights;
|
|
||||||
type BlockLength = BlockLength;
|
|
||||||
type RuntimeOrigin = RuntimeOrigin;
|
|
||||||
type RuntimeCall = RuntimeCall;
|
|
||||||
type Nonce = u32;
|
|
||||||
type Hash = <Self::Block as sp_runtime::traits::Block>::Hash;
|
|
||||||
type Hashing = sp_runtime::traits::BlakeTwo256;
|
|
||||||
type AccountId = sp_core::sr25519::Public;
|
|
||||||
type Lookup = Lookup;
|
|
||||||
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 = ConstU64<1>;
|
|
||||||
type DbWeight = frame_support::weights::constants::RocksDbWeight;
|
|
||||||
type Version = Version;
|
|
||||||
type PalletInfo = PalletInfo;
|
|
||||||
type AccountData = ();
|
|
||||||
type OnNewAccount = ();
|
|
||||||
type OnKilledAccount = ();
|
|
||||||
// We use the default weights as we never expose/call any of these methods
|
|
||||||
type SystemWeightInfo = ();
|
|
||||||
// We also don't use the provided extensions framework
|
|
||||||
type ExtensionsWeightInfo = ();
|
|
||||||
// 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 = ConstU32<{ u32::MAX }>;
|
|
||||||
// No migrations set
|
|
||||||
type SingleBlockMigrations = ();
|
|
||||||
type MultiBlockMigrator = ();
|
|
||||||
|
|
||||||
type PreInherents = serai_core_pallet::StartOfBlock<Runtime>;
|
|
||||||
type PostInherents = ();
|
|
||||||
type PostTransactions = serai_core_pallet::EndOfBlock<Runtime>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl serai_core_pallet::Config for Runtime {}
|
impl serai_core_pallet::Config for Runtime {}
|
||||||
|
|
||||||
impl serai_coins_pallet::Config<CoinsInstance> for Runtime {
|
impl serai_coins_pallet::Config<CoinsInstance> for Runtime {
|
||||||
@@ -237,137 +157,6 @@ impl pallet_grandpa::Config for Runtime {
|
|||||||
type EquivocationReportSystem = ();
|
type EquivocationReportSystem = ();
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Option<SeraiAddress>> for RuntimeOrigin {
|
|
||||||
fn from(signer: Option<SeraiAddress>) -> Self {
|
|
||||||
match signer {
|
|
||||||
None => RuntimeOrigin::none(),
|
|
||||||
Some(signer) => RuntimeOrigin::signed(signer.into()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<serai_abi::Call> for RuntimeCall {
|
|
||||||
fn from(call: serai_abi::Call) -> Self {
|
|
||||||
match call {
|
|
||||||
serai_abi::Call::Coins(call) => {
|
|
||||||
use serai_abi::coins::Call;
|
|
||||||
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 } => {
|
|
||||||
Scall::burn_with_instruction { instruction }
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
serai_abi::Call::ValidatorSets(call) => {
|
|
||||||
use serai_abi::validator_sets::Call;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
match call {
|
|
||||||
Call::add_liquidity {
|
|
||||||
external_coin,
|
|
||||||
sri_intended,
|
|
||||||
external_coin_intended,
|
|
||||||
sri_minimum,
|
|
||||||
external_coin_minimum,
|
|
||||||
} => RuntimeCall::Dex(serai_dex_pallet::Call::add_liquidity {
|
|
||||||
external_coin,
|
|
||||||
sri_intended,
|
|
||||||
external_coin_intended,
|
|
||||||
sri_minimum,
|
|
||||||
external_coin_minimum,
|
|
||||||
}),
|
|
||||||
Call::transfer_liquidity { to, liquidity_tokens } => {
|
|
||||||
RuntimeCall::Dex(serai_dex_pallet::Call::transfer_liquidity { to, liquidity_tokens })
|
|
||||||
}
|
|
||||||
Call::remove_liquidity { liquidity_tokens, sri_minimum, external_coin_minimum } => {
|
|
||||||
RuntimeCall::Dex(serai_dex_pallet::Call::remove_liquidity {
|
|
||||||
liquidity_tokens,
|
|
||||||
sri_minimum,
|
|
||||||
external_coin_minimum,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Call::swap { coins_to_swap, minimum_to_receive } => {
|
|
||||||
RuntimeCall::Dex(serai_dex_pallet::Call::swap { coins_to_swap, minimum_to_receive })
|
|
||||||
}
|
|
||||||
Call::swap_for { coins_to_receive, maximum_to_swap } => {
|
|
||||||
RuntimeCall::Dex(serai_dex_pallet::Call::swap_for { coins_to_receive, maximum_to_swap })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
serai_abi::Call::GenesisLiquidity(call) => {
|
|
||||||
use serai_abi::genesis_liquidity::Call;
|
|
||||||
match call {
|
|
||||||
Call::oraclize_values { values, signature } => {
|
|
||||||
RuntimeCall::GenesisLiquidity(serai_genesis_liquidity_pallet::Call::oraclize_values {
|
|
||||||
values,
|
|
||||||
signature,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Call::transfer_genesis_liquidity { to, genesis_liquidity } => {
|
|
||||||
RuntimeCall::GenesisLiquidity(
|
|
||||||
serai_genesis_liquidity_pallet::Call::transfer_genesis_liquidity {
|
|
||||||
to,
|
|
||||||
genesis_liquidity,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Call::remove_genesis_liquidity { genesis_liquidity } => RuntimeCall::GenesisLiquidity(
|
|
||||||
serai_genesis_liquidity_pallet::Call::remove_genesis_liquidity { genesis_liquidity },
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
serai_abi::Call::InInstructions(call) => {
|
|
||||||
use serai_abi::in_instructions::Call;
|
|
||||||
match call {
|
|
||||||
Call::execute_batch { batch } => {
|
|
||||||
RuntimeCall::InInstructions(serai_in_instructions_pallet::Call::execute_batch { batch })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type Executive = frame_executive::Executive<Runtime, Block, Context, Runtime, AllPalletsWithSystem>;
|
type Executive = frame_executive::Executive<Runtime, Block, Context, Runtime, AllPalletsWithSystem>;
|
||||||
|
|
||||||
const PRIMARY_PROBABILITY: (u64, u64) = (1, 4);
|
const PRIMARY_PROBABILITY: (u64, u64) = (1, 4);
|
||||||
@@ -411,7 +200,7 @@ sp_api::impl_runtime_apis! {
|
|||||||
|
|
||||||
impl sp_api::Core<Block> for Runtime {
|
impl sp_api::Core<Block> for Runtime {
|
||||||
fn version() -> RuntimeVersion {
|
fn version() -> RuntimeVersion {
|
||||||
VERSION
|
<Runtime as frame_system::Config>::Version::get()
|
||||||
}
|
}
|
||||||
fn initialize_block(header: &Header) -> sp_runtime::ExtrinsicInclusionMode {
|
fn initialize_block(header: &Header) -> sp_runtime::ExtrinsicInclusionMode {
|
||||||
Executive::initialize_block(header)
|
Executive::initialize_block(header)
|
||||||
@@ -667,13 +456,19 @@ impl serai_abi::TransactionContext for Context {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The size of the current block.
|
||||||
|
fn current_block_size(&self) -> usize {
|
||||||
|
let current_block_size = frame_system::AllExtrinsicsLen::<Runtime>::get().unwrap_or(0);
|
||||||
|
usize::try_from(current_block_size).unwrap_or(usize::MAX)
|
||||||
|
}
|
||||||
|
|
||||||
/// If a block is present in the blockchain.
|
/// If a block is present in the blockchain.
|
||||||
fn block_is_present_in_blockchain(&self, hash: &serai_abi::primitives::BlockHash) -> bool {
|
fn block_is_present_in_blockchain(&self, hash: &serai_abi::primitives::BlockHash) -> bool {
|
||||||
serai_core_pallet::Pallet::<Runtime>::block_exists(hash)
|
serai_core_pallet::Pallet::<Runtime>::block_exists(hash)
|
||||||
}
|
}
|
||||||
/// The time embedded into the current block.
|
/// The time embedded into the current block.
|
||||||
fn current_time(&self) -> Option<u64> {
|
fn current_time(&self) -> u64 {
|
||||||
todo!("TODO")
|
pallet_timestamp::Pallet::<Runtime>::get()
|
||||||
}
|
}
|
||||||
/// Get the next nonce for an account.
|
/// Get the next nonce for an account.
|
||||||
fn next_nonce(&self, signer: &SeraiAddress) -> u32 {
|
fn next_nonce(&self, signer: &SeraiAddress) -> u32 {
|
||||||
@@ -695,8 +490,8 @@ impl serai_abi::TransactionContext for Context {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_transaction(&self) {
|
fn start_transaction(&self, len: usize) {
|
||||||
Core::start_transaction()
|
Core::start_transaction(len)
|
||||||
}
|
}
|
||||||
fn consume_next_nonce(&self, signer: &SeraiAddress) {
|
fn consume_next_nonce(&self, signer: &SeraiAddress) {
|
||||||
serai_core_pallet::Pallet::<Runtime>::consume_next_nonce(signer)
|
serai_core_pallet::Pallet::<Runtime>::consume_next_nonce(signer)
|
||||||
@@ -726,26 +521,7 @@ impl serai_abi::TransactionContext for Context {
|
|||||||
/* TODO
|
/* TODO
|
||||||
use validator_sets::MembershipProof;
|
use validator_sets::MembershipProof;
|
||||||
|
|
||||||
const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
|
|
||||||
|
|
||||||
parameter_types! {
|
|
||||||
pub const Version: RuntimeVersion = VERSION;
|
|
||||||
|
|
||||||
pub const SS58Prefix: u8 = 42; // TODO: Remove for Bech32m
|
|
||||||
|
|
||||||
// 1 MB block size limit
|
|
||||||
pub BlockLength: system::limits::BlockLength =
|
|
||||||
system::limits::BlockLength::max_with_normal_ratio(BLOCK_SIZE, NORMAL_DISPATCH_RATIO);
|
|
||||||
pub BlockWeights: system::limits::BlockWeights =
|
|
||||||
system::limits::BlockWeights::with_sensible_defaults(
|
|
||||||
Weight::from_parts(2u64 * WEIGHT_REF_TIME_PER_SECOND, u64::MAX),
|
|
||||||
NORMAL_DISPATCH_RATIO,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl timestamp::Config for Runtime {
|
impl timestamp::Config for Runtime {
|
||||||
type Moment = u64;
|
|
||||||
type OnTimestampSet = Babe;
|
|
||||||
type MinimumPeriod = ConstU64<{ (TARGET_BLOCK_TIME * 1000) / 2 }>;
|
type MinimumPeriod = ConstU64<{ (TARGET_BLOCK_TIME * 1000) / 2 }>;
|
||||||
type WeightInfo = ();
|
type WeightInfo = ();
|
||||||
}
|
}
|
||||||
@@ -782,14 +558,6 @@ impl signals::Config for Runtime {
|
|||||||
type RetirementLockInDuration = ConstU32<{ (2 * 7 * 24 * 60 * 60) / (TARGET_BLOCK_TIME as u32) }>;
|
type RetirementLockInDuration = ConstU32<{ (2 * 7 * 24 * 60 * 60) / (TARGET_BLOCK_TIME as u32) }>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl in_instructions::Config for Runtime {
|
|
||||||
type RuntimeEvent = RuntimeEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl genesis_liquidity::Config for Runtime {
|
|
||||||
type RuntimeEvent = RuntimeEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl emissions::Config for Runtime {
|
impl emissions::Config for Runtime {
|
||||||
type RuntimeEvent = RuntimeEvent;
|
type RuntimeEvent = RuntimeEvent;
|
||||||
}
|
}
|
||||||
@@ -818,54 +586,4 @@ impl pallet_authorship::Config for Runtime {
|
|||||||
|
|
||||||
/// Longevity of an offence report.
|
/// Longevity of an offence report.
|
||||||
pub type ReportLongevity = <Runtime as pallet_babe::Config>::EpochDuration;
|
pub type ReportLongevity = <Runtime as pallet_babe::Config>::EpochDuration;
|
||||||
|
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
#[macro_use]
|
|
||||||
extern crate frame_benchmarking;
|
|
||||||
|
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
mod benches {
|
|
||||||
define_benchmarks!(
|
|
||||||
[frame_benchmarking, BaselineBench::<Runtime>]
|
|
||||||
|
|
||||||
[system, SystemBench::<Runtime>]
|
|
||||||
|
|
||||||
[balances, Balances]
|
|
||||||
|
|
||||||
[babe, Babe]
|
|
||||||
[grandpa, Grandpa]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
sp_api::impl_runtime_apis! {
|
|
||||||
impl validator_sets::ValidatorSetsApi<Block> for Runtime {
|
|
||||||
fn external_network_key(network: ExternalNetworkId) -> Option<Vec<u8>> {
|
|
||||||
ValidatorSets::external_network_key(network)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl dex::DexApi<Block> for Runtime {
|
|
||||||
fn quote_price_exact_tokens_for_tokens(
|
|
||||||
coin1: Coin,
|
|
||||||
coin2: Coin,
|
|
||||||
amount: SubstrateAmount,
|
|
||||||
include_fee: bool
|
|
||||||
) -> Option<SubstrateAmount> {
|
|
||||||
Dex::quote_price_exact_tokens_for_tokens(coin1, coin2, amount, include_fee)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn quote_price_tokens_for_exact_tokens(
|
|
||||||
coin1: Coin,
|
|
||||||
coin2: Coin,
|
|
||||||
amount: SubstrateAmount,
|
|
||||||
include_fee: bool
|
|
||||||
) -> Option<SubstrateAmount> {
|
|
||||||
Dex::quote_price_tokens_for_exact_tokens(coin1, coin2, amount, include_fee)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_reserves(coin1: Coin, coin2: Coin) -> Option<(SubstrateAmount, SubstrateAmount)> {
|
|
||||||
Dex::get_reserves(&coin1, &coin2).ok()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
|
|||||||
95
substrate/runtime/src/wasm/system.rs
Normal file
95
substrate/runtime/src/wasm/system.rs
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
use super::*;
|
||||||
|
|
||||||
|
/// The lookup for a SeraiAddress -> Public.
|
||||||
|
pub struct Lookup;
|
||||||
|
impl sp_runtime::traits::StaticLookup for Lookup {
|
||||||
|
type Source = SeraiAddress;
|
||||||
|
type Target = Public;
|
||||||
|
fn lookup(source: SeraiAddress) -> Result<Public, sp_runtime::traits::LookupError> {
|
||||||
|
Ok(source.into())
|
||||||
|
}
|
||||||
|
fn unlookup(source: Public) -> SeraiAddress {
|
||||||
|
source.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The runtime version.
|
||||||
|
pub struct Version;
|
||||||
|
// TODO: Are we reasonably able to prune `RuntimeVersion` from Substrate?
|
||||||
|
impl Get<RuntimeVersion> for Version {
|
||||||
|
fn get() -> RuntimeVersion {
|
||||||
|
#[sp_version::runtime_version]
|
||||||
|
pub const VERSION: RuntimeVersion = RuntimeVersion {
|
||||||
|
spec_name: Cow::Borrowed("serai"),
|
||||||
|
impl_name: Cow::Borrowed("core"),
|
||||||
|
authoring_version: 0,
|
||||||
|
spec_version: 0,
|
||||||
|
impl_version: 0,
|
||||||
|
apis: RUNTIME_API_VERSIONS,
|
||||||
|
transaction_version: 0,
|
||||||
|
system_version: 0,
|
||||||
|
};
|
||||||
|
VERSION
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl frame_system::Config for Runtime {
|
||||||
|
type RuntimeOrigin = RuntimeOrigin;
|
||||||
|
type RuntimeCall = RuntimeCall;
|
||||||
|
type RuntimeEvent = RuntimeEvent;
|
||||||
|
type PalletInfo = PalletInfo;
|
||||||
|
|
||||||
|
type Hashing = sp_runtime::traits::BlakeTwo256;
|
||||||
|
type Hash = <Self::Block as sp_runtime::traits::Block>::Hash;
|
||||||
|
|
||||||
|
type Block = Block;
|
||||||
|
type AccountId = sp_core::sr25519::Public;
|
||||||
|
type Lookup = Lookup;
|
||||||
|
type Nonce = u32;
|
||||||
|
|
||||||
|
type PreInherents = serai_core_pallet::StartOfBlock<Runtime>;
|
||||||
|
type PostInherents = ();
|
||||||
|
type PostTransactions = serai_core_pallet::EndOfBlock<Runtime>;
|
||||||
|
|
||||||
|
/*
|
||||||
|
We do not globally filter the types of calls which may be performed. Instead, our ABI only
|
||||||
|
exposes the calls we want exposed, and each call individually errors if it's called when it
|
||||||
|
shouldn't be.
|
||||||
|
*/
|
||||||
|
type BaseCallFilter = frame_support::traits::Everything;
|
||||||
|
|
||||||
|
/*
|
||||||
|
We do not have `frame_system` track historical block hashes by their block number. Instead,
|
||||||
|
`serai_core_pallet` populates a hash set (map of `[u8; 32] -> ()`) of all historical block's
|
||||||
|
hashes within itself.
|
||||||
|
|
||||||
|
The usage of `1` here is solely as `frame_system` requires it be at least `1`.
|
||||||
|
*/
|
||||||
|
type BlockHashCount = ConstU64<1>;
|
||||||
|
|
||||||
|
type Version = Version;
|
||||||
|
type BlockLength = serai_core_pallet::Limits;
|
||||||
|
type BlockWeights = serai_core_pallet::Limits;
|
||||||
|
// We assume `serai-node` will be run using the RocksDB backend
|
||||||
|
type DbWeight = frame_support::weights::constants::RocksDbWeight;
|
||||||
|
/*
|
||||||
|
Serai does not expose `frame_system::Call` nor does it use transaction extensions. We
|
||||||
|
accordingly have no consequence to using the default weights for these accordingly.
|
||||||
|
*/
|
||||||
|
type SystemWeightInfo = ();
|
||||||
|
type ExtensionsWeightInfo = ();
|
||||||
|
|
||||||
|
// We also don't use `frame_system`'s account system at all, leaving us to bottom these out.
|
||||||
|
type AccountData = ();
|
||||||
|
type MaxConsumers = ConstU32<{ u32::MAX }>;
|
||||||
|
type OnNewAccount = ();
|
||||||
|
type OnKilledAccount = ();
|
||||||
|
|
||||||
|
// Serai does perform any 'on-chain upgrades' to ensure upgrades are opted into by the entity
|
||||||
|
// running this node and accordingly consented to
|
||||||
|
type OnSetCode = ();
|
||||||
|
|
||||||
|
// We do not have any migrations declared
|
||||||
|
type SingleBlockMigrations = ();
|
||||||
|
type MultiBlockMigrator = ();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user