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

fix(storage-provider): registration extrinsic fix #143

Conversation

cernicc
Copy link
Member

@cernicc cernicc commented Jul 17, 2024

Description

The bug happens because we are trying to convert 64-bit value to the 32-bit. Code example is in the comment. The solution bounds the wpost_proving_period to the u32, so we know the maximal wpost_proving_period passed. The proving period is later used to mod the offset. Because we mod the offset with the u32 number, we know that the offset can later be saturated into the BlockNumber.

The solution can also be that we change the configured BlockNumber to the u64 and fix any config related issues. Hmm. This might be even better. If I understand the substrate, we choose the primitive types on which we depend on

Checklist

  • Make sure that you described what this change does.
  • Have you tested this solution?
  • Were there any alternative implementations considered?
    Yes. Many. It gets complicated fast :D This was the simplest aproach

@cernicc cernicc self-assigned this Jul 17, 2024
@cernicc cernicc added the ready for review Review is needed label Jul 17, 2024
const HOURS: BlockNumber = MINUTES * 60;
const DAYS: BlockNumber = HOURS * 24;
const YEARS: BlockNumber = DAYS * 365;
const MILLISECS_PER_BLOCK: u32 = 12000;
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think that's a good idea. We express time units in terms of blocks that passed, so the types must match the BlockNumber from the conceptual point of view.

Copy link
Member Author

@cernicc cernicc Jul 17, 2024

Choose a reason for hiding this comment

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

Hmm. I don't have this feeling. This is something similar as

type PlanetAgeYears = u64;
type UserAgeYears  = u8;

Both represent the distance on the same scale. Only the maximum boundary of that distance is different.

Suppose we implemented BlockDelta representing the distance between two blocks. In that case, The BlockDelta would have to be the same type as BlockNumber. These numbers are not BlockDelta because they can't contain an arbitrary distance between blocks. They are specified by us.

Copy link
Contributor

Choose a reason for hiding this comment

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

https://github.com/search?q=repo%3Aparitytech%2Fpolkadot-sdk%20DAYS&type=code -> when you look for it in the SDK code, they all use BlockNumber for this stuff.

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm. We can also change the BlockNumber to u64 and fix all config related issues. That would also solve this issue.

Copy link
Contributor

Choose a reason for hiding this comment

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

Seems to me that moving to u64 would also avoid the casts

@th7nder th7nder added this to the Phase 1 milestone Jul 17, 2024
@cernicc cernicc added ready for review Review is needed and removed ready for review Review is needed labels Jul 17, 2024
// Convert into block number. We can saturate because the offset is
// guaranteed to be less than the proving period. The guaranty is made by
// the modulo operation.
offset.saturated_into::<BlockNumber>()
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think saturated_into is good to use. See the comment on this post. You can do it with saturated_into(), but as soon as your block number is past 255, the value returned would be stuck at 255, and probably not very useful.

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 think this comment was written as the answer for Has anyone been able to convert substrate blocknumber to let's say a u8?

@cernicc cernicc mentioned this pull request Jul 19, 2024
3 tasks
Copy link
Contributor

@jmg-duarte jmg-duarte left a comment

Choose a reason for hiding this comment

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

I don't understand why this fixes the issue, it seems to me that this implementation may hide another bug in the worst case.

#136 doesn't explain the test situation under which the bug was found and this PR doesn't provide a test ensuring it works either.

It's lacking a lot of context, please cover the context in the PR description explaining the issue and why this actually fixes it, as well as add tests.

@th7nder
Copy link
Contributor

th7nder commented Jul 21, 2024

The original bug happens, because:

let digest = blake2_64(&addr);
// We're creating a 64-bit hash of Account address and BlockNumber
// To create a pseudo-random proving period.
let offset = u64::from_be_bytes(digest);
// We're trying to convert 64-bit bytes into 32-bit value (BlockNumber is defined as u32 in runtime)
let mut offset = TryInto::<BlockNumber>::try_into(offset).map_err(|_| ProofError::Conversion)?;
// So the try_into fails.

@cernicc cernicc requested a review from jmg-duarte July 22, 2024 07:38
@cernicc
Copy link
Member Author

cernicc commented Jul 22, 2024

@jmg-duarte Added a better description. If you have any more questions let me know.

Copy link
Contributor

@jmg-duarte jmg-duarte left a comment

Choose a reason for hiding this comment

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

LGTM but I wonder if we should move to BlockNumber = u64

const HOURS: BlockNumber = MINUTES * 60;
const DAYS: BlockNumber = HOURS * 24;
const YEARS: BlockNumber = DAYS * 365;
const MILLISECS_PER_BLOCK: u32 = 12000;
Copy link
Contributor

Choose a reason for hiding this comment

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

Seems to me that moving to u64 would also avoid the casts

…-settle-a-deal

fix(market-pallet): deal settling
@cernicc
Copy link
Member Author

cernicc commented Jul 22, 2024

LGTM but I wonder if we should move to BlockNumber = u64

I'll move it to u64 tomorrow. I have a feeling that the solution will be better that way.

@cernicc cernicc closed this Jul 23, 2024
@jmg-duarte jmg-duarte deleted the fix/136/storage-pallet-registering-a-provider-fails-with-conversionerror branch July 23, 2024 08:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ready for review Review is needed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Integration Tests: Storage Pallet: registering a provider fails with ConversionError
4 participants