diff --git a/Cargo.lock b/Cargo.lock index 037f254bd30d..fb3ea04c2810 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9423,6 +9423,7 @@ dependencies = [ "frame-system", "parity-scale-codec", "scale-info", + "sp-api", "sp-arithmetic", "sp-core", "sp-io", @@ -16199,7 +16200,7 @@ dependencies = [ "substrate-test-runtime", "tempfile", "tracing", - "tracing-subscriber 0.2.25", + "tracing-subscriber 0.3.18", "wat", ] @@ -16960,7 +16961,7 @@ dependencies = [ "thiserror", "tracing", "tracing-log 0.1.3", - "tracing-subscriber 0.2.25", + "tracing-subscriber 0.3.18", ] [[package]] @@ -19261,7 +19262,7 @@ dependencies = [ "parity-scale-codec", "tracing", "tracing-core", - "tracing-subscriber 0.2.25", + "tracing-subscriber 0.3.18", ] [[package]] @@ -20938,7 +20939,6 @@ dependencies = [ "chrono", "lazy_static", "matchers 0.0.1", - "parking_lot 0.11.2", "regex", "serde", "serde_json", @@ -20957,9 +20957,11 @@ version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ + "chrono", "matchers 0.1.0", "nu-ansi-term", "once_cell", + "parking_lot 0.12.1", "regex", "sharded-slab", "smallvec", diff --git a/Cargo.toml b/Cargo.toml index 067b65ff2299..252fe4fe4d65 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -558,6 +558,7 @@ serde_json = { version = "1.0.114", default-features = false } serde_yaml = { version = "0.9" } syn = { version = "2.0.53" } thiserror = { version = "1.0.48" } +tracing-subscriber = { version = "0.3.18" } [profile.release] # Polkadot runtime requires unwinding. diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs index 1c67740ee540..9f01d397598c 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs @@ -64,7 +64,7 @@ use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, traits::Block as BlockT, transaction_validity::{TransactionSource, TransactionValidity}, - ApplyExtrinsicResult, MultiAddress, Perbill, + ApplyExtrinsicResult, DispatchError, MultiAddress, Perbill, }; use sp_std::prelude::*; #[cfg(feature = "std")] @@ -593,6 +593,12 @@ impl_runtime_apis! { } } + impl pallet_broker::runtime_api::BrokerApi for Runtime { + fn sale_price() -> Result { + Broker::current_price() + } + } + impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi for Runtime { fn query_info( uxt: ::Extrinsic, diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs index 696618c37a28..29d348c1cd90 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs @@ -64,7 +64,7 @@ use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, traits::Block as BlockT, transaction_validity::{TransactionSource, TransactionValidity}, - ApplyExtrinsicResult, MultiAddress, Perbill, + ApplyExtrinsicResult, DispatchError, MultiAddress, Perbill, }; use sp_std::prelude::*; #[cfg(feature = "std")] @@ -584,6 +584,12 @@ impl_runtime_apis! { } } + impl pallet_broker::runtime_api::BrokerApi for Runtime { + fn sale_price() -> Result { + Broker::current_price() + } + } + impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi for Runtime { fn query_info( uxt: ::Extrinsic, diff --git a/prdoc/pr_3485.prdoc b/prdoc/pr_3485.prdoc new file mode 100644 index 000000000000..2add8867c4cd --- /dev/null +++ b/prdoc/pr_3485.prdoc @@ -0,0 +1,20 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: "Broker: sale price runtime api" + +doc: + - audience: Runtime Dev + description: | + Defines a runtime api for `pallet-broker` for getting the current price + of a core in the ongoing sale. + + - audience: Runtime User + description: | + Defines a runtime api for `pallet-broker` for getting the current price + of a core in the ongoing sale. + +crates: + - name: pallet-broker + - name: coretime-rococo-runtime + - name: coretime-westend-runtime diff --git a/prdoc/pr_3976.prdoc b/prdoc/pr_3976.prdoc new file mode 100644 index 000000000000..95afab6d4240 --- /dev/null +++ b/prdoc/pr_3976.prdoc @@ -0,0 +1,14 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Decrement total_deposit when clearing collection metadata + +doc: + - audience: Runtime Dev + description: Decrements total_deposit by the appropriate amount when collection metadata is cleared. + +crates: + - name: pallet-uniques + bump: patch + - name: pallet-nfts + bump: patch diff --git a/substrate/client/executor/Cargo.toml b/substrate/client/executor/Cargo.toml index cb0befe98710..efe8cc3069ca 100644 --- a/substrate/client/executor/Cargo.toml +++ b/substrate/client/executor/Cargo.toml @@ -47,7 +47,7 @@ sp-runtime = { path = "../../primitives/runtime" } sp-maybe-compressed-blob = { path = "../../primitives/maybe-compressed-blob" } sc-tracing = { path = "../tracing" } sp-tracing = { path = "../../primitives/tracing" } -tracing-subscriber = "0.2.19" +tracing-subscriber = { workspace = true } paste = "1.0" regex = "1.6.0" criterion = "0.4.0" diff --git a/substrate/client/tracing/Cargo.toml b/substrate/client/tracing/Cargo.toml index 61e6f7d0bab5..ba1a7c51ab8d 100644 --- a/substrate/client/tracing/Cargo.toml +++ b/substrate/client/tracing/Cargo.toml @@ -30,7 +30,7 @@ serde = { workspace = true, default-features = true } thiserror = { workspace = true } tracing = "0.1.29" tracing-log = "0.1.3" -tracing-subscriber = { version = "0.2.25", features = ["parking_lot"] } +tracing-subscriber = { workspace = true, features = ["parking_lot"] } sc-client-api = { path = "../api" } sc-tracing-proc-macro = { path = "proc-macro" } sp-api = { path = "../../primitives/api" } @@ -42,6 +42,7 @@ sp-tracing = { path = "../../primitives/tracing" } [dev-dependencies] criterion = "0.4.0" +tracing-subscriber = { workspace = true, features = ["chrono", "parking_lot"] } [[bench]] name = "bench" diff --git a/substrate/client/tracing/benches/bench.rs b/substrate/client/tracing/benches/bench.rs index 1379023ddfa6..0f581f6471de 100644 --- a/substrate/client/tracing/benches/bench.rs +++ b/substrate/client/tracing/benches/bench.rs @@ -16,7 +16,10 @@ // limitations under the License. use criterion::{criterion_group, criterion_main, Criterion}; -use tracing_subscriber::fmt::time::{ChronoLocal, FormatTime}; +use tracing_subscriber::fmt::{ + format, + time::{ChronoLocal, FormatTime}, +}; fn bench_fast_local_time(c: &mut Criterion) { c.bench_function("fast_local_time", |b| { @@ -24,7 +27,8 @@ fn bench_fast_local_time(c: &mut Criterion) { let t = sc_tracing::logging::FastLocalTime { with_fractional: true }; b.iter(|| { buffer.clear(); - t.format_time(&mut buffer).unwrap(); + let mut writer = format::Writer::new(&mut buffer); + t.format_time(&mut writer).unwrap(); }) }); } @@ -33,10 +37,11 @@ fn bench_fast_local_time(c: &mut Criterion) { fn bench_chrono_local(c: &mut Criterion) { c.bench_function("chrono_local", |b| { let mut buffer = String::new(); - let t = ChronoLocal::with_format("%Y-%m-%d %H:%M:%S%.3f".to_string()); + let t = ChronoLocal::new("%Y-%m-%d %H:%M:%S%.3f".to_string()); b.iter(|| { buffer.clear(); - t.format_time(&mut buffer).unwrap(); + let mut writer: format::Writer<'_> = format::Writer::new(&mut buffer); + t.format_time(&mut writer).unwrap(); }) }); } diff --git a/substrate/client/tracing/src/lib.rs b/substrate/client/tracing/src/lib.rs index 2107943cf6a5..ba4d1a15cc0c 100644 --- a/substrate/client/tracing/src/lib.rs +++ b/substrate/client/tracing/src/lib.rs @@ -290,7 +290,7 @@ impl Layer for ProfilingLayer where S: Subscriber + for<'span> LookupSpan<'span>, { - fn new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context) { + fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context) { if let Some(span) = ctx.span(id) { let mut extension = span.extensions_mut(); let parent_id = attrs.parent().cloned().or_else(|| { diff --git a/substrate/client/tracing/src/logging/event_format.rs b/substrate/client/tracing/src/logging/event_format.rs index f4579f006c25..235d66cadc78 100644 --- a/substrate/client/tracing/src/logging/event_format.rs +++ b/substrate/client/tracing/src/logging/event_format.rs @@ -24,7 +24,7 @@ use tracing::{Event, Level, Subscriber}; use tracing_log::NormalizeEvent; use tracing_subscriber::{ field::RecordFields, - fmt::{time::FormatTime, FmtContext, FormatEvent, FormatFields}, + fmt::{format, time::FormatTime, FmtContext, FormatEvent, FormatFields}, layer::Context, registry::{LookupSpan, SpanRef}, }; @@ -52,20 +52,20 @@ where // NOTE: the following code took inspiration from tracing-subscriber // // https://github.com/tokio-rs/tracing/blob/2f59b32/tracing-subscriber/src/fmt/format/mod.rs#L449 - pub(crate) fn format_event_custom<'b, S, N>( + pub(crate) fn format_event_custom<'b, 'w, S, N>( &self, ctx: CustomFmtContext<'b, S, N>, - writer: &mut dyn fmt::Write, + writer: format::Writer<'w>, event: &Event, ) -> fmt::Result where S: Subscriber + for<'a> LookupSpan<'a>, N: for<'a> FormatFields<'a> + 'static, { - let writer = &mut ControlCodeSanitizer::new(!self.enable_color, writer); + let mut writer = &mut ControlCodeSanitizer::new(!self.enable_color, writer); let normalized_meta = event.normalized_metadata(); let meta = normalized_meta.as_ref().unwrap_or_else(|| event.metadata()); - time::write(&self.timer, writer, self.enable_color)?; + time::write(&self.timer, &mut format::Writer::new(&mut writer), self.enable_color)?; if self.display_level { let fmt_level = { FmtLevel::new(meta.level(), self.enable_color) }; @@ -108,7 +108,7 @@ where writer.sanitize = true; } - ctx.format_fields(writer, event)?; + ctx.format_fields(format::Writer::new(writer), event)?; writeln!(writer)?; writer.flush() @@ -127,7 +127,7 @@ where fn format_event( &self, ctx: &FmtContext, - writer: &mut dyn fmt::Write, + mut writer: format::Writer<'_>, event: &Event, ) -> fmt::Result { if self.dup_to_stdout && @@ -136,7 +136,8 @@ where event.metadata().level() == &Level::ERROR) { let mut out = String::new(); - self.format_event_custom(CustomFmtContext::FmtContext(ctx), &mut out, event)?; + let buf_writer = format::Writer::new(&mut out); + self.format_event_custom(CustomFmtContext::FmtContext(ctx), buf_writer, event)?; writer.write_str(&out)?; print!("{}", out); Ok(()) @@ -237,9 +238,13 @@ impl<'a> fmt::Display for FmtThreadName<'a> { mod time { use ansi_term::Style; use std::fmt; - use tracing_subscriber::fmt::time::FormatTime; + use tracing_subscriber::fmt::{format, time::FormatTime}; - pub(crate) fn write(timer: T, writer: &mut dyn fmt::Write, with_ansi: bool) -> fmt::Result + pub(crate) fn write( + timer: T, + writer: &mut format::Writer<'_>, + with_ansi: bool, + ) -> fmt::Result where T: FormatTime, { @@ -269,11 +274,7 @@ where S: Subscriber + for<'lookup> LookupSpan<'lookup>, N: for<'writer> FormatFields<'writer> + 'static, { - fn format_fields( - &self, - writer: &'a mut dyn fmt::Write, - fields: R, - ) -> fmt::Result { + fn format_fields(&self, writer: format::Writer<'_>, fields: R) -> fmt::Result { match self { CustomFmtContext::FmtContext(fmt_ctx) => fmt_ctx.format_fields(writer, fields), CustomFmtContext::ContextWithFormatFields(_ctx, fmt_fields) => @@ -312,7 +313,7 @@ where struct ControlCodeSanitizer<'a> { sanitize: bool, buffer: String, - inner_writer: &'a mut dyn fmt::Write, + inner_writer: format::Writer<'a>, } impl<'a> fmt::Write for ControlCodeSanitizer<'a> { @@ -342,7 +343,7 @@ fn strip_control_codes(input: &str) -> std::borrow::Cow { impl<'a> ControlCodeSanitizer<'a> { /// Creates a new instance. - fn new(sanitize: bool, inner_writer: &'a mut dyn fmt::Write) -> Self { + fn new(sanitize: bool, inner_writer: format::Writer<'a>) -> Self { Self { sanitize, inner_writer, buffer: String::new() } } diff --git a/substrate/client/tracing/src/logging/fast_local_time.rs b/substrate/client/tracing/src/logging/fast_local_time.rs index 7be7bec8364a..ac4d14d95699 100644 --- a/substrate/client/tracing/src/logging/fast_local_time.rs +++ b/substrate/client/tracing/src/logging/fast_local_time.rs @@ -18,7 +18,7 @@ use chrono::{Datelike, Timelike}; use std::{cell::RefCell, fmt::Write, time::SystemTime}; -use tracing_subscriber::fmt::time::FormatTime; +use tracing_subscriber::fmt::{format, time::FormatTime}; /// A structure which, when `Display`d, will print out the current local time. #[derive(Debug, Clone, Copy, Eq, PartialEq, Default)] @@ -76,7 +76,7 @@ thread_local! { } impl FormatTime for FastLocalTime { - fn format_time(&self, w: &mut dyn Write) -> std::fmt::Result { + fn format_time(&self, w: &mut format::Writer<'_>) -> std::fmt::Result { const TIMESTAMP_PARTIAL_LENGTH: usize = "0000-00-00 00:00:00".len(); let elapsed = SystemTime::now() @@ -128,8 +128,8 @@ impl FormatTime for FastLocalTime { } impl std::fmt::Display for FastLocalTime { - fn fmt(&self, w: &mut std::fmt::Formatter) -> std::fmt::Result { - self.format_time(w) + fn fmt(&self, mut w: &mut std::fmt::Formatter) -> std::fmt::Result { + self.format_time(&mut format::Writer::new(&mut w)) } } diff --git a/substrate/client/tracing/src/logging/layers/prefix_layer.rs b/substrate/client/tracing/src/logging/layers/prefix_layer.rs index fc444257bde0..f73f06bb5320 100644 --- a/substrate/client/tracing/src/logging/layers/prefix_layer.rs +++ b/substrate/client/tracing/src/logging/layers/prefix_layer.rs @@ -32,7 +32,7 @@ impl Layer for PrefixLayer where S: Subscriber + for<'a> LookupSpan<'a>, { - fn new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>) { + fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>) { let span = match ctx.span(id) { Some(span) => span, None => { diff --git a/substrate/client/tracing/src/logging/mod.rs b/substrate/client/tracing/src/logging/mod.rs index 403839390d65..8b2ad9b598b5 100644 --- a/substrate/client/tracing/src/logging/mod.rs +++ b/substrate/client/tracing/src/logging/mod.rs @@ -104,7 +104,7 @@ fn prepare_subscriber( where N: for<'writer> FormatFields<'writer> + 'static, E: FormatEvent + 'static, - W: MakeWriter + 'static, + W: for<'writer> MakeWriter<'writer> + 'static, F: layer::Layer> + Send + Sync + 'static, FmtLayer: layer::Layer + Send + Sync + 'static, { diff --git a/substrate/client/tracing/src/logging/stderr_writer.rs b/substrate/client/tracing/src/logging/stderr_writer.rs index 80df2f1fe7cd..481efd32e50b 100644 --- a/substrate/client/tracing/src/logging/stderr_writer.rs +++ b/substrate/client/tracing/src/logging/stderr_writer.rs @@ -148,7 +148,7 @@ impl Default for MakeStderrWriter { } } -impl tracing_subscriber::fmt::MakeWriter for MakeStderrWriter { +impl tracing_subscriber::fmt::MakeWriter<'_> for MakeStderrWriter { type Writer = StderrWriter; fn make_writer(&self) -> Self::Writer { diff --git a/substrate/frame/broker/Cargo.toml b/substrate/frame/broker/Cargo.toml index 3b6bd2019cc1..969f13e269de 100644 --- a/substrate/frame/broker/Cargo.toml +++ b/substrate/frame/broker/Cargo.toml @@ -18,6 +18,7 @@ targets = ["x86_64-unknown-linux-gnu"] codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] } scale-info = { version = "2.11.1", default-features = false, features = ["derive"] } bitvec = { version = "1.0.0", default-features = false } +sp-api = { path = "../../primitives/api", default-features = false } sp-std = { path = "../../primitives/std", default-features = false } sp-arithmetic = { path = "../../primitives/arithmetic", default-features = false } sp-core = { path = "../../primitives/core", default-features = false } @@ -39,6 +40,7 @@ std = [ "frame-support/std", "frame-system/std", "scale-info/std", + "sp-api/std", "sp-arithmetic/std", "sp-core/std", "sp-io/std", diff --git a/substrate/frame/broker/src/dispatchable_impls.rs b/substrate/frame/broker/src/dispatchable_impls.rs index a87618147fea..ef20bc8fb80b 100644 --- a/substrate/frame/broker/src/dispatchable_impls.rs +++ b/substrate/frame/broker/src/dispatchable_impls.rs @@ -105,8 +105,8 @@ impl Pallet { ) -> Result { let status = Status::::get().ok_or(Error::::Uninitialized)?; let mut sale = SaleInfo::::get().ok_or(Error::::NoSales)?; - ensure!(sale.first_core < status.core_count, Error::::Unavailable); - ensure!(sale.cores_sold < sale.cores_offered, Error::::SoldOut); + Self::ensure_cores_for_sale(&status, &sale)?; + let now = frame_system::Pallet::::block_number(); ensure!(now > sale.sale_start, Error::::TooEarly); let price = Self::sale_price(&sale, now); @@ -131,8 +131,7 @@ impl Pallet { let config = Configuration::::get().ok_or(Error::::Uninitialized)?; let status = Status::::get().ok_or(Error::::Uninitialized)?; let mut sale = SaleInfo::::get().ok_or(Error::::NoSales)?; - ensure!(sale.first_core < status.core_count, Error::::Unavailable); - ensure!(sale.cores_sold < sale.cores_offered, Error::::SoldOut); + Self::ensure_cores_for_sale(&status, &sale)?; let renewal_id = AllowedRenewalId { core, when: sale.region_begin }; let record = AllowedRenewals::::get(renewal_id).ok_or(Error::::NotAllowed)?; @@ -456,4 +455,25 @@ impl Pallet { Ok(()) } + + pub(crate) fn ensure_cores_for_sale( + status: &StatusRecord, + sale: &SaleInfoRecordOf, + ) -> Result<(), DispatchError> { + ensure!(sale.first_core < status.core_count, Error::::Unavailable); + ensure!(sale.cores_sold < sale.cores_offered, Error::::SoldOut); + + Ok(()) + } + + /// If there is an ongoing sale returns the current price of a core. + pub fn current_price() -> Result, DispatchError> { + let status = Status::::get().ok_or(Error::::Uninitialized)?; + let sale = SaleInfo::::get().ok_or(Error::::NoSales)?; + + Self::ensure_cores_for_sale(&status, &sale)?; + + let now = frame_system::Pallet::::block_number(); + Ok(Self::sale_price(&sale, now)) + } } diff --git a/substrate/frame/broker/src/lib.rs b/substrate/frame/broker/src/lib.rs index d059965a392a..a39576b09013 100644 --- a/substrate/frame/broker/src/lib.rs +++ b/substrate/frame/broker/src/lib.rs @@ -36,6 +36,8 @@ mod tick_impls; mod types; mod utility_impls; +pub mod runtime_api; + pub mod weights; pub use weights::WeightInfo; @@ -132,7 +134,7 @@ pub mod pallet { pub type AllowedRenewals = StorageMap<_, Twox64Concat, AllowedRenewalId, AllowedRenewalRecordOf, OptionQuery>; - /// The current (unassigned) Regions. + /// The current (unassigned or provisionally assigend) Regions. #[pallet::storage] pub type Regions = StorageMap<_, Blake2_128Concat, RegionId, RegionRecordOf, OptionQuery>; diff --git a/substrate/frame/broker/src/runtime_api.rs b/substrate/frame/broker/src/runtime_api.rs new file mode 100644 index 000000000000..6faab6156503 --- /dev/null +++ b/substrate/frame/broker/src/runtime_api.rs @@ -0,0 +1,31 @@ +// 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. + +//! Runtime API definition for the FRAME Broker pallet. + +use codec::Codec; +use sp_runtime::DispatchError; + +sp_api::decl_runtime_apis! { + pub trait BrokerApi + where + Balance: Codec + { + /// If there is an ongoing sale returns the current price of a core. + fn sale_price() -> Result; + } +} diff --git a/substrate/frame/nfts/src/features/metadata.rs b/substrate/frame/nfts/src/features/metadata.rs index e177f39bb8b8..85edd294d50b 100644 --- a/substrate/frame/nfts/src/features/metadata.rs +++ b/substrate/frame/nfts/src/features/metadata.rs @@ -247,7 +247,7 @@ impl, I: 'static> Pallet { ); } - let details = + let mut details = Collection::::get(&collection).ok_or(Error::::UnknownCollection)?; let collection_config = Self::get_collection_config(&collection)?; @@ -260,6 +260,8 @@ impl, I: 'static> Pallet { CollectionMetadataOf::::try_mutate_exists(collection, |metadata| { let deposit = metadata.take().ok_or(Error::::UnknownCollection)?.deposit; T::Currency::unreserve(&details.owner, deposit); + details.owner_deposit.saturating_reduce(deposit); + Collection::::insert(&collection, details); Self::deposit_event(Event::CollectionMetadataCleared { collection }); Ok(()) }) diff --git a/substrate/frame/nfts/src/tests.rs b/substrate/frame/nfts/src/tests.rs index 6bf9427f4e6c..4d23aca64ceb 100644 --- a/substrate/frame/nfts/src/tests.rs +++ b/substrate/frame/nfts/src/tests.rs @@ -3835,3 +3835,44 @@ fn basic_create_collection_with_id_should_work() { ); }); } + +#[test] +fn clear_collection_metadata_works() { + new_test_ext().execute_with(|| { + // Start with an account with 100 tokens, 10 of which are reserved + Balances::make_free_balance_be(&account(1), 100); + Balances::reserve(&account(1), 10).unwrap(); + + // Creating a collection increases owner deposit by 2 + assert_ok!(Nfts::create( + RuntimeOrigin::signed(account(1)), + account(1), + collection_config_with_all_settings_enabled() + )); + assert_eq!(Collection::::get(0).unwrap().owner_deposit, 2); + assert_eq!(Balances::reserved_balance(&account(1)), 12); + + // Setting collection metadata increases owner deposit by 10 + assert_ok!(Nfts::set_collection_metadata( + RuntimeOrigin::signed(account(1)), + 0, + bvec![0, 0, 0, 0, 0, 0, 0, 0, 0], + )); + assert_eq!(Collection::::get(0).unwrap().owner_deposit, 12); + assert_eq!(Balances::reserved_balance(&account(1)), 22); + + // Clearing collection metadata decreases owner deposit by 10 + assert_ok!(Nfts::clear_collection_metadata(RuntimeOrigin::signed(account(1)), 0)); + assert_eq!(Collection::::get(0).unwrap().owner_deposit, 2); + assert_eq!(Balances::reserved_balance(&account(1)), 12); + + // Destroying the collection removes it from storage + assert_ok!(Nfts::destroy( + RuntimeOrigin::signed(account(1)), + 0, + DestroyWitness { item_configs: 0, item_metadatas: 0, attributes: 0 } + )); + assert_eq!(Collection::::get(0), None); + assert_eq!(Balances::reserved_balance(&account(1)), 10); + }); +} diff --git a/substrate/frame/src/lib.rs b/substrate/frame/src/lib.rs index d395b4c1902b..f93f4d31e777 100644 --- a/substrate/frame/src/lib.rs +++ b/substrate/frame/src/lib.rs @@ -53,24 +53,24 @@ #![cfg_attr(not(feature = "std"), no_std)] #![cfg(feature = "experimental")] -/// Exports the main pallet macro. This can wrap a `mod pallet` and will transform it into -/// being a pallet, eg `#[polkadot_sdk_frame::pallet] mod pallet { .. }`. -/// -/// Note that this is not part of the prelude, in order to make it such that the common way to -/// define a macro is `#[polkadot_sdk_frame::pallet] mod pallet { .. }`, followed by -/// `#[pallet::foo]`, `#[pallet::bar]` inside the mod. +#[doc(no_inline)] pub use frame_support::pallet; +#[doc(no_inline)] pub use frame_support::pallet_macros::{import_section, pallet_section}; /// The logging library of the runtime. Can normally be the classic `log` crate. pub use log; -/// A list of all macros used within the main [`pallet`] macro. +/// Macros used within the main [`pallet`] macro. /// /// Note: All of these macros are "stubs" and not really usable outside `#[pallet] mod pallet { .. /// }`. They are mainly provided for documentation and IDE support. +/// +/// To view a list of all the macros and their documentation, follow the links in the 'Re-exports' +/// section below: pub mod pallet_macros { + #[doc(no_inline)] pub use frame_support::{derive_impl, pallet, pallet_macros::*}; } diff --git a/substrate/frame/support/procedural/src/lib.rs b/substrate/frame/support/procedural/src/lib.rs index f22be024d3fe..53f01329d181 100644 --- a/substrate/frame/support/procedural/src/lib.rs +++ b/substrate/frame/support/procedural/src/lib.rs @@ -192,8 +192,7 @@ pub fn construct_runtime(input: TokenStream) -> TokenStream { /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// `frame_support::pallet`. +/// Documentation for this macro can be found at `frame_support::pallet`. #[proc_macro_attribute] pub fn pallet(attr: TokenStream, item: TokenStream) -> TokenStream { pallet::pallet(attr, item) @@ -290,8 +289,7 @@ pub fn transactional(attr: TokenStream, input: TokenStream) -> TokenStream { /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// `frame_support::require_transactional`. +/// Documentation for this macro can be found at `frame_support::require_transactional`. #[proc_macro_attribute] pub fn require_transactional(attr: TokenStream, input: TokenStream) -> TokenStream { transactional::require_transactional(attr, input) @@ -450,8 +448,7 @@ pub fn __create_tt_macro(input: TokenStream) -> TokenStream { /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// `frame_support::pallet_macros::storage_alias`. +/// Documentation for this macro can be found at `frame_support::pallet_macros::storage_alias`. #[proc_macro_attribute] pub fn storage_alias(attributes: TokenStream, input: TokenStream) -> TokenStream { storage_alias::storage_alias(attributes.into(), input.into()) @@ -690,8 +687,7 @@ pub fn derive_impl(attrs: TokenStream, input: TokenStream) -> TokenStream { /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// `frame_support::pallet_macros::no_default`. +/// Documentation for this macro can be found at `frame_support::pallet_macros::no_default`. #[proc_macro_attribute] pub fn no_default(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -700,8 +696,7 @@ pub fn no_default(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// `frame_support::pallet_macros::no_default_bounds`. +/// Documentation for this macro can be found at `frame_support::pallet_macros::no_default_bounds`. #[proc_macro_attribute] pub fn no_default_bounds(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -784,7 +779,7 @@ pub fn register_default_impl(attrs: TokenStream, tokens: TokenStream) -> TokenSt /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at +/// Documentation for this macro can be found at /// `frame_support::pallet_prelude::inject_runtime_type`. #[proc_macro_attribute] pub fn inject_runtime_type(_: TokenStream, tokens: TokenStream) -> TokenStream { @@ -822,8 +817,7 @@ fn pallet_macro_stub() -> TokenStream { /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// `frame_support::pallet_macros::config`. +/// Documentation for this macro can be found at `frame_support::pallet_macros::config`. #[proc_macro_attribute] pub fn config(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -832,8 +826,7 @@ pub fn config(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// `frame_support::pallet_macros::constant`. +/// Documentation for this macro can be found at `frame_support::pallet_macros::constant`. #[proc_macro_attribute] pub fn constant(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -842,8 +835,7 @@ pub fn constant(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// `frame_support::pallet_macros::constant_name`. +/// Documentation for this macro can be found at `frame_support::pallet_macros::constant_name`. #[proc_macro_attribute] pub fn constant_name(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -852,7 +844,7 @@ pub fn constant_name(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at +/// Documentation for this macro can be found at /// `frame_support::pallet_macros::disable_frame_system_supertrait_check`. #[proc_macro_attribute] pub fn disable_frame_system_supertrait_check(_: TokenStream, _: TokenStream) -> TokenStream { @@ -862,8 +854,7 @@ pub fn disable_frame_system_supertrait_check(_: TokenStream, _: TokenStream) -> /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// `frame_support::pallet_macros::storage_version`. +/// Documentation for this macro can be found at `frame_support::pallet_macros::storage_version`. #[proc_macro_attribute] pub fn storage_version(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -872,8 +863,7 @@ pub fn storage_version(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// `frame_support::pallet_macros::hooks`. +/// Documentation for this macro can be found at `frame_support::pallet_macros::hooks`. #[proc_macro_attribute] pub fn hooks(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -882,8 +872,7 @@ pub fn hooks(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// `frame_support::pallet_macros::weight`. +/// Documentation for this macro can be found at `frame_support::pallet_macros::weight`. #[proc_macro_attribute] pub fn weight(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -892,8 +881,7 @@ pub fn weight(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// `frame_support::pallet_macros::compact`. +/// Documentation for this macro can be found at `frame_support::pallet_macros::compact`. #[proc_macro_attribute] pub fn compact(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -902,8 +890,7 @@ pub fn compact(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// `frame_support::pallet_macros::call`. +/// Documentation for this macro can be found at `frame_support::pallet_macros::call`. #[proc_macro_attribute] pub fn call(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -914,8 +901,7 @@ pub fn call(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// `frame_support::pallet_macros::call_index`. +/// Documentation for this macro can be found at `frame_support::pallet_macros::call_index`. #[proc_macro_attribute] pub fn call_index(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -924,9 +910,7 @@ pub fn call_index(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// -/// `frame_support::pallet_macros::feeless_if`. +/// Documentation for this macro can be found at `frame_support::pallet_macros::feeless_if`. #[proc_macro_attribute] pub fn feeless_if(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -935,9 +919,7 @@ pub fn feeless_if(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// -/// `frame_support::pallet_macros::extra_constants`. +/// Documentation for this macro can be found at `frame_support::pallet_macros::extra_constants`. #[proc_macro_attribute] pub fn extra_constants(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -946,8 +928,7 @@ pub fn extra_constants(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// `frame_support::pallet_macros::error`. +/// Documentation for this macro can be found at `frame_support::pallet_macros::error`. #[proc_macro_attribute] pub fn error(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -956,8 +937,7 @@ pub fn error(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// `frame_support::pallet_macros::event`. +/// Documentation for this macro can be found at `frame_support::pallet_macros::event`. #[proc_macro_attribute] pub fn event(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -966,8 +946,7 @@ pub fn event(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// `frame_support::pallet_macros::generate_deposit`. +/// Documentation for this macro can be found at `frame_support::pallet_macros::generate_deposit`. #[proc_macro_attribute] pub fn generate_deposit(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -976,8 +955,7 @@ pub fn generate_deposit(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// `frame_support::pallet_macros::storage`. +/// Documentation for this macro can be found at `frame_support::pallet_macros::storage`. #[proc_macro_attribute] pub fn storage(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -986,8 +964,7 @@ pub fn storage(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// `frame_support::pallet_macros::getter`. +/// Documentation for this macro can be found at `frame_support::pallet_macros::getter`. #[proc_macro_attribute] pub fn getter(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -996,8 +973,7 @@ pub fn getter(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// `frame_support::pallet_macros::storage_prefix`. +/// Documentation for this macro can be found at `frame_support::pallet_macros::storage_prefix`. #[proc_macro_attribute] pub fn storage_prefix(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -1006,8 +982,7 @@ pub fn storage_prefix(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// `frame_support::pallet_macros::unbounded`. +/// Documentation for this macro can be found at `frame_support::pallet_macros::unbounded`. #[proc_macro_attribute] pub fn unbounded(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -1016,8 +991,7 @@ pub fn unbounded(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// `frame_support::pallet_macros::whitelist_storage`. +/// Documentation for this macro can be found at `frame_support::pallet_macros::whitelist_storage`. #[proc_macro_attribute] pub fn whitelist_storage(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -1026,7 +1000,7 @@ pub fn whitelist_storage(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at +/// Documentation for this macro can be found at /// `frame_support::pallet_macros::disable_try_decode_storage`. #[proc_macro_attribute] pub fn disable_try_decode_storage(_: TokenStream, _: TokenStream) -> TokenStream { @@ -1036,8 +1010,7 @@ pub fn disable_try_decode_storage(_: TokenStream, _: TokenStream) -> TokenStream /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// `frame_support::pallet_macros::type_value`. +/// Documentation for this macro can be found at `frame_support::pallet_macros::type_value`. #[proc_macro_attribute] pub fn type_value(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -1046,8 +1019,7 @@ pub fn type_value(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// `frame_support::pallet_macros::genesis_config`. +/// Documentation for this macro can be found at `frame_support::pallet_macros::genesis_config`. #[proc_macro_attribute] pub fn genesis_config(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -1056,8 +1028,7 @@ pub fn genesis_config(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// `frame_support::pallet_macros::genesis_build`. +/// Documentation for this macro can be found at `frame_support::pallet_macros::genesis_build`. #[proc_macro_attribute] pub fn genesis_build(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -1066,8 +1037,7 @@ pub fn genesis_build(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// `frame_support::pallet_macros::inherent`. +/// Documentation for this macro can be found at `frame_support::pallet_macros::inherent`. #[proc_macro_attribute] pub fn inherent(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -1076,8 +1046,7 @@ pub fn inherent(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// `frame_support::pallet_macros::validate_unsigned`. +/// Documentation for this macro can be found at `frame_support::pallet_macros::validate_unsigned`. #[proc_macro_attribute] pub fn validate_unsigned(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -1086,8 +1055,7 @@ pub fn validate_unsigned(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// `frame_support::pallet_macros::origin`. +/// Documentation for this macro can be found at `frame_support::pallet_macros::origin`. #[proc_macro_attribute] pub fn origin(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -1096,8 +1064,7 @@ pub fn origin(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// `frame_support::pallet_macros::composite_enum`. +/// Documentation for this macro can be found at `frame_support::pallet_macros::composite_enum`. #[proc_macro_attribute] pub fn composite_enum(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() diff --git a/substrate/frame/uniques/src/lib.rs b/substrate/frame/uniques/src/lib.rs index f7cc6b044d72..2291d19de2bf 100644 --- a/substrate/frame/uniques/src/lib.rs +++ b/substrate/frame/uniques/src/lib.rs @@ -1399,7 +1399,7 @@ pub mod pallet { .map(|_| None) .or_else(|origin| ensure_signed(origin).map(Some))?; - let details = + let mut details = Collection::::get(&collection).ok_or(Error::::UnknownCollection)?; if let Some(check_owner) = &maybe_check_owner { ensure!(check_owner == &details.owner, Error::::NoPermission); @@ -1411,6 +1411,8 @@ pub mod pallet { let deposit = metadata.take().ok_or(Error::::UnknownCollection)?.deposit; T::Currency::unreserve(&details.owner, deposit); + details.total_deposit.saturating_reduce(deposit); + Collection::::insert(&collection, details); Self::deposit_event(Event::CollectionMetadataCleared { collection }); Ok(()) }) diff --git a/substrate/frame/uniques/src/tests.rs b/substrate/frame/uniques/src/tests.rs index afd0352bf90e..5dfe43c96888 100644 --- a/substrate/frame/uniques/src/tests.rs +++ b/substrate/frame/uniques/src/tests.rs @@ -1062,3 +1062,41 @@ fn buy_item_should_work() { } }); } + +#[test] +fn clear_collection_metadata_works() { + new_test_ext().execute_with(|| { + // Start with an account with 100 balance, 10 of which are reserved + Balances::make_free_balance_be(&1, 100); + Balances::reserve(&1, 10).unwrap(); + + // Create a Unique which increases total_deposit by 2 + assert_ok!(Uniques::create(RuntimeOrigin::signed(1), 0, 123)); + assert_eq!(Collection::::get(0).unwrap().total_deposit, 2); + assert_eq!(Balances::reserved_balance(&1), 12); + + // Set collection metadata which increases total_deposit by 10 + assert_ok!(Uniques::set_collection_metadata( + RuntimeOrigin::signed(1), + 0, + bvec![0, 0, 0, 0, 0, 0, 0, 0, 0], + false + )); + assert_eq!(Collection::::get(0).unwrap().total_deposit, 12); + assert_eq!(Balances::reserved_balance(&1), 22); + + // Clearing collection metadata reduces total_deposit by the expected amount + assert_ok!(Uniques::clear_collection_metadata(RuntimeOrigin::signed(1), 0)); + assert_eq!(Collection::::get(0).unwrap().total_deposit, 2); + assert_eq!(Balances::reserved_balance(&1), 12); + + // Destroying the collection removes it from storage + assert_ok!(Uniques::destroy( + RuntimeOrigin::signed(1), + 0, + DestroyWitness { items: 0, item_metadatas: 0, attributes: 0 } + )); + assert_eq!(Collection::::get(0), None); + assert_eq!(Balances::reserved_balance(&1), 10); + }); +} diff --git a/substrate/primitives/tracing/Cargo.toml b/substrate/primitives/tracing/Cargo.toml index 368f8c096dd4..ce30302d4bb0 100644 --- a/substrate/primitives/tracing/Cargo.toml +++ b/substrate/primitives/tracing/Cargo.toml @@ -26,7 +26,8 @@ codec = { version = "3.6.1", package = "parity-scale-codec", default-features = ] } tracing = { version = "0.1.29", default-features = false } tracing-core = { version = "0.1.32", default-features = false } -tracing-subscriber = { version = "0.2.25", optional = true, features = [ +tracing-subscriber = { workspace = true, optional = true, features = [ + "env-filter", "tracing-log", ] }