-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Remark storage #10698
Remark storage #10698
Changes from all commits
cabb3f1
aaa818c
e3ec7ad
88b8627
dbbe384
c92b9bd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
[package] | ||
name = "pallet-remark" | ||
version = "4.0.0-dev" | ||
authors = ["Parity Technologies <[email protected]>"] | ||
edition = "2021" | ||
license = "Apache-2.0" | ||
homepage = "https://substrate.io" | ||
repository = "https://github.com/paritytech/substrate/" | ||
description = "Remark storage pallet" | ||
readme = "README.md" | ||
|
||
[package.metadata.docs.rs] | ||
targets = ["x86_64-unknown-linux-gnu"] | ||
|
||
[dependencies] | ||
serde = { version = "1.0.136", optional = true } | ||
codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false } | ||
scale-info = { version = "2.0.1", default-features = false, features = ["derive"] } | ||
frame-support = { version = "4.0.0-dev", default-features = false, path = "../support" } | ||
frame-system = { version = "4.0.0-dev", default-features = false, path = "../system" } | ||
sp-runtime = { version = "6.0.0", default-features = false, path = "../../primitives/runtime" } | ||
sp-std = { version = "4.0.0", default-features = false, path = "../../primitives/std" } | ||
sp-io = { version = "6.0.0", default-features = false, path = "../../primitives/io" } | ||
sp-core = { version = "6.0.0", default-features = false, path = "../../primitives/core" } | ||
frame-benchmarking = { version = "4.0.0-dev", default-features = false, path = "../benchmarking", optional = true } | ||
|
||
[dev-dependencies] | ||
sp-core = { version = "6.0.0", path = "../../primitives/core", default-features = false } | ||
|
||
[features] | ||
default = ["std"] | ||
runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks"] | ||
std = [ | ||
"serde", | ||
"codec/std", | ||
"scale-info/std", | ||
"sp-runtime/std", | ||
"frame-support/std", | ||
"frame-system/std", | ||
"sp-io/std", | ||
"sp-std/std", | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Remark Storage Pallet | ||
|
||
Allows storing arbitrary data off chain. | ||
|
||
|
||
License: Apache-2.0 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// This file is part of Substrate. | ||
|
||
// Copyright (C) 2021-2022 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. | ||
|
||
//! Benchmarks for remarks pallet | ||
|
||
#![cfg(feature = "runtime-benchmarks")] | ||
|
||
use super::*; | ||
use frame_benchmarking::{benchmarks, whitelisted_caller}; | ||
use frame_system::{EventRecord, Pallet as System, RawOrigin}; | ||
use sp_std::*; | ||
|
||
#[cfg(test)] | ||
use crate::Pallet as Remark; | ||
|
||
fn assert_last_event<T: Config>(generic_event: <T as Config>::Event) { | ||
let events = System::<T>::events(); | ||
let system_event: <T as frame_system::Config>::Event = generic_event.into(); | ||
let EventRecord { event, .. } = &events[events.len() - 1]; | ||
assert_eq!(event, &system_event); | ||
} | ||
|
||
benchmarks! { | ||
store { | ||
let l in 1 .. 1024*1024; | ||
let caller: T::AccountId = whitelisted_caller(); | ||
}: _(RawOrigin::Signed(caller.clone()), vec![0u8; l as usize]) | ||
verify { | ||
assert_last_event::<T>(Event::Stored { sender: caller, content_hash: sp_io::hashing::blake2_256(&vec![0u8; l as usize]).into() }.into()); | ||
} | ||
|
||
impl_benchmark_test_suite!(Remark, crate::mock::new_test_ext(), crate::mock::Test); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
// This file is part of Substrate. | ||
|
||
// Copyright (C) 2017-2022 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. | ||
|
||
//! Remark storage pallet. Indexes remarks and stores them off chain. | ||
|
||
// Ensure we're `no_std` when compiling for Wasm. | ||
#![cfg_attr(not(feature = "std"), no_std)] | ||
|
||
mod benchmarking; | ||
pub mod weights; | ||
|
||
#[cfg(test)] | ||
mod mock; | ||
#[cfg(test)] | ||
mod tests; | ||
|
||
use sp_std::prelude::*; | ||
|
||
// Re-export pallet items so that they can be accessed from the crate namespace. | ||
pub use pallet::*; | ||
pub use weights::WeightInfo; | ||
|
||
#[frame_support::pallet] | ||
pub mod pallet { | ||
use super::*; | ||
use frame_support::pallet_prelude::*; | ||
use frame_system::pallet_prelude::*; | ||
|
||
#[pallet::config] | ||
pub trait Config: frame_system::Config { | ||
/// The overarching event type. | ||
type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>; | ||
/// Weight information for extrinsics in this pallet. | ||
type WeightInfo: WeightInfo; | ||
} | ||
|
||
#[pallet::error] | ||
pub enum Error<T> { | ||
/// Attempting to store empty data. | ||
Empty, | ||
/// Attempted to call `store` outside of block execution. | ||
BadContext, | ||
} | ||
|
||
#[pallet::pallet] | ||
#[pallet::without_storage_info] | ||
pub struct Pallet<T>(_); | ||
|
||
#[pallet::call] | ||
impl<T: Config> Pallet<T> { | ||
/// Index and store data off chain. | ||
#[pallet::weight(T::WeightInfo::store(remark.len() as u32))] | ||
pub fn store(origin: OriginFor<T>, remark: Vec<u8>) -> DispatchResultWithPostInfo { | ||
ensure!(!remark.is_empty(), Error::<T>::Empty); | ||
let sender = ensure_signed(origin)?; | ||
let content_hash = sp_io::hashing::blake2_256(&remark); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why don't we use the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay, I have now seen it is because of the transaction indexing. But that should have maybe been generic as well. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hashing scheme has to match the scheme supported by the IPFS bitswap server. The generic parameter would need to be propagated to |
||
let extrinsic_index = <frame_system::Pallet<T>>::extrinsic_index() | ||
.ok_or_else(|| Error::<T>::BadContext)?; | ||
sp_io::transaction_index::index(extrinsic_index, remark.len() as u32, content_hash); | ||
Self::deposit_event(Event::Stored { sender, content_hash: content_hash.into() }); | ||
Ok(().into()) | ||
} | ||
} | ||
|
||
#[pallet::event] | ||
#[pallet::generate_deposit(pub(super) fn deposit_event)] | ||
pub enum Event<T: Config> { | ||
/// Stored data off chain. | ||
Stored { sender: T::AccountId, content_hash: sp_core::H256 }, | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
// This file is part of Substrate. | ||
|
||
// Copyright (C) 2019-2022 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. | ||
|
||
//! Test environment for remarks pallet. | ||
|
||
use crate as pallet_remark; | ||
use frame_support::traits::{ConstU16, ConstU32, ConstU64}; | ||
use sp_core::H256; | ||
use sp_runtime::{ | ||
testing::Header, | ||
traits::{BlakeTwo256, IdentityLookup}, | ||
BuildStorage, | ||
}; | ||
|
||
type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Test>; | ||
pub type Block = frame_system::mocking::MockBlock<Test>; | ||
|
||
// Configure a mock runtime to test the pallet. | ||
frame_support::construct_runtime!( | ||
pub enum Test where | ||
Block = Block, | ||
NodeBlock = Block, | ||
UncheckedExtrinsic = UncheckedExtrinsic, | ||
{ | ||
System: frame_system::{Pallet, Call, Config, Storage, Event<T>}, | ||
Remark: pallet_remark::{ Pallet, Call, Event<T> }, | ||
} | ||
); | ||
|
||
impl frame_system::Config for Test { | ||
type BaseCallFilter = frame_support::traits::Everything; | ||
type BlockWeights = (); | ||
type BlockLength = (); | ||
type Origin = Origin; | ||
type Call = Call; | ||
type Index = u64; | ||
type BlockNumber = u64; | ||
type Hash = H256; | ||
type Hashing = BlakeTwo256; | ||
type AccountId = u64; | ||
type Lookup = IdentityLookup<Self::AccountId>; | ||
type Header = Header; | ||
type Event = Event; | ||
type BlockHashCount = ConstU64<250>; | ||
type DbWeight = (); | ||
type Version = (); | ||
type PalletInfo = PalletInfo; | ||
type AccountData = (); | ||
type OnNewAccount = (); | ||
type OnKilledAccount = (); | ||
type SystemWeightInfo = (); | ||
type SS58Prefix = ConstU16<42>; | ||
type OnSetCode = (); | ||
type MaxConsumers = ConstU32<16>; | ||
} | ||
|
||
impl pallet_remark::Config for Test { | ||
type Event = Event; | ||
type WeightInfo = (); | ||
} | ||
|
||
pub fn new_test_ext() -> sp_io::TestExternalities { | ||
let t = GenesisConfig { system: Default::default() }.build_storage().unwrap(); | ||
t.into() | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could also have a
but I don't think it is necessary at this point.