Skip to content

Commit bcf6b0a

Browse files
committed
Avoid associated type in Consideration
1 parent 9e2dd10 commit bcf6b0a

File tree

3 files changed

+177
-127
lines changed

3 files changed

+177
-127
lines changed

substrate/frame/preimage/src/lib.rs

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,6 @@ pub enum RequestStatus<AccountId, Ticket> {
8585

8686
type BalanceOf<T> =
8787
<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;
88-
type TicketOf<T> =
89-
<<T as Config>::Consideration as Consideration<<T as frame_system::Config>::AccountId>>::Ticket;
9088

9189
/// Maximum size of preimage we can store is 4mb.
9290
const MAX_SIZE: u32 = 4 * 1024 * 1024;
@@ -164,7 +162,7 @@ pub mod pallet {
164162
/// The request status of a given hash.
165163
#[pallet::storage]
166164
pub(super) type RequestStatusFor<T: Config> =
167-
StorageMap<_, Identity, T::Hash, RequestStatus<T::AccountId, TicketOf<T>>>;
165+
StorageMap<_, Identity, T::Hash, RequestStatus<T::AccountId, T::Consideration>>;
168166

169167
#[pallet::storage]
170168
pub(super) type PreimageFor<T: Config> =
@@ -239,20 +237,21 @@ impl<T: Config> Pallet<T> {
239237
// unreserve deposit
240238
T::Currency::unreserve(&who, amount);
241239
// take consideration
242-
let ticket = T::Consideration::new(&who, Footprint::from_parts(1, len as usize))
243-
.unwrap_or_default();
244-
RequestStatus::Unrequested { ticket: (who, ticket), len }
240+
let footprint = Footprint::from_parts(1, len as usize);
241+
let maybe_consider = T::Consideration::new(&who, footprint);
242+
let Ok(consider) = maybe_consider else { return false };
243+
RequestStatus::Unrequested { ticket: (who, consider), len }
245244
},
246245
OldRequestStatus::Requested { deposit: maybe_deposit, count, len: maybe_len } => {
247246
let maybe_ticket = if let Some((who, deposit)) = maybe_deposit {
248247
// unreserve deposit
249248
T::Currency::unreserve(&who, deposit);
250249
// take consideration
251250
if let Some(len) = maybe_len {
252-
let ticket =
253-
T::Consideration::new(&who, Footprint::from_parts(1, len as usize))
254-
.unwrap_or_default();
255-
Some((who, ticket))
251+
let footprint = Footprint::from_parts(1, len as usize);
252+
let maybe_consider = T::Consideration::new(&who, footprint);
253+
let Ok(consider) = maybe_consider else { return false };
254+
Some((who, consider))
256255
} else {
257256
None
258257
}
@@ -308,9 +307,9 @@ impl<T: Config> Pallet<T> {
308307
(None, None) =>
309308
RequestStatus::Requested { maybe_ticket: None, count: 1, maybe_len: Some(len) },
310309
(None, Some(depositor)) => {
311-
let ticket =
310+
let consider =
312311
T::Consideration::new(depositor, Footprint::from_parts(1, len as usize))?;
313-
RequestStatus::Unrequested { ticket: (depositor.clone(), ticket), len }
312+
RequestStatus::Unrequested { ticket: (depositor.clone(), consider), len }
314313
},
315314
};
316315
let was_requested = matches!(status, RequestStatus::Requested { .. });
@@ -359,9 +358,13 @@ impl<T: Config> Pallet<T> {
359358
) -> DispatchResult {
360359
Self::ensure_updated(&hash);
361360
match RequestStatusFor::<T>::get(hash).ok_or(Error::<T>::NotNoted)? {
362-
RequestStatus::Requested { maybe_ticket: Some((owner, ticket)), count, maybe_len } => {
361+
RequestStatus::Requested {
362+
maybe_ticket: Some((owner, consider)),
363+
count,
364+
maybe_len,
365+
} => {
363366
ensure!(maybe_check_owner.map_or(true, |c| c == owner), Error::<T>::NotAuthorized);
364-
let _ = T::Consideration::drop(&owner, ticket);
367+
let _ = consider.drop(&owner);
365368
RequestStatusFor::<T>::insert(
366369
hash,
367370
RequestStatus::Requested { maybe_ticket: None, count, maybe_len },
@@ -372,9 +375,9 @@ impl<T: Config> Pallet<T> {
372375
ensure!(maybe_check_owner.is_none(), Error::<T>::NotAuthorized);
373376
Self::do_unrequest_preimage(hash)
374377
},
375-
RequestStatus::Unrequested { ticket: (owner, ticket), len } => {
378+
RequestStatus::Unrequested { ticket: (owner, consider), len } => {
376379
ensure!(maybe_check_owner.map_or(true, |c| c == owner), Error::<T>::NotAuthorized);
377-
let _ = T::Consideration::drop(&owner, ticket);
380+
let _ = consider.drop(&owner);
378381
RequestStatusFor::<T>::remove(hash);
379382

380383
Self::remove(hash, len);

substrate/frame/support/src/traits/storage.rs

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -156,41 +156,38 @@ impl Footprint {
156156
/// holding some data `Footprint` in state.
157157
///
158158
/// The cost may be increased, reduced or dropped entirely as the footprint changes.
159-
pub trait Consideration<AccountId> {
160-
/// A single ticket corresponding to some particular datum held in storage. This is an opaque
161-
/// type, but must itself be stored and generally it should be placed alongside whatever data
162-
/// the ticket was created for.
163-
///
164-
/// While not technically a linear type owing to the need for `FullCodec`, *this should be
165-
/// treated as one*. Don't type to duplicate it, and remember to drop it when you're done with
166-
/// it.
167-
type Ticket: Member + FullCodec + TypeInfo + MaxEncodedLen + Default;
159+
///
160+
/// A single ticket corresponding to some particular datum held in storage. This is an opaque
161+
/// type, but must itself be stored and generally it should be placed alongside whatever data
162+
/// the ticket was created for.
163+
///
164+
/// While not technically a linear type owing to the need for `FullCodec`, *this should be
165+
/// treated as one*. Don't type to duplicate it, and remember to drop it when you're done with
166+
/// it.
167+
#[must_use]
168+
pub trait Consideration<AccountId>: Member + FullCodec + TypeInfo + MaxEncodedLen {
169+
/// Create a ticket for the `new` footprint attributable to `who`. This ticket *must* ultimately
170+
/// be consumed through `update` or `drop` once the footprint changes or is removed.
171+
fn new(who: &AccountId, new: Footprint) -> Result<Self, DispatchError>;
168172

169173
/// Optionally consume an old ticket and alter the footprint, enforcing the new cost to `who`
170174
/// and returning the new ticket (or an error if there was an issue).
171175
///
172176
/// For creating tickets and dropping them, you can use the simpler `new` and `drop` instead.
173-
fn update(
174-
who: &AccountId,
175-
old: Option<Self::Ticket>,
176-
new: Option<Footprint>,
177-
) -> Result<Self::Ticket, DispatchError>;
178-
179-
/// Create a ticket for the `new` footprint attributable to `who`. This ticket *must* be
180-
/// consumed (through either `drop` or `update`) if the footprint changes or is removed.
181-
fn new(who: &AccountId, new: Footprint) -> Result<Self::Ticket, DispatchError> {
182-
Self::update(who, None, Some(new))
183-
}
177+
fn update(self, who: &AccountId, new: Footprint) -> Result<Self, DispatchError>;
184178

185179
/// Consume a ticket for some `old` footprint attributable to `who` which has now been freed.
186-
fn drop(who: &AccountId, old: Self::Ticket) -> Result<(), DispatchError> {
187-
Self::update(who, Some(old), None).map(|_| ())
188-
}
180+
fn drop(self, who: &AccountId) -> Result<(), DispatchError>;
189181
}
190182

191183
impl<A> Consideration<A> for () {
192-
type Ticket = ();
193-
fn update(_: &A, _: Option<()>, _: Option<Footprint>) -> Result<(), DispatchError> {
184+
fn new(_: &A, _: Footprint) -> Result<Self, DispatchError> {
185+
Ok(())
186+
}
187+
fn update(self, _: &A, _: Footprint) -> Result<(), DispatchError> {
188+
Ok(())
189+
}
190+
fn drop(self, _: &A) -> Result<(), DispatchError> {
194191
Ok(())
195192
}
196193
}

0 commit comments

Comments
 (0)