Skip to content

Commit

Permalink
Make state types public (paritytech#12032)
Browse files Browse the repository at this point in the history
  • Loading branch information
athei authored and ark0f committed Feb 27, 2023
1 parent e53c39c commit 1a2eb58
Showing 1 changed file with 60 additions and 38 deletions.
98 changes: 60 additions & 38 deletions frame/contracts/src/chain_extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ pub use crate::{exec::Ext, Config};
pub use frame_system::Config as SysConfig;
pub use pallet_contracts_primitives::ReturnFlags;
pub use sp_core::crypto::UncheckedFrom;
pub use state::Init as InitState;

/// Result that returns a [`DispatchError`] on error.
pub type Result<T> = sp_std::result::Result<T, DispatchError>;
Expand Down Expand Up @@ -198,15 +197,15 @@ pub enum RetVal {
///
/// It uses [typestate programming](https://docs.rust-embedded.org/book/static-guarantees/typestate-programming.html)
/// to enforce the correct usage of the parameters passed to the chain extension.
pub struct Environment<'a, 'b, E: Ext, S: state::State> {
pub struct Environment<'a, 'b, E: Ext, S: State> {
/// The actual data of this type.
inner: Inner<'a, 'b, E>,
/// `S` is only used in the type system but never as value.
phantom: PhantomData<S>,
}

/// Functions that are available in every state of this type.
impl<'a, 'b, E: Ext, S: state::State> Environment<'a, 'b, E, S>
impl<'a, 'b, E: Ext, S: State> Environment<'a, 'b, E, S>
where
<E::T as SysConfig>::AccountId: UncheckedFrom<<E::T as SysConfig>::Hash> + AsRef<[u8]>,
{
Expand Down Expand Up @@ -264,7 +263,7 @@ where
///
/// Those are the functions that determine how the arguments to the chain extensions
/// should be consumed.
impl<'a, 'b, E: Ext> Environment<'a, 'b, E, state::Init> {
impl<'a, 'b, E: Ext> Environment<'a, 'b, E, InitState> {
/// Creates a new environment for consumption by a chain extension.
///
/// It is only available to this crate because only the wasm runtime module needs to
Expand All @@ -284,23 +283,23 @@ impl<'a, 'b, E: Ext> Environment<'a, 'b, E, state::Init> {
}

/// Use all arguments as integer values.
pub fn only_in(self) -> Environment<'a, 'b, E, state::OnlyIn> {
pub fn only_in(self) -> Environment<'a, 'b, E, OnlyInState> {
Environment { inner: self.inner, phantom: PhantomData }
}

/// Use input arguments as integer and output arguments as pointer to a buffer.
pub fn prim_in_buf_out(self) -> Environment<'a, 'b, E, state::PrimInBufOut> {
pub fn prim_in_buf_out(self) -> Environment<'a, 'b, E, PrimInBufOutState> {
Environment { inner: self.inner, phantom: PhantomData }
}

/// Use input and output arguments as pointers to a buffer.
pub fn buf_in_buf_out(self) -> Environment<'a, 'b, E, state::BufInBufOut> {
pub fn buf_in_buf_out(self) -> Environment<'a, 'b, E, BufInBufOutState> {
Environment { inner: self.inner, phantom: PhantomData }
}
}

/// Functions to use the input arguments as integers.
impl<'a, 'b, E: Ext, S: state::PrimIn> Environment<'a, 'b, E, S> {
impl<'a, 'b, E: Ext, S: PrimIn> Environment<'a, 'b, E, S> {
/// The `input_ptr` argument.
pub fn val0(&self) -> u32 {
self.inner.input_ptr
Expand All @@ -313,7 +312,7 @@ impl<'a, 'b, E: Ext, S: state::PrimIn> Environment<'a, 'b, E, S> {
}

/// Functions to use the output arguments as integers.
impl<'a, 'b, E: Ext, S: state::PrimOut> Environment<'a, 'b, E, S> {
impl<'a, 'b, E: Ext, S: PrimOut> Environment<'a, 'b, E, S> {
/// The `output_ptr` argument.
pub fn val2(&self) -> u32 {
self.inner.output_ptr
Expand All @@ -326,7 +325,7 @@ impl<'a, 'b, E: Ext, S: state::PrimOut> Environment<'a, 'b, E, S> {
}

/// Functions to use the input arguments as pointer to a buffer.
impl<'a, 'b, E: Ext, S: state::BufIn> Environment<'a, 'b, E, S>
impl<'a, 'b, E: Ext, S: BufIn> Environment<'a, 'b, E, S>
where
<E::T as SysConfig>::AccountId: UncheckedFrom<<E::T as SysConfig>::Hash> + AsRef<[u8]>,
{
Expand Down Expand Up @@ -389,7 +388,7 @@ where
}

/// Functions to use the output arguments as pointer to a buffer.
impl<'a, 'b, E: Ext, S: state::BufOut> Environment<'a, 'b, E, S>
impl<'a, 'b, E: Ext, S: BufOut> Environment<'a, 'b, E, S>
where
<E::T as SysConfig>::AccountId: UncheckedFrom<<E::T as SysConfig>::Hash> + AsRef<[u8]>,
{
Expand Down Expand Up @@ -438,31 +437,54 @@ struct Inner<'a, 'b, E: Ext> {
output_len_ptr: u32,
}

/// Private submodule with public types to prevent other modules from naming them.
mod state {
pub trait State {}

pub trait PrimIn: State {}
pub trait PrimOut: State {}
pub trait BufIn: State {}
pub trait BufOut: State {}

/// The initial state of an [`Environment`](`super::Environment`).
/// See [typestate programming](https://docs.rust-embedded.org/book/static-guarantees/typestate-programming.html).
pub enum Init {}
pub enum OnlyIn {}
pub enum PrimInBufOut {}
pub enum BufInBufOut {}

impl State for Init {}
impl State for OnlyIn {}
impl State for PrimInBufOut {}
impl State for BufInBufOut {}

impl PrimIn for OnlyIn {}
impl PrimOut for OnlyIn {}
impl PrimIn for PrimInBufOut {}
impl BufOut for PrimInBufOut {}
impl BufIn for BufInBufOut {}
impl BufOut for BufInBufOut {}
/// Any state of an [`Environment`] implements this trait.
/// See [typestate programming](https://docs.rust-embedded.org/book/static-guarantees/typestate-programming.html).
pub trait State: sealed::Sealed {}

/// A state that uses primitive inputs.
pub trait PrimIn: State {}

/// A state that uses primitive outputs.
pub trait PrimOut: State {}

/// A state that uses a buffer as input.
pub trait BufIn: State {}

/// A state that uses a buffer as output.
pub trait BufOut: State {}

/// The initial state of an [`Environment`].
pub enum InitState {}

/// A state that uses all arguments as primitive inputs.
pub enum OnlyInState {}

/// A state that uses two arguments as primitive inputs and the other two as buffer output.
pub enum PrimInBufOutState {}

/// Uses a buffer for input and a buffer for output.
pub enum BufInBufOutState {}

mod sealed {
use super::*;

/// Trait to prevent users from implementing `State` for anything else.
pub trait Sealed {}

impl Sealed for InitState {}
impl Sealed for OnlyInState {}
impl Sealed for PrimInBufOutState {}
impl Sealed for BufInBufOutState {}

impl State for InitState {}
impl State for OnlyInState {}
impl State for PrimInBufOutState {}
impl State for BufInBufOutState {}

impl PrimIn for OnlyInState {}
impl PrimOut for OnlyInState {}
impl PrimIn for PrimInBufOutState {}
impl BufOut for PrimInBufOutState {}
impl BufIn for BufInBufOutState {}
impl BufOut for BufInBufOutState {}
}

0 comments on commit 1a2eb58

Please sign in to comment.