-
Notifications
You must be signed in to change notification settings - Fork 1
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
fix(storage-provider): registration extrinsic fix #143
Conversation
const HOURS: BlockNumber = MINUTES * 60; | ||
const DAYS: BlockNumber = HOURS * 24; | ||
const YEARS: BlockNumber = DAYS * 365; | ||
const MILLISECS_PER_BLOCK: u32 = 12000; |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
// 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>() |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this 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.
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. |
…ider-fails-with-conversionerror
@jmg-duarte Added a better description. If you have any more questions let me know. |
There was a problem hiding this 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; |
There was a problem hiding this comment.
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
I'll move it to u64 tomorrow. I have a feeling that the solution will be better that way. |
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 maximalwpost_proving_period
passed. The proving period is later used to mod theoffset
. Because we mod the offset with the u32 number, we know that the offset can later be saturated into theBlockNumber
.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
Yes. Many. It gets complicated fast :D This was the simplest aproach