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

feat: dynamic deposit for did creation #507

Merged
merged 50 commits into from
May 11, 2023
Merged

feat: dynamic deposit for did creation #507

merged 50 commits into from
May 11, 2023

Conversation

Ad96el
Copy link
Member

@Ad96el Ad96el commented Apr 19, 2023

fixes 2636

Since the service endpoints would each support 2 URLs, the maximum DID size would also be bigger than before. To accommodate, the base deposit of around 2 KILT would remain, but the deposit could increase depending on heavy usage (calculated automatically if you rotate/add keys or add service endpoints). For example, having 25 service endpoints would increase the deposit needed, up to a maximum of 4 KILT. If you later delete the service endpoints and the DID gets smaller again the extra deposit would be automatically refunded.

The runtimeAPI call to get an approximation for the deposit will be developed in a different PR.

@Ad96el Ad96el marked this pull request as draft April 19, 2023 15:36
@Ad96el Ad96el marked this pull request as ready for review April 20, 2023 12:32
@Ad96el Ad96el requested review from weichweich and ntn-x2 April 20, 2023 12:32
Copy link
Contributor

@weichweich weichweich left a comment

Choose a reason for hiding this comment

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

Looks good! But there might be some bugs and I'm not 100% sure how to do the base deposit.

Comment on lines 1290 to 1294
let did_entry = Did::<T>::get(key);
match did_entry {
Some(entry) => entry.calculate_deposit(key),
_ => <T as Config>::BaseDeposit::get(),
}
Copy link
Contributor

Choose a reason for hiding this comment

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

A comment would be good here. Why take the base deposit when there is nothing in storage. This seems counter intuitive.

Would obviously be better if the interface would provide you with the item and not the key... I'm not 100% sure but there was some reason for adding the key and not the value here. 🤔

Copy link
Contributor

@weichweich weichweich left a comment

Choose a reason for hiding this comment

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

I think the benchmarks might not be accurate.

Comment on lines 343 to 345
#[cfg(not(feature = "runtime-benchmarks"))]
kilt_support::reserve_deposit::<AccountIdOf<T>, CurrencyOf<T>>(_who, _deposit_to_reserve)?;
Ok(())
Copy link
Contributor

Choose a reason for hiding this comment

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

We cannot simply omit this part in the runtime benchmarks? We would not benchmark the weight that is added by this call, which is not what we want.

Comment on lines 323 to 327
let count_endpoints: BalanceOf<T> = DidEndpointsCount::<T>::get(did_subject).into();
deposit = deposit.saturating_add(count_endpoints.saturating_mul(T::ServiceEndpointDeposit::get()));

let key_agreement_counts: BalanceOf<T> = self.key_agreement_keys.len().saturated_into();
deposit = deposit.saturating_add(key_agreement_counts.saturating_mul(T::KeyDeposit::get()));
Copy link
Contributor

Choose a reason for hiding this comment

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

For anyone with an OCD it's count_endpoints and key_agreement_counts. Once it's in front the other time in the back. 😱 Maybe rename them to endpoint_count and key_agreement_count

@@ -642,6 +639,30 @@ pub struct DidCreationDetails<T: Config> {
pub new_service_details: Vec<DidEndpoint<T>>,
}

impl<T: Config> DidCreationDetails<T> {
pub fn calculate_deposit(&self) -> BalanceOf<T> {
Copy link
Member

Choose a reason for hiding this comment

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

Do we still need this if we have the same function for DidDetails?

Copy link
Member Author

Choose a reason for hiding this comment

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

I need the function to evaluate the deposit before doing any heavy work. I think it is a design decision now. Likewise, I would leave it there, but if you think it is ugly and the computation power is to less to care about, I will remove it

Copy link
Member

Choose a reason for hiding this comment

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

Is the heavy work you are referring to the one that checks the validity of the input? If that's the case, it does not matter much, since we take fees for that anyway, based on the size of the input, and we never return any surplus in case we finish early (e.g., if the user has not enough funds to pay for the deposit). Hence I would say it makes sense to avoid duplication and remove the code to calculate the deposit from the creation details, and simply call it on the created DidDetails inside the creation operation.
Alternatively, you could also simply create the details from the creation, calculate and check for the deposit, then run all the checks.
But as I said, the extrinsic is benchmarked depending on the input, so it does not really matter if we return early from the function or not.

@Ad96el Ad96el requested review from weichweich and ntn-x2 May 8, 2023 12:29
Copy link
Member

@ntn-x2 ntn-x2 left a comment

Choose a reason for hiding this comment

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

It looks better! I have just one question about the calculation of the max deposit for a DID.

@@ -324,7 +324,18 @@ pub mod did {
/// The size is checked in the runtime by a test.
pub const MAX_DID_BYTE_LENGTH: u32 = 9918;

pub const DID_DEPOSIT: Balance = deposit(2 + MAX_NUMBER_OF_SERVICES_PER_DID, MAX_DID_BYTE_LENGTH);
/// The length of all used Keys.
pub const KEY_DID_BYTE_LENGTH: u32 = 32;
Copy link
Member

Choose a reason for hiding this comment

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

Is is rather the max length of a key, right? In future if we use a key that is 33 byte long, we will probably bump this to 33, right?

Copy link
Member Author

@Ad96el Ad96el May 9, 2023

Choose a reason for hiding this comment

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

Yes exactly 👯. I updated the comment.

Copy link
Member

Choose a reason for hiding this comment

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

Could you maybe rename the const as well? 😁

Copy link
Member

@ntn-x2 ntn-x2 left a comment

Choose a reason for hiding this comment

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

One last rename, and then it's good to go for me! 👌

@ntn-x2 ntn-x2 merged commit 70a85da into develop May 11, 2023
@ntn-x2 ntn-x2 deleted the feat/deposit branch May 11, 2023 12:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants