Skip to content

Commit

Permalink
Relay block number provider
Browse files Browse the repository at this point in the history
  • Loading branch information
Szegoo committed Jan 27, 2024
1 parent a46e7f0 commit 8e6ba0b
Show file tree
Hide file tree
Showing 10 changed files with 246 additions and 24 deletions.
20 changes: 20 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ members = [
"chain-extensions/xvm",
"chain-extensions/unified-accounts",
"chain-extensions/pallet-uniques",
"chain-extensions/block-number-provider",
"chain-extensions/types/*",

"vendor/evm-tracing",
Expand Down Expand Up @@ -556,6 +557,7 @@ pallet-chain-extension-xvm = { path = "./chain-extensions/xvm", default-features
pallet-chain-extension-assets = { path = "./chain-extensions/pallet-assets", default-features = false }
pallet-chain-extension-unified-accounts = { path = "./chain-extensions/unified-accounts", default-features = false }
pallet-chain-extension-uniques = { path = "./chain-extensions/pallet-uniques", default-features = false }
chain-extension-block-number-provider = { path = "./chain-extensions/block-number-provider", default-features = false }

xvm-chain-extension-types = { path = "./chain-extensions/types/xvm", default-features = false }
assets-chain-extension-types = { path = "./chain-extensions/types/assets", default-features = false }
Expand Down
40 changes: 40 additions & 0 deletions chain-extensions/block-number-provider/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
[package]
name = "chain-extension-block-number-provider"
version = "0.1.0"
license = "Apache-2.0"
description = "Relay chain block number provider chain extension for WASM contracts"
authors.workspace = true
edition.workspace = true
homepage.workspace = true
repository.workspace = true

[dependencies]
cumulus-pallet-parachain-system ={ workspace = true }
log = { workspace = true }
num-traits = { workspace = true }
frame-support = { workspace = true }
frame-system = { workspace = true }
pallet-contracts = { workspace = true }
pallet-contracts-primitives = { workspace = true }
parity-scale-codec = { workspace = true }
scale-info = { workspace = true }
sp-core = { workspace = true }
sp-runtime = { workspace = true }
sp-std = { workspace = true }

[features]
default = ["std"]
std = [
"cumulus-pallet-parachain-system/std",
"parity-scale-codec/std",
"num-traits/std",
"frame-support/std",
"frame-system/std",
"pallet-contracts/std",
"pallet-contracts-primitives/std",
"scale-info/std",
"sp-std/std",
"sp-core/std",
"sp-runtime/std",
]
local = []
130 changes: 130 additions & 0 deletions chain-extensions/block-number-provider/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
// This file is part of Astar.

// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd.
// SPDX-License-Identifier: GPL-3.0-or-later

// Astar is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Astar is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Astar. If not, see <http://www.gnu.org/licenses/>.

#![cfg_attr(not(feature = "std"), no_std)]

pub mod weights;

use pallet_contracts::chain_extension::{
ChainExtension, Environment, Ext, InitState, RetVal, SysConfig,
};
use parity_scale_codec::{Decode, Encode};
use sp_runtime::{traits::StaticLookup, DispatchError};
use sp_std::marker::PhantomData;

#[cfg(not(feature = "local"))]
use cumulus_pallet_parachain_system::RelaychainDataProvider;
#[cfg(not(feature = "local"))]
use sp_runtime::traits::BlockNumberProvider;

type AccountIdLookup<T> = <<T as SysConfig>::Lookup as StaticLookup>::Source;

enum BlockNumberProviderFunc {
RelayChainBlockNumber,
}

#[derive(PartialEq, Eq, Copy, Clone, Encode, Decode, Debug)]
#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))]
pub enum Outcome {
/// Success
Success = 0,
/// Origin Caller is not supported
OriginCannotBeCaller = 98,
/// Unknown error
RuntimeError = 99,
}

impl TryFrom<u16> for BlockNumberProviderFunc {
type Error = DispatchError;

fn try_from(value: u16) -> Result<Self, Self::Error> {
match value {
1 => Ok(Self::RelayChainBlockNumber),
_ => Err(DispatchError::Other(
"Unimplemented func_id for BlockNumberProvider",
)),
}
}
}

/// Block number provider chain extension.
pub struct BlockNumberProviderExtension<T, W>(PhantomData<(T, W)>);

impl<T, W> Default for BlockNumberProviderExtension<T, W> {
fn default() -> Self {
BlockNumberProviderExtension(PhantomData)
}
}

#[cfg(feature = "local")]
impl<T, W> ChainExtension<T> for BlockNumberProviderExtension<T, W>
where
T: pallet_contracts::Config,
AccountIdLookup<T>: From<<T as SysConfig>::AccountId>,
<T as SysConfig>::AccountId: From<[u8; 32]>,
W: weights::WeightInfo,
{
fn call<E: Ext>(&mut self, env: Environment<E, InitState>) -> Result<RetVal, DispatchError>
where
E: Ext<T = T>,
{
let func_id = env.func_id().try_into()?;
let mut env = env.buf_in_buf_out();

match func_id {
BlockNumberProviderFunc::RelayChainBlockNumber => {
let base_weight = <W as weights::WeightInfo>::relay_chain_block_number();
env.charge_weight(base_weight)?;

let current_block_number = frame_system::Pallet::<T>::block_number();
env.write(&current_block_number.encode(), false, None)?;
}
}

Ok(RetVal::Converging(Outcome::Success as u32))
}
}

#[cfg(not(feature = "local"))]
impl<T, W> ChainExtension<T> for BlockNumberProviderExtension<T, W>
where
T: pallet_contracts::Config + cumulus_pallet_parachain_system::Config,
AccountIdLookup<T>: From<<T as SysConfig>::AccountId>,
<T as SysConfig>::AccountId: From<[u8; 32]>,
W: weights::WeightInfo,
{
fn call<E: Ext>(&mut self, env: Environment<E, InitState>) -> Result<RetVal, DispatchError>
where
E: Ext<T = T>,
{
let func_id = env.func_id().try_into()?;
let mut env = env.buf_in_buf_out();

match func_id {
BlockNumberProviderFunc::RelayChainBlockNumber => {
let base_weight = <W as weights::WeightInfo>::relay_chain_block_number();
env.charge_weight(base_weight)?;

let current_block_number = RelaychainDataProvider::<T>::current_block_number();
env.write(&current_block_number.encode(), false, None)?;
}
}

Ok(RetVal::Converging(Outcome::Success as u32))
}
}
37 changes: 37 additions & 0 deletions chain-extensions/block-number-provider/src/weights.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// This file is part of Astar.

// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd.
// SPDX-License-Identifier: GPL-3.0-or-later

// Astar is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Astar is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Astar. If not, see <http://www.gnu.org/licenses/>.

#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(unused_parens)]
#![allow(unused_imports)]

use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
use sp_std::marker::PhantomData;

/// Weight functions needed for block number provider chain-extension.
pub trait WeightInfo {
fn relay_chain_block_number() -> Weight;
}

/// Weights for block number provider chain-extension
pub struct SubstrateWeight<T>(PhantomData<T>);
impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
fn relay_chain_block_number() -> Weight {
T::DbWeight::get().reads(1 as u64)
}
}
24 changes: 0 additions & 24 deletions chain-extensions/types/uniques/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#![cfg_attr(not(feature = "std"), no_std)]
use parity_scale_codec::MaxEncodedLen;
use parity_scale_codec::{Decode, Encode};

#[derive(PartialEq, Eq, Copy, Clone, Encode, Decode, Debug)]
Expand All @@ -12,26 +11,3 @@ pub enum Outcome {
/// Unknown error
RuntimeError = 99,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, Decode, MaxEncodedLen)]
#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))]
pub enum Origin {
Caller,
Address,
}

