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

Implement pallet view function queries #4722

Draft
wants to merge 47 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
264b902
Add view functions parsing and definition
ascjones May 20, 2024
987802c
Add to view functions mod definition
ascjones May 20, 2024
4f7a513
Adding traits and types and wiring up expansion
ascjones May 21, 2024
e8af3c2
Use ToTokens for expansion
ascjones May 22, 2024
7038710
fmtl
ascjones May 22, 2024
9267519
Adding generics etc to query struct
ascjones May 22, 2024
c6a4e42
fmt
ascjones May 22, 2024
140f7d9
example with args
ascjones May 23, 2024
23b9ebf
add example for testing
ascjones May 23, 2024
86c5f2f
wire up codegen for view functions
ascjones May 24, 2024
f42c5c4
Generate DispatchQuery impl
ascjones May 24, 2024
ac6643e
Wire up runtime PalletQuery
ascjones May 24, 2024
2ea6158
Wire up query args
ascjones May 28, 2024
8b56a84
Add get value with args query
ascjones May 28, 2024
06f9ffc
decode_all
ascjones May 29, 2024
9ed181b
Merge branch 'master' into aj/view-functions
ascjones May 29, 2024
cd52010
Docs
ascjones May 30, 2024
44707b3
Generate suffix from view_fn signature
ascjones May 30, 2024
afa1490
separate suffix id
ascjones May 30, 2024
f97a40c
WIP expand runtime level query
ascjones May 30, 2024
ddff4d0
Implement `DispatchQuery` for pallets even without queries
ascjones May 31, 2024
538ea8a
WIP
ascjones May 31, 2024
db616f5
Use pallet name hash as query id prefix
ascjones Jun 3, 2024
fd3318b
Commented out code
ascjones Jun 3, 2024
a49e5f3
Inject runtime type
ascjones Jun 3, 2024
dd651ac
tidy
ascjones Jun 3, 2024
c7ff6c9
Add pallet with instances
ascjones Jun 3, 2024
5a8e559
Pallet instances tests
ascjones Jun 3, 2024
e71b9de
Refactor tests
ascjones Jun 3, 2024
22dd94b
Move execute from codegen to trait
ascjones Jun 4, 2024
117ac87
WIP query runtime api
ascjones Jun 4, 2024
def7807
WIP query metadata
ascjones Jun 5, 2024
fbd4d3a
Fix up metadata generation
ascjones Jun 5, 2024
04d763e
Add queries section to custom metadata
ascjones Jun 6, 2024
86f35eb
Comment
ascjones Jun 6, 2024
885fd3a
fix metadata gen
ascjones Jun 6, 2024
3b563fb
move runtime api and core types to primitives
ascjones Jun 6, 2024
43de841
Add some RuntimeQuery types
ascjones Jun 7, 2024
ebcf283
Fix up westend runtime
ascjones Jun 7, 2024
f0b1f36
Add RuntimeQuery derives
ascjones Jun 7, 2024
c6dd8a5
Wire up runtime API query methods
ascjones Jun 7, 2024
81150ba
Use Runtime::execute_query generated method
ascjones Jun 7, 2024
11cb3db
Fmt
ascjones Jun 7, 2024
18b7deb
Merge branch 'master' into aj/view-functions
ascjones Jun 7, 2024
21eeba7
Merge branch 'master' into aj/view-functions
ascjones Jun 7, 2024
7b82da6
Master.into()
kianenigma Oct 8, 2024
fd0896c
Merge branch 'master' into aj/view-functions
ascjones Oct 9, 2024
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
17 changes: 17 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -922,6 +922,7 @@ pallet-example-offchain-worker = { path = "substrate/frame/examples/offchain-wor
pallet-example-single-block-migrations = { path = "substrate/frame/examples/single-block-migrations", default-features = false }
pallet-example-split = { path = "substrate/frame/examples/split", default-features = false }
pallet-example-tasks = { path = "substrate/frame/examples/tasks", default-features = false }
pallet-example-view-functions = { path = "substrate/frame/examples/view-functions", default-features = false }
pallet-examples = { path = "substrate/frame/examples" }
pallet-fast-unstake = { path = "substrate/frame/fast-unstake", default-features = false }
pallet-glutton = { path = "substrate/frame/glutton", default-features = false }
Expand Down
3 changes: 2 additions & 1 deletion polkadot/runtime/westend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1548,7 +1548,8 @@ mod runtime {
RuntimeHoldReason,
RuntimeSlashReason,
RuntimeLockId,
RuntimeTask
RuntimeTask,
RuntimeQuery
)]
pub struct Runtime;

