-
Notifications
You must be signed in to change notification settings - Fork 237
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: store packing #343
feat: store packing #343
Conversation
6f7dbfd
to
cccedd3
Compare
cccedd3
to
8ceb04d
Compare
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.
Super cool and interesting chapter!
Co-authored-by: glihm <dev@glihm.net>
Thanks @glihm ! |
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.
When writing Cairo smart contracts, it is important to optimize storage usage to reduce gas costs. Indeed, most of the cost associated to a transaction is related to storage updates; and each storage slot costs gas to write to. | ||
This means that by packing multiple values into fewer slots, you can decrease the gas cost incurred to the users of your smart contract. | ||
|
||
Cairo provides the `StorePacking` trait to enable packing struct fields into a fewer number of storage slots. For example, consider a `Sizes` struct with 3 fields of different types. The total size is 8 + 32 + 64 = 104 bits. This is less than the 128 bits of a single `u128`. This means we can pack all 3 fields into a single `u128` variable, taking up only one storage slot instead of 3. |
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.
This makes it sound like a storage slot is exactly 128 bits, not full 251.
First, when packing: | ||
|
||
- `tiny` is a `u8` so we just convert it directly to a `u128` with `.into()`. This creates a `u128` value with the low 8 bits set to `tiny`'s value. | ||
- `small` is a `u32` so we first shift it left by 8 bits (add 8 bits with the value 0 to the left) to make space for `tiny`. The value of `tiny` now takes bits 0-7 and the value of small takes bits 8-39. Then we add tiny to small to combine them into a single `u128` value. This takes bits 8-39. |
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.
The wording here makes it sound like the shift size (8 bits) is a function of the size of the next element (small
, 32 bits), which of course it isn't.
TYVM for the reviews @milancermak @glihm ! |
* feat: store packing * Apply suggestions from code review Co-authored-by: glihm <dev@glihm.net> * fix: build * add suggestions * fmt --------- Co-authored-by: glihm <dev@glihm.net>
Added a chapter on storage packing for efficient storage optimisation
Closes #324