impl Default for Origin {
fn default() -> Self {
Self::Address
}
}

#[macro_export]
macro_rules! select_origin {
($origin:expr, $account:expr) => {
match $origin {
Origin::Caller => return Ok(RetVal::Converging(Outcome::OriginCannotBeCaller as u32)),
Origin::Address => RawOrigin::Signed($account),
}
};
}
2 changes: 2 additions & 0 deletions runtime/local/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ moonbeam-rpc-primitives-txpool = { workspace = true, optional = true }
# chain-extensions
pallet-chain-extension-assets = { workspace = true }
pallet-chain-extension-uniques = { workspace = true }
chain-extension-block-number-provider = { workspace = true, features = ["local"]}

# benchmarking
array-bytes = { workspace = true }
Expand Down Expand Up @@ -186,6 +187,7 @@ std = [
"substrate-wasm-builder",
"pallet-chain-extension-assets/std",
"pallet-chain-extension-uniques/std",
"chain-extension-block-number-provider/std",
"astar-primitives/std",
]
runtime-benchmarks = [
Expand Down
7 changes: 7 additions & 0 deletions runtime/local/src/chain_extensions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

use super::{Runtime, UnifiedAccounts, Xvm};

pub use chain_extension_block_number_provider::BlockNumberProviderExtension;
/// Registered WASM contracts chain extensions.
pub use pallet_chain_extension_assets::AssetsExtension;
pub use pallet_chain_extension_uniques::UniquesExtension;
Expand Down Expand Up @@ -47,3 +48,9 @@ impl<W: pallet_chain_extension_uniques::weights::WeightInfo> RegisteredChainExte
{
const ID: u16 = 04;
}

impl<W: chain_extension_block_number_provider::weights::WeightInfo>
RegisteredChainExtension<Runtime> for BlockNumberProviderExtension<Runtime, W>
{
const ID: u16 = 05;
}
1 change: 1 addition & 0 deletions runtime/shibuya/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ moonbeam-rpc-primitives-txpool = { workspace = true, optional = true }
# chain-extensions
pallet-chain-extension-assets = { workspace = true }
pallet-chain-extension-uniques = { workspace = true }
chain-extension-block-number-provider = { workspace = true }

# benchmarking
array-bytes = { workspace = true }
Expand Down
7 changes: 7 additions & 0 deletions runtime/shibuya/src/chain_extensions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

use super::{Runtime, UnifiedAccounts, Xvm};

pub use chain_extension_block_number_provider::BlockNumberProviderExtension;
/// Registered WASM contracts chain extensions.
pub use pallet_chain_extension_assets::AssetsExtension;
pub use pallet_chain_extension_uniques::UniquesExtension;
Expand Down Expand Up @@ -47,3 +48,9 @@ impl<W: pallet_chain_extension_uniques::weights::WeightInfo> RegisteredChainExte
{
const ID: u16 = 04;
}

impl<W: chain_extension_block_number_provider::weights::WeightInfo>
RegisteredChainExtension<Runtime> for BlockNumberProviderExtension<Runtime, W>
{
const ID: u16 = 05;
}

0 comments on commit 8e6ba0b

Please sign in to comment.