Expand Down
11 changes: 9 additions & 2 deletions substrate/bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ use sp_consensus_beefy::{
mmr::MmrLeafVersion,
};
use sp_consensus_grandpa::AuthorityId as GrandpaId;
use sp_core::{crypto::KeyTypeId, OpaqueMetadata, H160};
use sp_core::{crypto::KeyTypeId, OpaqueMetadata, QueryDispatchError, QueryId, H160};
use sp_inherents::{CheckInherentsResult, InherentData};
use sp_runtime::{
create_runtime_str,
Expand Down Expand Up @@ -2283,7 +2283,8 @@ mod runtime {
RuntimeHoldReason,
RuntimeSlashReason,
RuntimeLockId,
RuntimeTask
RuntimeTask,
RuntimeQuery
)]
pub struct Runtime;

Expand Down Expand Up @@ -2726,6 +2727,12 @@ impl_runtime_apis! {
}
}

impl sp_api::RuntimeQuery<Block> for Runtime {
fn execute_query(query_id: QueryId, query: Vec<u8>) -> Result<Vec<u8>, QueryDispatchError> {
Runtime::execute_query(query_id, query)
}
}

impl sp_block_builder::BlockBuilder<Block> for Runtime {
fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
Executive::apply_extrinsic(extrinsic)
Expand Down
4 changes: 4 additions & 0 deletions substrate/frame/examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ pallet-example-offchain-worker = { workspace = true }
pallet-example-split = { workspace = true }
pallet-example-single-block-migrations = { workspace = true }
pallet-example-tasks = { workspace = true }
pallet-example-view-functions = { workspace = true }


[features]
default = ["std"]
Expand All @@ -38,6 +40,7 @@ std = [
"pallet-example-single-block-migrations/std",
"pallet-example-split/std",
"pallet-example-tasks/std",
"pallet-example-view-functions/std",
]
try-runtime = [
"pallet-default-config-example/try-runtime",
Expand All @@ -48,4 +51,5 @@ try-runtime = [
"pallet-example-single-block-migrations/try-runtime",
"pallet-example-split/try-runtime",
"pallet-example-tasks/try-runtime",
"pallet-example-view-functions/try-runtime",
]
3 changes: 3 additions & 0 deletions substrate/frame/examples/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,7 @@
//!
//! - [`pallet_example_tasks`]: This pallet demonstrates the use of `Tasks` to execute service work.
//!
//! - [`pallet_example_view_functions`]: This pallet demonstrates the use of view functions to query
//! pallet state.
//!
//! **Tip**: Use `cargo doc --package <pallet-name> --open` to view each pallet's documentation.
55 changes: 55 additions & 0 deletions substrate/frame/examples/view-functions/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
[package]
name = "pallet-example-view-functions"
version = "1.0.0"
authors.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
description = "Pallet to demonstrate the usage of view functions to query pallet state"

[lints]
workspace = true

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
codec = { package = "parity-scale-codec", version = "3.6.12", default-features = false }
log = { workspace = true }
scale-info = { version = "2.11.1", default-features = false, features = ["derive"] }

frame-support = { path = "../../support", default-features = false }
frame-system = { path = "../../system", default-features = false }

sp-io = { path = "../../../primitives/io", default-features = false }
sp-runtime = { path = "../../../primitives/runtime", default-features = false }
sp-std = { path = "../../../primitives/std", default-features = false }
sp-core = { default-features = false, path = "../../../primitives/core" }

frame-benchmarking = { path = "../../benchmarking", default-features = false, optional = true }

[features]
default = ["std"]
std = [
"codec/std",
"frame-benchmarking?/std",
"frame-support/std",
"frame-system/std",
"log/std",
"scale-info/std",
"sp-core/std",
"sp-io/std",
"sp-runtime/std",
"sp-std/std",
]
runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
]
try-runtime = [
"frame-support/try-runtime",
"frame-system/try-runtime",
"sp-runtime/try-runtime",
]
114 changes: 114 additions & 0 deletions substrate/frame/examples/view-functions/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// This file is part of Substrate.

// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! This pallet demonstrates the use of the `pallet::view_functions` api for service work.
#![cfg_attr(not(feature = "std"), no_std)]

pub mod mock;
pub mod tests;

use frame_support::Parameter;
use scale_info::TypeInfo;

pub struct SomeType1;
impl From<SomeType1> for u64 {
fn from(_t: SomeType1) -> Self {
0u64
}
}

pub trait SomeAssociation1 {
type _1: Parameter + codec::MaxEncodedLen + TypeInfo;
}
impl SomeAssociation1 for u64 {
type _1 = u64;
}

#[frame_support::pallet]
pub mod pallet {
use super::*;
use frame_support::pallet_prelude::*;

#[pallet::error]
pub enum Error<T> {}

#[pallet::config]
pub trait Config: frame_system::Config {}

#[pallet::pallet]
pub struct Pallet<T>(_);

#[pallet::storage]
pub type SomeValue<T: Config> = StorageValue<_, u32>;

#[pallet::storage]
pub type SomeMap<T: Config> = StorageMap<_, Twox64Concat, u32, u32, OptionQuery>;

#[pallet::view_functions]
impl<T: Config> Pallet<T>
where
T::AccountId: From<SomeType1> + SomeAssociation1,
{
/// Query value no args.
pub fn get_value() -> Option<u32> {
SomeValue::<T>::get()
}

/// Query value with args.
pub fn get_value_with_arg(key: u32) -> Option<u32> {
SomeMap::<T>::get(key)
}
}
}

#[frame_support::pallet]
pub mod pallet2 {
use super::*;
use frame_support::pallet_prelude::*;

#[pallet::error]
pub enum Error<T, I = ()> {}

#[pallet::config]
pub trait Config<I: 'static = ()>: frame_system::Config {}

#[pallet::pallet]
pub struct Pallet<T, I = ()>(PhantomData<(T, I)>);

#[pallet::storage]
pub type SomeValue<T: Config<I>, I: 'static = ()> = StorageValue<_, u32>;

#[pallet::storage]
pub type SomeMap<T: Config<I>, I: 'static = ()> =
StorageMap<_, Twox64Concat, u32, u32, OptionQuery>;

#[pallet::view_functions]
impl<T: Config<I>, I: 'static> Pallet<T, I>
where
T::AccountId: From<SomeType1> + SomeAssociation1,
{
/// Query value no args.
pub fn get_value() -> Option<u32> {
SomeValue::<T, I>::get()
}

/// Query value with args.
pub fn get_value_with_arg(key: u32) -> Option<u32> {
SomeMap::<T, I>::get(key)
}
}
}
55 changes: 55 additions & 0 deletions substrate/frame/examples/view-functions/src/mock.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// This file is part of Substrate.

// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Mock runtime for `view-functions-example` tests.
#![cfg(test)]

use crate::{pallet, pallet2};
use frame_support::derive_impl;
use sp_runtime::testing::TestXt;

pub type AccountId = u32;
pub type Balance = u32;

type Block = frame_system::mocking::MockBlock<Runtime>;
frame_support::construct_runtime!(
pub enum Runtime {
System: frame_system,
ViewFunctionsExample: pallet,
ViewFunctionsInstance: pallet2,
ViewFunctionsInstance1: pallet2::<Instance1>,
}
);

pub type Extrinsic = TestXt<RuntimeCall, ()>;

#[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
impl frame_system::Config for Runtime {
type Block = Block;
}

impl pallet::Config for Runtime {}
impl pallet2::Config<pallet2::Instance1> for Runtime {}

impl pallet2::Config for Runtime {}

pub fn new_test_ext() -> sp_io::TestExternalities {
use sp_runtime::BuildStorage;

let t = RuntimeGenesisConfig { system: Default::default() }.build_storage().unwrap();
t.into()
}
Loading
Loading