Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Implement a CountedStorageMap #9125

Merged
29 commits merged into from
Sep 16, 2021
Merged

Implement a CountedStorageMap #9125

29 commits merged into from
Sep 16, 2021

Conversation

gui1117
Copy link
Contributor

@gui1117 gui1117 commented Jun 16, 2021

This PR introduces a new Storage abstraction: CountedStorageMap

The CountedStorageMap is a new type with a similar API as StorageMap which internally use a StorageMap and StorageValue<u32> and keeps count of the number of items in the map by using the value as a counter.

@github-actions github-actions bot added the A0-please_review Pull request needs code review. label Jun 16, 2021
@gui1117 gui1117 added B7-runtimenoteworthy C1-low PR touches the given topic and has a low impact on builders. D5-nicetohaveaudit ⚠️ PR contains trivial changes to logic that should be properly reviewed. labels Jun 16, 2021
}

/// Remove all value of the storage.
pub fn remove_all() {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

if we want to support limit, then we need sp-io to return the number of deleted key in the overlay, once merged I will open an issue, and we can work on it when we need it

Copy link
Contributor

Choose a reason for hiding this comment

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

What is limit?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

for other storage the remove_all method allow to remove only up to a certain number of key in the backend: https://substrate.dev/rustdocs/latest/frame_support/storage/types/struct.StorageMap.html#method.remove_all

Here it is not possible without changing sp-io. Because we need to count the value removed in the overlay. And https://substrate.dev/rustdocs/latest/sp_io/storage/fn.clear_prefix.html doesn't give us this information

@gui1117
Copy link
Contributor Author

gui1117 commented Jun 16, 2021

would StorageCountedMap be a better name than CountedStorageMap, this makes all storages type start with Storage ?

@shawntabrizi
Copy link
Member

would StorageCountedMap be a better name than CountedStorageMap, this makes all storages type start with Storage ?

I think CountedStorageMap is more natural, but I dont really care one way or another.

@shawntabrizi
Copy link
Member

@jacogr i think this is a change to the metadata

@shawntabrizi
Copy link
Member

AFAICT this looks good to me.

However, I wonder how scalable this overall approach is.

I can imagine we will continue to want to add new and different kinds of storage types to make runtime development easier and more ergonomic.

Do you see that writing all this code every time is sustainable?

@shawntabrizi
Copy link
Member

shawntabrizi commented Jun 16, 2021

Note also that we will already need to extend this API for all of our needs.

See here in Assets we have a StorageNMap:

https://github.com/paritytech/substrate/blob/master/frame/assets/src/lib.rs#L245

	#[pallet::storage]
	/// Approved balance transfers. First balance is the amount approved for transfer. Second
	/// is the amount of `T::Currency` reserved for storing this.
	/// First key is the asset ID, second key is the owner and third key is the delegate.
	pub(super) type Approvals<T: Config<I>, I: 'static = ()> = StorageNMap<
		_,
		(
			NMapKey<Blake2_128Concat, T::AssetId>,
			NMapKey<Blake2_128Concat, T::AccountId>, // owner
			NMapKey<Blake2_128Concat, T::AccountId>, // delegate
		),
		Approval<T::Balance, DepositBalanceOf<T, I>>,
		OptionQuery,
		GetDefault,
		ConstU32<300_000>,
	>;

We are not only interested in the total number of values for this whole map, but also just the number of values for the map under a specific user.

So something like CountedStorageNMap would need N - 1 counters... Does that change the way you approach this problem?

@KiChjang
Copy link
Contributor

I honestly think #8605 is a better approach here, but it looks like there is already a pressing need for counters? If so, the question then becomes maintaining a sensible API that's compatible with the storage mutation hooks. I agree that adding additional storage item types don't seem to be a scalable solution, and we may end up with a system that is overly complex.

I think all storage map types should simply support the basic CRUD operations, and if there is a need to add additional functionality to them, creating extension traits or functions sounds like the best way forward to me.

@jacogr
Copy link
Contributor

jacogr commented Jun 17, 2021

You will need to bump the metadata version - this is smack-bang in the middle of the enum which means V13 parsers cannot parse this at all.

@gui1117
Copy link
Contributor Author

gui1117 commented Jun 17, 2021 via email

@kianenigma kianenigma self-requested a review August 7, 2021 09:24
Copy link
Contributor

@kianenigma kianenigma left a comment

Choose a reason for hiding this comment

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

LGTM except a few suggestions, there should be a follow up that migrates the staking counters to this PR.

@stale
Copy link

stale bot commented Sep 6, 2021

Hey, is anyone still working on this? Due to the inactivity this issue has been automatically marked as stale. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the A5-stale Pull request did not receive any updates in a long time. No review needed at this stage. Close it. label Sep 6, 2021
@emostov emostov removed the A5-stale Pull request did not receive any updates in a long time. No review needed at this stage. Close it. label Sep 6, 2021
@gui1117
Copy link
Contributor Author

gui1117 commented Sep 16, 2021

I slightly refactored the metadata for storages, instead of having the trait StorageEntryMetadata which gives the name, the type, etc.. I did StorageEntryMetadataBuilder which directly build the metadata of the storage. This is good because in case of counted storage map it allows to generate both inner storage metadata (the map and the value holding the counter), without any additional code from the macro.
So the macro only needs to care about a few less stuff.

EDIT: if people want they can do a final review, but I think it is good to merge, and as behavior hasn't change, the current review are valid.

@gui1117
Copy link
Contributor Author

gui1117 commented Sep 16, 2021

bot merge

@ghost
Copy link

ghost commented Sep 16, 2021

Trying merge.

This pull request was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A0-please_review Pull request needs code review. C1-low PR touches the given topic and has a low impact on builders. D5-nicetohaveaudit ⚠️ PR contains trivial changes to logic that should be properly reviewed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants