Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: devnet runtime api #274

Merged
merged 22 commits into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions pallets/api/src/fungibles/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ pub mod pallet {

/// State reads for the fungibles API with required input.
#[derive(Encode, Decode, Debug, MaxEncodedLen)]
#[cfg_attr(feature = "std", derive(PartialEq, Clone))]
#[repr(u8)]
#[allow(clippy::unnecessary_cast)]
pub enum Read<T: Config> {
Expand Down Expand Up @@ -85,6 +86,7 @@ pub mod pallet {

/// Results of state reads for the fungibles API.
#[derive(Debug)]
#[cfg_attr(feature = "std", derive(PartialEq, Clone))]
pub enum ReadResult<T: Config> {
/// Total token supply for a specified token.
TotalSupply(BalanceOf<T>),
Expand Down
121 changes: 77 additions & 44 deletions runtime/devnet/src/config/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type DecodesAs<Output, Logger = ()> = pallet_api::extension::DecodesAs<

/// A query of runtime state.
#[derive(Decode, Debug)]
#[cfg_attr(test, derive(PartialEq, Clone))]
#[repr(u8)]
pub enum RuntimeRead {
/// Fungible token queries.
Expand Down Expand Up @@ -55,6 +56,7 @@ impl Readable for RuntimeRead {

/// The result of a runtime state read.
#[derive(Debug)]
#[cfg_attr(test, derive(PartialEq, Clone))]
pub enum RuntimeResult {
/// Fungible token read results.
Fungibles(fungibles::ReadResult<Runtime>),
Expand Down Expand Up @@ -163,53 +165,84 @@ impl<T: frame_system::Config> Contains<RuntimeRead> for Filter<T> {
}
}

#[test]
fn filter_prevents_runtime_filtered_calls() {
use pallet_balances::{AdjustmentDirection, Call::*};
use sp_runtime::MultiAddress;
use RuntimeCall::Balances;

const CALLS: [RuntimeCall; 4] = [
Balances(force_adjust_total_issuance {
direction: AdjustmentDirection::Increase,
delta: 0,
}),
Balances(force_set_balance { who: MultiAddress::Address32([0u8; 32]), new_free: 0 }),
Balances(force_transfer {
source: MultiAddress::Address32([0u8; 32]),
dest: MultiAddress::Address32([0u8; 32]),
value: 0,
}),
Balances(force_unreserve { who: MultiAddress::Address32([0u8; 32]), amount: 0 }),
];

for call in CALLS {
assert!(!Filter::<Runtime>::contains(&call))
}
}

#[test]
fn filter_allows_fungibles_calls() {
#[cfg(test)]
mod tests {
use codec::Encode;
use pallet_api::fungibles::Call::*;
use sp_core::crypto::AccountId32;
use RuntimeCall::Fungibles;
use RuntimeCall::{Balances, Fungibles};

use super::*;

const ACCOUNT: AccountId32 = AccountId32::new([0u8; 32]);
const CALLS: [RuntimeCall; 11] = [
Fungibles(transfer { token: 0, to: ACCOUNT, value: 0 }),
Fungibles(transfer_from { token: 0, from: ACCOUNT, to: ACCOUNT, value: 0 }),
Fungibles(approve { token: 0, spender: ACCOUNT, value: 0 }),
Fungibles(increase_allowance { token: 0, spender: ACCOUNT, value: 0 }),
Fungibles(decrease_allowance { token: 0, spender: ACCOUNT, value: 0 }),
Fungibles(create { id: 0, admin: ACCOUNT, min_balance: 0 }),
Fungibles(set_metadata { token: 0, name: vec![], symbol: vec![], decimals: 0 }),
Fungibles(start_destroy { token: 0 }),
Fungibles(clear_metadata { token: 0 }),
Fungibles(mint { token: 0, account: ACCOUNT, value: 0 }),
Fungibles(burn { token: 0, account: ACCOUNT, value: 0 }),
];

for call in CALLS {
assert!(Filter::<Runtime>::contains(&call))

#[test]
fn runtime_result_encode_works() {
let value = 1_000;
let result = fungibles::ReadResult::<Runtime>::TotalSupply(value);
assert_eq!(RuntimeResult::Fungibles(result).encode(), value.encode());
}

#[test]
fn filter_prevents_runtime_filtered_calls() {
use pallet_balances::{AdjustmentDirection, Call::*};
use sp_runtime::MultiAddress;

const CALLS: [RuntimeCall; 4] = [
Balances(force_adjust_total_issuance {
direction: AdjustmentDirection::Increase,
delta: 0,
}),
Balances(force_set_balance { who: MultiAddress::Address32([0u8; 32]), new_free: 0 }),
Balances(force_transfer {
source: MultiAddress::Address32([0u8; 32]),
dest: MultiAddress::Address32([0u8; 32]),
value: 0,
}),
Balances(force_unreserve { who: MultiAddress::Address32([0u8; 32]), amount: 0 }),
];

for call in CALLS {
assert!(!Filter::<Runtime>::contains(&call))
}
}

#[test]
fn filter_allows_fungibles_calls() {
const CALLS: [RuntimeCall; 11] = [
Fungibles(transfer { token: 0, to: ACCOUNT, value: 0 }),
Fungibles(transfer_from { token: 0, from: ACCOUNT, to: ACCOUNT, value: 0 }),
Fungibles(approve { token: 0, spender: ACCOUNT, value: 0 }),
Fungibles(increase_allowance { token: 0, spender: ACCOUNT, value: 0 }),
Fungibles(decrease_allowance { token: 0, spender: ACCOUNT, value: 0 }),
Fungibles(create { id: 0, admin: ACCOUNT, min_balance: 0 }),
Fungibles(set_metadata { token: 0, name: vec![], symbol: vec![], decimals: 0 }),
Fungibles(start_destroy { token: 0 }),
Fungibles(clear_metadata { token: 0 }),
Fungibles(mint { token: 0, account: ACCOUNT, value: 0 }),
Fungibles(burn { token: 0, account: ACCOUNT, value: 0 }),
];

for call in CALLS {
assert!(Filter::<Runtime>::contains(&call))
}
}

#[test]
fn filter_allows_fungibles_reads() {
use super::{fungibles::Read::*, RuntimeRead::*};
const READS: [RuntimeRead; 7] = [
evilrobot-01 marked this conversation as resolved.
Show resolved Hide resolved
Fungibles(TotalSupply(1)),
Fungibles(BalanceOf { token: 1, owner: ACCOUNT }),
Fungibles(Allowance { token: 1, owner: ACCOUNT, spender: ACCOUNT }),
Fungibles(TokenName(1)),
Fungibles(TokenSymbol(1)),
Fungibles(TokenDecimals(10)),
Fungibles(TokenExists(1)),
];

for read in READS {
assert!(Filter::<Runtime>::contains(&read))
}
}
}
63 changes: 63 additions & 0 deletions runtime/devnet/src/config/api/versioning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ impl From<VersionedRuntimeRead> for RuntimeRead {

/// Versioned runtime state read results.
#[derive(Debug)]
#[cfg_attr(test, derive(PartialEq, Clone))]
pub enum VersionedRuntimeResult {
/// Version zero of runtime read results.
V0(RuntimeResult),
Expand Down Expand Up @@ -69,6 +70,7 @@ impl From<VersionedRuntimeResult> for Vec<u8> {

/// Versioned errors.
#[derive(Debug)]
#[cfg_attr(test, derive(PartialEq))]
Daanvdplas marked this conversation as resolved.
Show resolved Hide resolved
pub enum VersionedError {
/// Version zero of errors.
V0(pop_primitives::v0::Error),
Expand All @@ -95,6 +97,8 @@ impl From<VersionedError> for u32 {
}
}

// Type for conversion to a versioned `pop_primitives::Error` to avoid taking a dependency of
// sp_runtime on pop-primitives.
peterwht marked this conversation as resolved.
Show resolved Hide resolved
struct V0Error(pop_primitives::v0::Error);
impl From<DispatchError> for V0Error {
fn from(error: DispatchError) -> Self {
Expand Down Expand Up @@ -159,12 +163,71 @@ impl From<DispatchError> for V0Error {

#[cfg(test)]
mod tests {
use codec::Encode;
use frame_system::Call;
use pop_primitives::{ArithmeticError::*, Error, TokenError::*, TransactionalError::*};
use sp_runtime::ModuleError;
use DispatchError::*;

use super::*;

#[test]
fn from_versioned_runtime_call_to_runtime_call_works() {
let call =
RuntimeCall::System(Call::remark_with_event { remark: "pop".as_bytes().to_vec() });
assert_eq!(RuntimeCall::from(VersionedRuntimeCall::V0(call.clone())), call);
}

#[test]
fn from_versioned_runtime_read_to_runtime_read_works() {
let read = RuntimeRead::Fungibles(fungibles::Read::<Runtime>::TotalSupply(42));
assert_eq!(RuntimeRead::from(VersionedRuntimeRead::V0(read.clone())), read);
}

#[test]
fn versioned_runtime_result_works() {
let result = RuntimeResult::Fungibles(fungibles::ReadResult::<Runtime>::TotalSupply(1_000));
let v0 = 0;
let v1 = 1;
assert_eq!(
VersionedRuntimeResult::try_from((result.clone(), v0)),
Ok(VersionedRuntimeResult::V0(result.clone()))
);
// Unknown version.
assert_eq!(
peterwht marked this conversation as resolved.
Show resolved Hide resolved
VersionedRuntimeResult::try_from((result.clone(), v1)),
Err(pallet_contracts::Error::<Runtime>::DecodingFailed.into())
);
}

#[test]
fn versioned_runtime_result_to_bytes_works() {
let value = 1_000;
let result = RuntimeResult::Fungibles(fungibles::ReadResult::<Runtime>::TotalSupply(value));
assert_eq!(<Vec<u8>>::from(VersionedRuntimeResult::V0(result)), value.encode());
}

#[test]
fn versioned_error_works() {
let error = BadOrigin;
let v0 = 0;
let v1 = 1;
assert_eq!(
VersionedError::try_from((error, v0)),
Ok(VersionedError::V0(V0Error::from(error).0))
);
// Unknown version.
assert_eq!(
peterwht marked this conversation as resolved.
Show resolved Hide resolved
VersionedError::try_from((error, v1)),
Err(pallet_contracts::Error::<Runtime>::DecodingFailed.into())
);
}

#[test]
fn versioned_error_to_u32_works() {
assert_eq!(u32::from(VersionedError::V0(Error::BadOrigin)), u32::from(Error::BadOrigin));
}

// Compare all the different `DispatchError` variants with the expected `Error`.
#[test]
fn dispatch_error_to_error() {
Expand Down
33 changes: 15 additions & 18 deletions runtime/devnet/src/config/contracts.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,15 @@
use frame_support::{
parameter_types,
traits::{ConstBool, ConstU32, Randomness},
traits::{ConstBool, ConstU32, Nothing, Randomness},
};
use frame_system::{pallet_prelude::BlockNumberFor, EnsureSigned};

use super::api::{self, Config};
use crate::{
deposit, Balance, Balances, BalancesCall, Perbill, Runtime, RuntimeCall, RuntimeEvent,
RuntimeHoldReason, Timestamp,
deposit, Balance, Balances, Perbill, Runtime, RuntimeCall, RuntimeEvent, RuntimeHoldReason,
Timestamp,
};

pub enum AllowBalancesCall {}

impl frame_support::traits::Contains<RuntimeCall> for AllowBalancesCall {
fn contains(call: &RuntimeCall) -> bool {
matches!(call, RuntimeCall::Balances(BalancesCall::transfer_allow_death { .. }))
}
}

fn schedule<T: pallet_contracts::Config>() -> pallet_contracts::Schedule<T> {
pallet_contracts::Schedule {
limits: pallet_contracts::Limits {
Expand Down Expand Up @@ -49,13 +41,8 @@ parameter_types! {
impl pallet_contracts::Config for Runtime {
type AddressGenerator = pallet_contracts::DefaultAddressGenerator;
type ApiVersion = ();
/// The safest default is to allow no calls at all.
///
/// Runtimes should whitelist dispatchables that are allowed to be called from contracts
/// and make sure they are stable. Dispatchables exposed to contracts are not allowed to
/// change because that would break already deployed contracts. The `RuntimeCall` structure
/// itself is not allowed to change the indices of existing pallets, too.
type CallFilter = AllowBalancesCall;
// IMPORTANT: only runtime calls through the api are allowed.
type CallFilter = Nothing;
Daanvdplas marked this conversation as resolved.
Show resolved Hide resolved
type CallStack = [pallet_contracts::Frame<Self>; 23];
type ChainExtension = api::Extension<Config>;
type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent;
Expand Down Expand Up @@ -91,3 +78,13 @@ impl pallet_contracts::Config for Runtime {
type WeightPrice = pallet_transaction_payment::Pallet<Self>;
type Xcm = pallet_xcm::Pallet<Self>;
}

// IMPORTANT: only runtime calls through the api are allowed.
#[test]
fn contracts_prevents_runtime_calls() {
Daanvdplas marked this conversation as resolved.
Show resolved Hide resolved
use std::any::TypeId;
assert_eq!(
TypeId::of::<<Runtime as pallet_contracts::Config>::CallFilter>(),
TypeId::of::<Nothing>()
);
}
25 changes: 8 additions & 17 deletions runtime/devnet/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));

// Public due to integration tests crate.
pub mod config;

Check warning on line 10 in runtime/devnet/src/lib.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for a module

warning: missing documentation for a module --> runtime/devnet/src/lib.rs:10:1 | 10 | pub mod config; | ^^^^^^^^^^^^^^
mod weights;

use config::xcm::{RelayLocation, XcmOriginToTransactDispatchOrigin};
Expand Down Expand Up @@ -169,7 +169,7 @@
}

#[sp_version::runtime_version]
pub const VERSION: RuntimeVersion = RuntimeVersion {

Check warning on line 172 in runtime/devnet/src/lib.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for a constant

warning: missing documentation for a constant --> runtime/devnet/src/lib.rs:172:1 | 172 | pub const VERSION: RuntimeVersion = RuntimeVersion { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
spec_name: create_runtime_str!("pop"),
impl_name: create_runtime_str!("pop"),
authoring_version: 1,
Expand Down Expand Up @@ -531,7 +531,7 @@
type WeightInfo = pallet_utility::weights::SubstrateWeight<Runtime>;
}

#[frame_support::runtime]

Check warning on line 534 in runtime/devnet/src/lib.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for an associated function

warning: missing documentation for an associated function --> runtime/devnet/src/lib.rs:534:1 | 534 | #[frame_support::runtime] | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: this warning originates in the attribute macro `frame_support::runtime` (in Nightly builds, run with -Z macro-backtrace for more info)

Check warning on line 534 in runtime/devnet/src/lib.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for a type alias

warning: missing documentation for a type alias --> runtime/devnet/src/lib.rs:534:1 | 534 | #[frame_support::runtime] | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: this warning originates in the attribute macro `frame_support::runtime` (in Nightly builds, run with -Z macro-backtrace for more info)

Check warning on line 534 in runtime/devnet/src/lib.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for a struct field

warning: missing documentation for a struct field --> runtime/devnet/src/lib.rs:534:1 | 534 | #[frame_support::runtime] | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: this warning originates in the attribute macro `frame_support::runtime` (in Nightly builds, run with -Z macro-backtrace for more info)

Check warning on line 534 in runtime/devnet/src/lib.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for a variant

warning: missing documentation for a variant --> runtime/devnet/src/lib.rs:534:1 | 534 | #[frame_support::runtime] | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: this warning originates in the attribute macro `frame_support::runtime` (in Nightly builds, run with -Z macro-backtrace for more info)

Check warning on line 534 in runtime/devnet/src/lib.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for an enum

warning: missing documentation for an enum --> runtime/devnet/src/lib.rs:534:1 | 534 | #[frame_support::runtime] | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: this warning originates in the attribute macro `frame_support::runtime` (in Nightly builds, run with -Z macro-backtrace for more info)

Check warning on line 534 in runtime/devnet/src/lib.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for a struct

warning: missing documentation for a struct --> runtime/devnet/src/lib.rs:534:1 | 534 | #[frame_support::runtime] | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: this warning originates in the attribute macro `frame_support::runtime` (in Nightly builds, run with -Z macro-backtrace for more info)
mod runtime {
// Create the runtime by composing the FRAME pallets that were previously configured.
#[runtime::runtime]
Expand Down Expand Up @@ -641,376 +641,367 @@
);
}

impl_runtime_apis! {

impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {
fn slot_duration() -> sp_consensus_aura::SlotDuration {
sp_consensus_aura::SlotDuration::from_millis(SLOT_DURATION)
}

fn authorities() -> Vec<AuraId> {
pallet_aura::Authorities::<Runtime>::get().into_inner()
}
}

impl sp_api::Core<Block> for Runtime {
fn version() -> RuntimeVersion {
VERSION
}

fn execute_block(block: Block) {
Executive::execute_block(block)
}

fn initialize_block(header: &<Block as BlockT>::Header) -> ExtrinsicInclusionMode {
Executive::initialize_block(header)
}
}

impl sp_api::Metadata<Block> for Runtime {
fn metadata() -> OpaqueMetadata {
OpaqueMetadata::new(Runtime::metadata().into())
}

fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
Runtime::metadata_at_version(version)
}

fn metadata_versions() -> Vec<u32> {
Runtime::metadata_versions()
}
}

impl sp_block_builder::BlockBuilder<Block> for Runtime {
fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
Executive::apply_extrinsic(extrinsic)
}

fn finalize_block() -> <Block as BlockT>::Header {
Executive::finalize_block()
}

fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
data.create_extrinsics()
}

fn check_inherents(
block: Block,
data: sp_inherents::InherentData,
) -> sp_inherents::CheckInherentsResult {
data.check_extrinsics(&block)
}
}

impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
fn validate_transaction(
source: TransactionSource,
tx: <Block as BlockT>::Extrinsic,
block_hash: <Block as BlockT>::Hash,
) -> TransactionValidity {
Executive::validate_transaction(source, tx, block_hash)
}
}

impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
fn offchain_worker(header: &<Block as BlockT>::Header) {
Executive::offchain_worker(header)
}
}

impl sp_session::SessionKeys<Block> for Runtime {
fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
SessionKeys::generate(seed)
}

fn decode_session_keys(
encoded: Vec<u8>,
) -> Option<Vec<(Vec<u8>, KeyTypeId)>> {
SessionKeys::decode_into_raw_public_keys(&encoded)
}
}

impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce> for Runtime {
fn account_nonce(account: AccountId) -> Nonce {
System::account_nonce(account)
}
}

impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime {
fn query_info(
uxt: <Block as BlockT>::Extrinsic,
len: u32,
) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo<Balance> {
TransactionPayment::query_info(uxt, len)
}
fn query_fee_details(
uxt: <Block as BlockT>::Extrinsic,
len: u32,
) -> pallet_transaction_payment::FeeDetails<Balance> {
TransactionPayment::query_fee_details(uxt, len)
}
fn query_weight_to_fee(weight: Weight) -> Balance {
TransactionPayment::weight_to_fee(weight)
}
fn query_length_to_fee(length: u32) -> Balance {
TransactionPayment::length_to_fee(length)
}
}

impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi<Block, Balance, RuntimeCall>
for Runtime
{
fn query_call_info(
call: RuntimeCall,
len: u32,
) -> pallet_transaction_payment::RuntimeDispatchInfo<Balance> {
TransactionPayment::query_call_info(call, len)
}
fn query_call_fee_details(
call: RuntimeCall,
len: u32,
) -> pallet_transaction_payment::FeeDetails<Balance> {
TransactionPayment::query_call_fee_details(call, len)
}
fn query_weight_to_fee(weight: Weight) -> Balance {
TransactionPayment::weight_to_fee(weight)
}
fn query_length_to_fee(length: u32) -> Balance {
TransactionPayment::length_to_fee(length)
}
}

impl pallet_contracts::ContractsApi<Block, AccountId, Balance, BlockNumber, Hash, EventRecord>
for Runtime
{
fn call(
origin: AccountId,
dest: AccountId,
value: Balance,
gas_limit: Option<Weight>,
storage_deposit_limit: Option<Balance>,
input_data: Vec<u8>,
) -> pallet_contracts::ContractExecResult<Balance, EventRecord> {
let gas_limit = gas_limit.unwrap_or(RuntimeBlockWeights::get().max_block);
Contracts::bare_call(
origin,
dest,
value,
gas_limit,
storage_deposit_limit,
input_data,
CONTRACTS_DEBUG_OUTPUT,
CONTRACTS_EVENTS,
pallet_contracts::Determinism::Enforced,
)
}

fn instantiate(
origin: AccountId,
value: Balance,
gas_limit: Option<Weight>,
storage_deposit_limit: Option<Balance>,
code: pallet_contracts::Code<Hash>,
data: Vec<u8>,
salt: Vec<u8>,
) -> pallet_contracts::ContractInstantiateResult<AccountId, Balance, EventRecord>
{
let gas_limit = gas_limit.unwrap_or(RuntimeBlockWeights::get().max_block);
Contracts::bare_instantiate(
origin,
value,
gas_limit,
storage_deposit_limit,
code,
data,
salt,
CONTRACTS_DEBUG_OUTPUT,
CONTRACTS_EVENTS,
)
}

fn upload_code(
origin: AccountId,
code: Vec<u8>,
storage_deposit_limit: Option<Balance>,
determinism: pallet_contracts::Determinism,
) -> pallet_contracts::CodeUploadResult<Hash, Balance>
{
Contracts::bare_upload_code(origin, code, storage_deposit_limit, determinism)
}

fn get_storage(
address: AccountId,
key: Vec<u8>,
) -> pallet_contracts::GetStorageResult {
Contracts::get_storage(address, key)
}
}

impl cumulus_primitives_aura::AuraUnincludedSegmentApi<Block> for Runtime {
fn can_build_upon(
included_hash: <Block as BlockT>::Hash,
slot: cumulus_primitives_aura::Slot,
) -> bool {
ConsensusHook::can_build_upon(included_hash, slot)
}
}

impl cumulus_primitives_core::CollectCollationInfo<Block> for Runtime {
fn collect_collation_info(header: &<Block as BlockT>::Header) -> cumulus_primitives_core::CollationInfo {
ParachainSystem::collect_collation_info(header)
}
}

impl pallet_nfts_runtime_api::NftsApi<Block, AccountId, u32, u32> for Runtime {
fn owner(collection: u32, item: u32) -> Option<AccountId> {
<Nfts as Inspect<AccountId>>::owner(&collection, &item)
}

fn collection_owner(collection: u32) -> Option<AccountId> {
<Nfts as Inspect<AccountId>>::collection_owner(&collection)
}

fn attribute(
collection: u32,
item: u32,
key: Vec<u8>,
) -> Option<Vec<u8>> {
<Nfts as Inspect<AccountId>>::attribute(&collection, &item, &key)
}

fn custom_attribute(
account: AccountId,
collection: u32,
item: u32,
key: Vec<u8>,
) -> Option<Vec<u8>> {
<Nfts as Inspect<AccountId>>::custom_attribute(
&account,
&collection,
&item,
&key,
)
}

fn system_attribute(
collection: u32,
item: Option<u32>,
key: Vec<u8>,
) -> Option<Vec<u8>> {
<Nfts as Inspect<AccountId>>::system_attribute(&collection, item.as_ref(), &key)
}

fn collection_attribute(collection: u32, key: Vec<u8>) -> Option<Vec<u8>> {
<Nfts as Inspect<AccountId>>::collection_attribute(&collection, &key)
}
}

#[cfg(feature = "try-runtime")]
impl frame_try_runtime::TryRuntime<Block> for Runtime {
fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) {
let weight = Executive::try_runtime_upgrade(checks).unwrap();
(weight, RuntimeBlockWeights::get().max_block)
}

fn execute_block(
block: Block,
state_root_check: bool,
signature_check: bool,
select: frame_try_runtime::TryStateSelect,
) -> Weight {
// NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to
// have a backtrace here.
Executive::try_execute_block(block, state_root_check, signature_check, select).unwrap()
}
}

#[cfg(feature = "runtime-benchmarks")]
impl frame_benchmarking::Benchmark<Block> for Runtime {
fn benchmark_metadata(extra: bool) -> (
Vec<frame_benchmarking::BenchmarkList>,
Vec<frame_support::traits::StorageInfo>,
) {
use frame_benchmarking::{Benchmarking, BenchmarkList};
use frame_support::traits::StorageInfoTrait;
use frame_system_benchmarking::Pallet as SystemBench;
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;

let mut list = Vec::<BenchmarkList>::new();
list_benchmarks!(list, extra);

let storage_info = AllPalletsWithSystem::storage_info();
(list, storage_info)
}

fn dispatch_benchmark(
config: frame_benchmarking::BenchmarkConfig
) -> Result<Vec<frame_benchmarking::BenchmarkBatch>, sp_runtime::RuntimeString> {
use frame_benchmarking::{BenchmarkError, Benchmarking, BenchmarkBatch};

use frame_system_benchmarking::Pallet as SystemBench;
impl frame_system_benchmarking::Config for Runtime {
fn setup_set_code_requirements(code: &Vec<u8>) -> Result<(), BenchmarkError> {
ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32);
Ok(())
}

fn verify_set_code() {
System::assert_last_event(cumulus_pallet_parachain_system::Event::<Runtime>::ValidationFunctionStored.into());
}
}

use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
impl cumulus_pallet_session_benchmarking::Config for Runtime {}

use frame_support::traits::WhitelistedStorageKeys;
let whitelist = AllPalletsWithSystem::whitelisted_storage_keys();

let mut batches = Vec::<BenchmarkBatch>::new();
let params = (&config, &whitelist);
add_benchmarks!(params, batches);

if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) }
Ok(batches)
}
}

impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
build_state::<RuntimeGenesisConfig>(config)
}

fn get_preset(id: &Option<sp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
get_preset::<RuntimeGenesisConfig>(id, |_| None)
}

fn preset_names() -> Vec<sp_genesis_builder::PresetId> {
Default::default()
}
}
}

Check warning on line 991 in runtime/devnet/src/lib.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for a function

warning: missing documentation for a function --> runtime/devnet/src/lib.rs:644:1 | 644 | / impl_runtime_apis! { 645 | | 646 | | impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime { 647 | | fn slot_duration() -> sp_consensus_aura::SlotDuration { ... | 990 | | } 991 | | } | |_^ | = note: this warning originates in the macro `impl_runtime_apis` (in Nightly builds, run with -Z macro-backtrace for more info)

Check warning on line 991 in runtime/devnet/src/lib.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for a module

warning: missing documentation for a module --> runtime/devnet/src/lib.rs:644:1 | 644 | / impl_runtime_apis! { 645 | | 646 | | impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime { 647 | | fn slot_duration() -> sp_consensus_aura::SlotDuration { ... | 990 | | } 991 | | } | |_^ | = note: this warning originates in the macro `impl_runtime_apis` (in Nightly builds, run with -Z macro-backtrace for more info)

Check warning on line 991 in runtime/devnet/src/lib.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for a constant

warning: missing documentation for a constant --> runtime/devnet/src/lib.rs:644:1 | 644 | / impl_runtime_apis! { 645 | | 646 | | impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime { 647 | | fn slot_duration() -> sp_consensus_aura::SlotDuration { ... | 990 | | } 991 | | } | |_^ | = note: this warning originates in the macro `impl_runtime_apis` (in Nightly builds, run with -Z macro-backtrace for more info)

Check warning on line 991 in runtime/devnet/src/lib.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for a struct

warning: missing documentation for a struct --> runtime/devnet/src/lib.rs:644:1 | 644 | / impl_runtime_apis! { 645 | | 646 | | impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime { 647 | | fn slot_duration() -> sp_consensus_aura::SlotDuration { ... | 990 | | } 991 | | } | |_^ | = note: this warning originates in the macro `impl_runtime_apis` (in Nightly builds, run with -Z macro-backtrace for more info)

cumulus_pallet_parachain_system::register_validate_block! {
Runtime = Runtime,
BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::<Runtime, Executive>,
}

#[cfg(test)]
mod tests {
// Ensures that the account id lookup does not perform any state reads. When this changes,
// `pallet_api::fungibles` dispatchables need to be re-evaluated.
#[test]
fn test_lookup_config() {
use std::any::TypeId;

use crate::Runtime;

// Ensures that the account id lookup does not perform any state reads. When this changes,
// `pallet_api::fungibles` dispatchables need to be re-evaluated.
#[test]
fn test_lookup_config() {
type ExpectedLookup = sp_runtime::traits::AccountIdLookup<sp_runtime::AccountId32, ()>;
type ConfigLookup = <Runtime as frame_system::Config>::Lookup;

let expected_type_id = TypeId::of::<ExpectedLookup>();
let config_type_id = TypeId::of::<ConfigLookup>();

assert_eq!(config_type_id, expected_type_id);
}
assert_eq!(
TypeId::of::<<Runtime as frame_system::Config>::Lookup>(),
TypeId::of::<sp_runtime::traits::AccountIdLookup<sp_runtime::AccountId32, ()>>()
);
}
Loading
Loading