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

schemas: PoV compatible changes #1743

Merged
merged 19 commits into from
Nov 13, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions Cargo.lock

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

17 changes: 17 additions & 0 deletions common/primitives/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,27 @@
pub settings: Vec<SchemaSetting>,
}

/// RPC Response form for a Schema Info
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[derive(Clone, Encode, Decode, PartialEq, Debug, TypeInfo, Eq)]
pub struct SchemaInfoResponse {

Check warning on line 79 in common/primitives/src/schema.rs

View check run for this annotation

Codecov / codecov/patch

common/primitives/src/schema.rs#L77-L79

Added lines #L77 - L79 were not covered by tests
/// The unique identifier for this Schema
pub schema_id: SchemaId,
/// The model format type for how the schema model is represented
pub model_type: ModelType,
/// The payload location
pub payload_location: PayloadLocation,
/// grants for the schema
pub settings: Vec<SchemaSetting>,
}

/// This allows other pallets to resolve Schema information. With generic SchemaId
pub trait SchemaProvider<SchemaId> {
/// Gets the Schema details associated with this `SchemaId` if any
fn get_schema_by_id(schema_id: SchemaId) -> Option<SchemaResponse>;

/// Gets the Schema Info associated with this `SchemaId` if any
fn get_schema_info_by_id(schema_id: SchemaId) -> Option<SchemaInfoResponse>;
}

/// This allows other Pallets to check validity of schema ids.
Expand Down
46 changes: 46 additions & 0 deletions designdocs/schema_v2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# On Chain Message Storage
aramikm marked this conversation as resolved.
Show resolved Hide resolved

## Context and Scope
The proposed feature consists of changes that is going to be one (or more) pallet(s) in runtime of a
Substrate based blockchain, and it will be used in all environments including production.

## Problem Statement
After introduction of **Proof of Validity** or **PoV** in runtime weights, all pallets should be
re-evaluated and refactored if necessary to minimize the usage of **PoV**. This is to ensure all
important operations are scalable.
This document tries to propose some changes on **Schemas** pallet to optimize the **PoV** size.

## Goals
- Minimizing Weights including **execution times** and **PoV** size.

## Proposal
Split Schemas into `SchemaInfo` and `payload` would allow lower **PoV** when verifying schema existence
or compatibility.

### Main Storage types
- **SchemaInfos**
- _Type_: `StorageMap<SchemaId, SchemaInfo>`
- _Purpose_: Main structure To store related properties of any schema
index
- **SchemaPayloads**
- _Type_: `StorageMap<SchemaId, BoundedVec<u8>>`
- _Purpose_: Stores the payload or model for each schema


### On Chain Structure
Following is a proposed data structure for storing schema information on chain.
```rust
pub struct SchemaInfo {
/// The type of model (AvroBinary, Parquet, etc.)
pub model_type: ModelType,
/// The payload location
pub payload_location: PayloadLocation,
/// additional control settings for the schema
pub settings: SchemaSettings,
}
```
### Expected PoV improvements
This PoV improvement would not affect extrinsic weights in this pallet, but it would directly affect any
pallet that is dependent on **Schemas** pallet. Some of these pallets are **Messages** and
**Stateful-Storage**. After these changes we are expecting see to see around 30-60KiB decrease in PoV
for `MaxEncodedLen` mode.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice

2 changes: 1 addition & 1 deletion e2e/package-lock.json

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

