mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-09 20:59:23 +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],
|
||||
}
|
||||
|
||||
impl HeaderV1 {
|
||||
/// The size of a serialized V1 header.
|
||||
pub const SIZE: usize = 8 + 32 + 8 + 32 + 32 + 32;
|
||||
}
|
||||
|
||||
/// A header for a block.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, BorshSerialize, BorshDeserialize)]
|
||||
pub enum Header {
|
||||
@@ -71,6 +76,9 @@ pub enum Header {
|
||||
}
|
||||
|
||||
impl Header {
|
||||
/// The size of a serialized header.
|
||||
pub const SIZE: usize = 1 + HeaderV1::SIZE;
|
||||
|
||||
/// Get the hash of the header.
|
||||
pub fn number(&self) -> u64 {
|
||||
match self {
|
||||
@@ -109,8 +117,8 @@ impl Header {
|
||||
|
||||
/// A block.
|
||||
///
|
||||
/// This does not guarantee consistency. The header's `transactions_root` may not match the
|
||||
/// contained transactions.
|
||||
/// This does not guarantee consistency nor validity. The header's `transactions_root` may not
|
||||
/// match the contained transactions, among other ill effects.
|
||||
#[derive(Clone, PartialEq, Eq, Debug, BorshSerialize, BorshDeserialize)]
|
||||
pub struct Block {
|
||||
/// The block's header.
|
||||
@@ -119,6 +127,13 @@ pub struct Block {
|
||||
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")]
|
||||
mod substrate {
|
||||
use core::fmt::Debug;
|
||||
@@ -133,7 +148,7 @@ mod substrate {
|
||||
|
||||
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 {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
|
||||
@@ -279,12 +279,13 @@ mod substrate {
|
||||
/// The implicit context to verify transactions with.
|
||||
fn implicit_context() -> ImplicitContext;
|
||||
|
||||
/// The size of the current block.
|
||||
fn current_block_size(&self) -> usize;
|
||||
|
||||
/// If a block is present in the blockchain.
|
||||
fn block_is_present_in_blockchain(&self, hash: &BlockHash) -> bool;
|
||||
/// The time embedded into the current block.
|
||||
///
|
||||
/// Returns `None` if the time has yet to be set.
|
||||
fn current_time(&self) -> Option<u64>;
|
||||
fn current_time(&self) -> u64;
|
||||
/// Get the next nonce for an account.
|
||||
fn next_nonce(&self, signer: &SeraiAddress) -> u32;
|
||||
/// If the signer can pay the SRI fee.
|
||||
@@ -295,7 +296,7 @@ mod substrate {
|
||||
) -> Result<(), TransactionValidityError>;
|
||||
|
||||
/// Begin execution of a transaction.
|
||||
fn start_transaction(&self);
|
||||
fn start_transaction(&self, len: usize);
|
||||
/// 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.
|
||||
@@ -390,9 +391,14 @@ mod substrate {
|
||||
impl<Context: TransactionContext> TransactionWithContext<Context> {
|
||||
fn validate_except_fee<V: ValidateUnsigned<Call = Context::RuntimeCall>>(
|
||||
&self,
|
||||
len: usize,
|
||||
source: TransactionSource,
|
||||
mempool_priority_if_signed: u64,
|
||||
) -> TransactionValidity {
|
||||
if self.1.current_block_size().saturating_add(len) > crate::Block::SIZE_LIMIT {
|
||||
Err(TransactionValidityError::Invalid(InvalidTransaction::ExhaustsResources))?;
|
||||
}
|
||||
|
||||
match &self.0 {
|
||||
Transaction::Unsigned { call } => {
|
||||
let ValidTransaction { priority: _, requires, provides, longevity: _, propagate: _ } =
|
||||
@@ -417,13 +423,8 @@ mod substrate {
|
||||
Err(TransactionValidityError::Unknown(UnknownTransaction::CannotLookup))?;
|
||||
}
|
||||
if let Some(include_by) = *include_by {
|
||||
if let Some(current_time) = self.1.current_time() {
|
||||
if current_time >= u64::from(include_by) {
|
||||
// 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
|
||||
if self.1.current_time() >= u64::from(include_by) {
|
||||
// Since this transaction has a time bound which has passed, error
|
||||
Err(TransactionValidityError::Invalid(InvalidTransaction::Stale))?;
|
||||
}
|
||||
}
|
||||
@@ -471,7 +472,7 @@ mod substrate {
|
||||
&self,
|
||||
source: TransactionSource,
|
||||
info: &DispatchInfo,
|
||||
_len: usize,
|
||||
len: usize,
|
||||
) -> TransactionValidity {
|
||||
let mempool_priority_if_signed = match &self.0 {
|
||||
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>>(
|
||||
self,
|
||||
_info: &DispatchInfo,
|
||||
_len: usize,
|
||||
len: usize,
|
||||
) -> sp_runtime::ApplyExtrinsicResultWithInfo<PostDispatchInfo> {
|
||||
// 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
|
||||
self.1.start_transaction();
|
||||
self.1.start_transaction(len);
|
||||
|
||||
let transaction_hash = self.0.hash();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user