4 changes: 2 additions & 2 deletions pallets/messages/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ pub mod pallet {
.try_into()
.map_err(|_| Error::<T>::ExceedsMaxMessagePayloadSizeBytes)?;

if let Some(schema) = T::SchemaProvider::get_schema_by_id(schema_id) {
if let Some(schema) = T::SchemaProvider::get_schema_info_by_id(schema_id) {
ensure!(
schema.payload_location == PayloadLocation::IPFS,
Error::<T>::InvalidPayloadLocation
Expand Down Expand Up @@ -283,7 +283,7 @@ pub mod pallet {
let bounded_payload: BoundedVec<u8, T::MessagesMaxPayloadSizeBytes> =
payload.try_into().map_err(|_| Error::<T>::ExceedsMaxMessagePayloadSizeBytes)?;

if let Some(schema) = T::SchemaProvider::get_schema_by_id(schema_id) {
if let Some(schema) = T::SchemaProvider::get_schema_info_by_id(schema_id) {
ensure!(
schema.payload_location == PayloadLocation::OnChain,
Error::<T>::InvalidPayloadLocation
Expand Down
11 changes: 11 additions & 0 deletions pallets/messages/src/tests/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,17 @@ impl SchemaProvider<u16> for SchemaHandler {
settings: Vec::new(),
})
}

fn get_schema_info_by_id(schema_id: u16) -> Option<SchemaInfoResponse> {
Self::get_schema_by_id(schema_id).and_then(|schema| {
Some(SchemaInfoResponse {
schema_id: schema.schema_id,
settings: schema.settings,
model_type: schema.model_type,
payload_location: schema.payload_location,
})
})
}
}

impl pallet_messages::Config for Test {
Expand Down
96 changes: 48 additions & 48 deletions pallets/messages/src/weights.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
//! Autogenerated weights for pallet_messages
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
//! DATE: 2023-10-30, STEPS: `20`, REPEAT: `10`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! DATE: 2023-11-10, STEPS: `20`, REPEAT: `10`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! WORST CASE MAP SIZE: `1000000`
//! HOSTNAME: `benchmark-runner-44wtw-bw25f`, CPU: `Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz`
//! HOSTNAME: `benchmark-runner-44wtw-d4nrm`, CPU: `Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz`
//! EXECUTION: , WASM-EXECUTION: Compiled, CHAIN: Some("frequency-bench"), DB CACHE: 1024

// Executed Command:
Expand Down Expand Up @@ -56,78 +56,78 @@ pub trait WeightInfo {
/// Weights for pallet_messages using the Substrate node and recommended hardware.
pub struct SubstrateWeight<T>(PhantomData<T>);
impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
/// Storage: `Schemas::Schemas` (r:1 w:0)
/// Proof: `Schemas::Schemas` (`max_values`: None, `max_size`: Some(65518), added: 67993, mode: `Measured`)
/// Storage: `Schemas::SchemaInfos` (r:1 w:0)
/// Proof: `Schemas::SchemaInfos` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`)
/// Storage: `Msa::PublicKeyToMsaId` (r:1 w:0)
/// Proof: `Msa::PublicKeyToMsaId` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `Measured`)
/// Proof: `Msa::PublicKeyToMsaId` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`)
/// Storage: `Msa::DelegatorAndProviderToDelegation` (r:1 w:0)
/// Proof: `Msa::DelegatorAndProviderToDelegation` (`max_values`: None, `max_size`: Some(217), added: 2692, mode: `Measured`)
/// Storage: `Messages::Messages` (r:1 w:1)
/// Proof: `Messages::Messages` (`max_values`: None, `max_size`: Some(618624), added: 621099, mode: `Measured`)
/// Proof: `Msa::DelegatorAndProviderToDelegation` (`max_values`: None, `max_size`: Some(217), added: 2692, mode: `MaxEncodedLen`)
/// Storage: `Messages::MessagesV2` (r:0 w:1)
/// Proof: `Messages::MessagesV2` (`max_values`: None, `max_size`: Some(3123), added: 5598, mode: `MaxEncodedLen`)
/// The range of component `n` is `[0, 3071]`.
fn add_onchain_message(n: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `9664`
// Estimated: `22039`
// Minimum execution time: 47_640_000 picoseconds.
Weight::from_parts(49_189_621, 22039)
// Standard Error: 82
.saturating_add(Weight::from_parts(938, 0).saturating_mul(n.into()))
.saturating_add(T::DbWeight::get().reads(4_u64))
// Measured: `402`
// Estimated: `12592`
// Minimum execution time: 32_164_000 picoseconds.
Weight::from_parts(33_345_645, 12592)
// Standard Error: 43
.saturating_add(Weight::from_parts(848, 0).saturating_mul(n.into()))
.saturating_add(T::DbWeight::get().reads(3_u64))
.saturating_add(T::DbWeight::get().writes(1_u64))
}
/// Storage: `Schemas::Schemas` (r:1 w:0)
/// Proof: `Schemas::Schemas` (`max_values`: None, `max_size`: Some(65518), added: 67993, mode: `Measured`)
/// Storage: `Schemas::SchemaInfos` (r:1 w:0)
/// Proof: `Schemas::SchemaInfos` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`)
/// Storage: `Msa::PublicKeyToMsaId` (r:1 w:0)
/// Proof: `Msa::PublicKeyToMsaId` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `Measured`)
/// Storage: `Messages::Messages` (r:1 w:1)
/// Proof: `Messages::Messages` (`max_values`: None, `max_size`: Some(618624), added: 621099, mode: `Measured`)
/// Proof: `Msa::PublicKeyToMsaId` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`)
/// Storage: `Messages::MessagesV2` (r:0 w:1)
/// Proof: `Messages::MessagesV2` (`max_values`: None, `max_size`: Some(3123), added: 5598, mode: `MaxEncodedLen`)
fn add_ipfs_message() -> Weight {
// Proof Size summary in bytes:
// Measured: `7958`
// Estimated: `20333`
// Minimum execution time: 43_681_000 picoseconds.
Weight::from_parts(45_218_000, 20333)
.saturating_add(T::DbWeight::get().reads(3_u64))
// Measured: `790`
// Estimated: `12423`
// Minimum execution time: 31_839_000 picoseconds.
Weight::from_parts(32_576_000, 12423)
.saturating_add(T::DbWeight::get().reads(2_u64))
.saturating_add(T::DbWeight::get().writes(1_u64))
}
}

// For backwards compatibility and tests
impl WeightInfo for () {
/// Storage: `Schemas::Schemas` (r:1 w:0)
/// Proof: `Schemas::Schemas` (`max_values`: None, `max_size`: Some(65518), added: 67993, mode: `Measured`)
/// Storage: `Schemas::SchemaInfos` (r:1 w:0)
/// Proof: `Schemas::SchemaInfos` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`)
/// Storage: `Msa::PublicKeyToMsaId` (r:1 w:0)
/// Proof: `Msa::PublicKeyToMsaId` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `Measured`)
/// Proof: `Msa::PublicKeyToMsaId` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`)
/// Storage: `Msa::DelegatorAndProviderToDelegation` (r:1 w:0)
/// Proof: `Msa::DelegatorAndProviderToDelegation` (`max_values`: None, `max_size`: Some(217), added: 2692, mode: `Measured`)
/// Storage: `Messages::Messages` (r:1 w:1)
/// Proof: `Messages::Messages` (`max_values`: None, `max_size`: Some(618624), added: 621099, mode: `Measured`)
/// Proof: `Msa::DelegatorAndProviderToDelegation` (`max_values`: None, `max_size`: Some(217), added: 2692, mode: `MaxEncodedLen`)
/// Storage: `Messages::MessagesV2` (r:0 w:1)
/// Proof: `Messages::MessagesV2` (`max_values`: None, `max_size`: Some(3123), added: 5598, mode: `MaxEncodedLen`)
/// The range of component `n` is `[0, 3071]`.
fn add_onchain_message(n: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `9664`
// Estimated: `22039`
// Minimum execution time: 47_640_000 picoseconds.
Weight::from_parts(49_189_621, 22039)
// Standard Error: 82
.saturating_add(Weight::from_parts(938, 0).saturating_mul(n.into()))
.saturating_add(RocksDbWeight::get().reads(4_u64))
// Measured: `402`
// Estimated: `12592`
// Minimum execution time: 32_164_000 picoseconds.
Weight::from_parts(33_345_645, 12592)
// Standard Error: 43
.saturating_add(Weight::from_parts(848, 0).saturating_mul(n.into()))
.saturating_add(RocksDbWeight::get().reads(3_u64))
.saturating_add(RocksDbWeight::get().writes(1_u64))
}
/// Storage: `Schemas::Schemas` (r:1 w:0)
/// Proof: `Schemas::Schemas` (`max_values`: None, `max_size`: Some(65518), added: 67993, mode: `Measured`)
/// Storage: `Schemas::SchemaInfos` (r:1 w:0)
/// Proof: `Schemas::SchemaInfos` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`)
/// Storage: `Msa::PublicKeyToMsaId` (r:1 w:0)
/// Proof: `Msa::PublicKeyToMsaId` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `Measured`)
/// Storage: `Messages::Messages` (r:1 w:1)
/// Proof: `Messages::Messages` (`max_values`: None, `max_size`: Some(618624), added: 621099, mode: `Measured`)
/// Proof: `Msa::PublicKeyToMsaId` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`)
/// Storage: `Messages::MessagesV2` (r:0 w:1)
/// Proof: `Messages::MessagesV2` (`max_values`: None, `max_size`: Some(3123), added: 5598, mode: `MaxEncodedLen`)
fn add_ipfs_message() -> Weight {
// Proof Size summary in bytes:
// Measured: `7958`
// Estimated: `20333`
// Minimum execution time: 43_681_000 picoseconds.
Weight::from_parts(45_218_000, 20333)
.saturating_add(RocksDbWeight::get().reads(3_u64))
// Measured: `790`
// Estimated: `12423`
// Minimum execution time: 31_839_000 picoseconds.
Weight::from_parts(32_576_000, 12423)
.saturating_add(RocksDbWeight::get().reads(2_u64))
.saturating_add(RocksDbWeight::get().writes(1_u64))
}
}
1 change: 1 addition & 0 deletions pallets/schemas/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ targets = ["x86_64-unknown-linux-gnu"]
codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = [
"derive",
] }
log = { version = "0.4.17", default-features = false }
frame-benchmarking = { default-features = false, git = "https://github.com/paritytech/polkadot-sdk", optional = true, branch = "release-polkadot-v1.1.0" }
frame-support = { default-features = false, git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" }
frame-system = { default-features = false, git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" }
Expand Down
6 changes: 3 additions & 3 deletions pallets/schemas/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ benchmarks! {
}: _(RawOrigin::Signed(sender), schema_input, model_type, payload_location)
verify {
ensure!(SchemasPallet::<T>::get_current_schema_identifier_maximum() > 0, "Created schema count should be > 0");
ensure!(SchemasPallet::<T>::get_schema(1).is_some(), "Created schema should exist");
ensure!(SchemasPallet::<T>::get_schema_info(1).is_some(), "Created schema should exist");
}

create_schema_via_governance {
Expand All @@ -55,7 +55,7 @@ benchmarks! {
}: _(RawOrigin::Root, sender.clone(), schema_input, model_type, payload_location, BoundedVec::default())
verify {
ensure!(SchemasPallet::<T>::get_current_schema_identifier_maximum() > 0, "Created schema count should be > 0");
ensure!(SchemasPallet::<T>::get_schema(1).is_some(), "Created schema should exist");
ensure!(SchemasPallet::<T>::get_schema_info(1).is_some(), "Created schema should exist");
}

propose_to_create_schema {
Expand All @@ -80,7 +80,7 @@ benchmarks! {
}: _(RawOrigin::Signed(sender), schema_input, model_type, payload_location, BoundedVec::default())
verify {
ensure!(SchemasPallet::<T>::get_current_schema_identifier_maximum() > 0, "Created schema count should be > 0");
ensure!(SchemasPallet::<T>::get_schema(1).is_some(), "Created schema should exist");
ensure!(SchemasPallet::<T>::get_schema_info(1).is_some(), "Created schema should exist");
}

set_max_schema_model_bytes {
Expand Down
Loading
Loading