| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
Optimize type casting by using `__transmute` instead of `asm` blocks (#7675) ## Description This PR improves gas costs and bytecode sizes by consistently replacing `asm`-based conversions of _reference types_ in `std` with `__transmute`. Note that **copy-types are still converted using `asm` blocks**, because currently we didn't extend `__transmute` to handle copy-types without demoting transmuted values to stack and actually casting pointers. This gives a performance penalty when transmuting copy-types which we don't want to have. As expected, removing `asm` blocks unlocked existing IR performance optimizations and resulted in performance improvements given in the comment below. Note that we might think of temporarily forbidding using `__transmute` with copy-types until it is properly supported. But we have code in `ops.sw` where `__transmute` must be used to convert between copy-types, because the operator trait methods must be const-evaluable and if they use `asm` for conversion, they cannot be. Historically, making them const-evaluable was the reason for adding `__transmute` in the first place. Note that in the future, we plan to improve IR optimizations by letting them be aware of "safe `asm` blocks". Pure conversion blocks will be considered safe. That improvement would likely bring the same performance benefits as rolling out `__transmute`, but: - it will take some time before we get it implemented, - regardless, `__transmute` is the expected way to convert types and we should use it consistentlty across the codebase. Note that the PR changes snapshot files in the `sway-ir` tests. These changes are not related to this PR, but likely to the snapshots not being updated because of the `insta` checks being silent. For more info see https://github.com/FuelLabs/sway/pull/7666#pullrequestreview-4589675640. ## Checklist - [x] I have linked to any relevant issues. - [ ] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [ ] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 2 个月前 | |
Optimize hashing by implementing `is_hash_trivial` (#7695) ## Description This PR extends the `Hash` trait with the `is_hash_trivial() -> bool` associated function. This function is supposed to return true if the hash byte representation of the type is the same as its runtime memory representation. By using `is_hash_trivial`, `std::hash::sha256` and `keccak256` module functions can skip expensive `Bytes` creation in the `Hasher` and directly hash the value's memory content. This optimization is similar to what `is_encode/decode_trivial()` associated functions are providing for ABI encoding/decoding. Similar to ABI encoding/decoding, implementation of hashing for a type is in full control of the Sway package that owns the type. In practice, and in `std` in particular, non-dynamic types are in general trivially hashable if their packed memory representation is the same as their runtime memory representation. Because of this, when implementing `Hash` for tuples, we use the `__runtime_mem_id` and the `__encoding_mem_id` intrinsics. While using the `__encoding_mem_id` might look like coupling encoding and hashing, it is not. What we are actually using is the notion of the "packed memory representation" that the `__encoding_mem_id` provides. Unfortunately, the intrinsic that provides this information was originally created for ABI encoding and not for a more generic usage, e.g., `__packed__mem_id`. To make the distinction clear and remove what looks like coupling of unrelated concepts, we will provide a follow-up PR that introduces intrinsics for use case based memory layouts: - `__mem_repr_id_runtime` - `__mem_repr_id_encoding` - `__mem_repr_id_hashing` Currently, all enums in the `std` hash their descriminators as `u8`. This makes them all being non-trivially hashable. For many of them, hashing the descriminator as `u64` would make them trivially hashable. This is however a breaking change that potentially affects the hashed data we already have deployed, e.g., `StorageMap` keys. In the future, we can provide this breaking change behind a feature flag. Enums that can benefit from being trivially hashed are marked in code with `TODO: (HASH-TRIVIAL-ENUMS)`. ## Checklist - [ ] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 1 个月前 | |
Optimize type casting by using `__transmute` instead of `asm` blocks (#7675) ## Description This PR improves gas costs and bytecode sizes by consistently replacing `asm`-based conversions of _reference types_ in `std` with `__transmute`. Note that **copy-types are still converted using `asm` blocks**, because currently we didn't extend `__transmute` to handle copy-types without demoting transmuted values to stack and actually casting pointers. This gives a performance penalty when transmuting copy-types which we don't want to have. As expected, removing `asm` blocks unlocked existing IR performance optimizations and resulted in performance improvements given in the comment below. Note that we might think of temporarily forbidding using `__transmute` with copy-types until it is properly supported. But we have code in `ops.sw` where `__transmute` must be used to convert between copy-types, because the operator trait methods must be const-evaluable and if they use `asm` for conversion, they cannot be. Historically, making them const-evaluable was the reason for adding `__transmute` in the first place. Note that in the future, we plan to improve IR optimizations by letting them be aware of "safe `asm` blocks". Pure conversion blocks will be considered safe. That improvement would likely bring the same performance benefits as rolling out `__transmute`, but: - it will take some time before we get it implemented, - regardless, `__transmute` is the expected way to convert types and we should use it consistentlty across the codebase. Note that the PR changes snapshot files in the `sway-ir` tests. These changes are not related to this PR, but likely to the snapshots not being updated because of the `insta` checks being silent. For more info see https://github.com/FuelLabs/sway/pull/7666#pullrequestreview-4589675640. ## Checklist - [x] I have linked to any relevant issues. - [ ] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [ ] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 2 个月前 | |
Optimize dynamic `std` types (#7683) ## Description This PR optimizes several aspects of dynamic `std` types: - Hashing of string arrays, by properly accommodating initial `Hasher` buffer capacity for the string length prefix. - `Bytes::clear`, by reusing the already allocated buffer, the same way `Vec` is doing it. - Removing expensive double-allocation and memory-copy in the `Bytes::append_raw_slice`. - Adding `from_moved_...` constructors to types that own their buffers, for supporting taking ownership of the content without copying it. - Adding `from_ascii_str_array` constructor to `String` to create a string directly from string array without a need to first copy it to `str` via `from_str_array`. Additionally, the PR: - fixes invalid doc-comment examples on `String` methods, that were using a non-existing `String::push` method. ## Performance Improvements Performance improvements are given in the comment below. Although the PR obviously only removes runtime overhead, we still have some smaller numbers of regressions. Regressions are analyzed and have the same root-cause, the one we already encountered before. The leaner `Bytes::append_raw_slice` now leads to more inlining in hashing code like `sha256` that brings `CastPtr` to caller scope suppressing potential optimizations in the caller. The regressions on real-life o2 code are small and in contract methods that are not frequently used while improvements are bigger and in often use contract methods. Improving this particular issue will be done in #7492. Also, analysis of regressions in `sha256` and `keccak256` calls revealed another potentially high future performance improvement. E.g., hashing a `b256` using `s256` opcode directly costs ~60 gas units, while using `sha256` function will cost ~250 gas units. Similar values for are for `u8`, .., `u256` and even worse for larger structured types. One way to improve our hashing abstractions is to introduce a concept of "trivially hashable types", similar to trivially encodeable and decodeable. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 1 个月前 | |
Optimize hashing by implementing `is_hash_trivial` (#7695) ## Description This PR extends the `Hash` trait with the `is_hash_trivial() -> bool` associated function. This function is supposed to return true if the hash byte representation of the type is the same as its runtime memory representation. By using `is_hash_trivial`, `std::hash::sha256` and `keccak256` module functions can skip expensive `Bytes` creation in the `Hasher` and directly hash the value's memory content. This optimization is similar to what `is_encode/decode_trivial()` associated functions are providing for ABI encoding/decoding. Similar to ABI encoding/decoding, implementation of hashing for a type is in full control of the Sway package that owns the type. In practice, and in `std` in particular, non-dynamic types are in general trivially hashable if their packed memory representation is the same as their runtime memory representation. Because of this, when implementing `Hash` for tuples, we use the `__runtime_mem_id` and the `__encoding_mem_id` intrinsics. While using the `__encoding_mem_id` might look like coupling encoding and hashing, it is not. What we are actually using is the notion of the "packed memory representation" that the `__encoding_mem_id` provides. Unfortunately, the intrinsic that provides this information was originally created for ABI encoding and not for a more generic usage, e.g., `__packed__mem_id`. To make the distinction clear and remove what looks like coupling of unrelated concepts, we will provide a follow-up PR that introduces intrinsics for use case based memory layouts: - `__mem_repr_id_runtime` - `__mem_repr_id_encoding` - `__mem_repr_id_hashing` Currently, all enums in the `std` hash their descriminators as `u8`. This makes them all being non-trivially hashable. For many of them, hashing the descriminator as `u64` would make them trivially hashable. This is however a breaking change that potentially affects the hashed data we already have deployed, e.g., `StorageMap` keys. In the future, we can provide this breaking change behind a feature flag. Enums that can benefit from being trivially hashed are marked in code with `TODO: (HASH-TRIVIAL-ENUMS)`. ## Checklist - [ ] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 1 个月前 | |
Optimize hashing by implementing `is_hash_trivial` (#7695) ## Description This PR extends the `Hash` trait with the `is_hash_trivial() -> bool` associated function. This function is supposed to return true if the hash byte representation of the type is the same as its runtime memory representation. By using `is_hash_trivial`, `std::hash::sha256` and `keccak256` module functions can skip expensive `Bytes` creation in the `Hasher` and directly hash the value's memory content. This optimization is similar to what `is_encode/decode_trivial()` associated functions are providing for ABI encoding/decoding. Similar to ABI encoding/decoding, implementation of hashing for a type is in full control of the Sway package that owns the type. In practice, and in `std` in particular, non-dynamic types are in general trivially hashable if their packed memory representation is the same as their runtime memory representation. Because of this, when implementing `Hash` for tuples, we use the `__runtime_mem_id` and the `__encoding_mem_id` intrinsics. While using the `__encoding_mem_id` might look like coupling encoding and hashing, it is not. What we are actually using is the notion of the "packed memory representation" that the `__encoding_mem_id` provides. Unfortunately, the intrinsic that provides this information was originally created for ABI encoding and not for a more generic usage, e.g., `__packed__mem_id`. To make the distinction clear and remove what looks like coupling of unrelated concepts, we will provide a follow-up PR that introduces intrinsics for use case based memory layouts: - `__mem_repr_id_runtime` - `__mem_repr_id_encoding` - `__mem_repr_id_hashing` Currently, all enums in the `std` hash their descriminators as `u8`. This makes them all being non-trivially hashable. For many of them, hashing the descriminator as `u64` would make them trivially hashable. This is however a breaking change that potentially affects the hashed data we already have deployed, e.g., `StorageMap` keys. In the future, we can provide this breaking change behind a feature flag. Enums that can benefit from being trivially hashed are marked in code with `TODO: (HASH-TRIVIAL-ENUMS)`. ## Checklist - [ ] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 1 个月前 | |
Update library inline docs descriptions (#5984) ## Description While reviewing the [std-lib docs](https://fuellabs.github.io/sway/master/std/), it was noted that some of the libraries and modules do not have docs or are outdated. These have been updated. ## Checklist - [ ] I have linked to any relevant issues. - [ ] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [ ] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: K1-R1 <77465250+K1-R1@users.noreply.github.com> | 2 年前 | |
Introduce `alloc` intrinsic to avoid using `asm` (#7499) Improvement chart: https://github.com/FuelLabs/sway/pull/7499#issuecomment-3574549744 --------- Co-authored-by: Igor Rončević <ironcev@hotmail.com> | 9 个月前 | |
Add bytes conversions and move array conversions to std lib (#5180) ## Description Add bytes conversions and move array conversions to std lib ## Checklist - [ ] I have linked to any relevant issues. - [ ] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [ ] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [ ] I have requested a review from the relevant team or maintainers. | 2 年前 | |
`assert_eq` requires `PartialEq` instead of `Eq` (#7105) ## Description This PR changes the trait constraints on `assert_eq` and `assert_ne` from `Eq` to `PartialEq`. The `Eq` requirement was unnecessary strong, and is actually a "leftover" from the original implementation, before we introduced `PartialEq`. ## Checklist - [ ] I have linked to any relevant issues. - [ ] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [ ] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 1 年前 | |
Increase Safety when introspecting transaction outputs (#6414) ## Description When using the`outputs.sw` library of the std-lib, if a bad input was given to the functions or a transaction did not exist, the functions would revert. Instead, they now return options so errors may be caught. ## Fixes - This PR updates `output_count()` to return a `u16` which follows the fuel specifications. - `output_pointer()` now returns a pointer rather than a `u64` and is private ## Breaking There are a number of breaking changes in function return types. - `output_type()` now returns an `Option<Output>`. Before: ```sway let my_output_type: Output = output_type(0); ``` After: ```sway let my_output_type: Output = output_type(0).unwrap(); ``` - `output_pointer()` now returns an `Option<raw_ptr>` and is private Before: ```sway let my_output_pointer: u64 = output_pointer(0); ``` After: ```sway let my_output_pointer: raw_ptr = output_pointer(0).unwrap(); ``` - `output_count()` now returns a `u16`. Before: ```sway let output_count: u64 = output_count(); ``` After: ```sway let my_output_count: u16 = output_count(); ``` - `output_amount()` now returns an `Option<u64>`. Before: ```sway let my_output_amount: u64 = output_amount(0); ``` After: ```sway let my_output_amount: Option<u64> = output_amount(0).unwrap(); ``` ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: K1-R1 <77465250+K1-R1@users.noreply.github.com> | 2 年前 | |
Optimize hashing by implementing `is_hash_trivial` (#7695) ## Description This PR extends the `Hash` trait with the `is_hash_trivial() -> bool` associated function. This function is supposed to return true if the hash byte representation of the type is the same as its runtime memory representation. By using `is_hash_trivial`, `std::hash::sha256` and `keccak256` module functions can skip expensive `Bytes` creation in the `Hasher` and directly hash the value's memory content. This optimization is similar to what `is_encode/decode_trivial()` associated functions are providing for ABI encoding/decoding. Similar to ABI encoding/decoding, implementation of hashing for a type is in full control of the Sway package that owns the type. In practice, and in `std` in particular, non-dynamic types are in general trivially hashable if their packed memory representation is the same as their runtime memory representation. Because of this, when implementing `Hash` for tuples, we use the `__runtime_mem_id` and the `__encoding_mem_id` intrinsics. While using the `__encoding_mem_id` might look like coupling encoding and hashing, it is not. What we are actually using is the notion of the "packed memory representation" that the `__encoding_mem_id` provides. Unfortunately, the intrinsic that provides this information was originally created for ABI encoding and not for a more generic usage, e.g., `__packed__mem_id`. To make the distinction clear and remove what looks like coupling of unrelated concepts, we will provide a follow-up PR that introduces intrinsics for use case based memory layouts: - `__mem_repr_id_runtime` - `__mem_repr_id_encoding` - `__mem_repr_id_hashing` Currently, all enums in the `std` hash their descriminators as `u8`. This makes them all being non-trivially hashable. For many of them, hashing the descriminator as `u64` would make them trivially hashable. This is however a breaking change that potentially affects the hashed data we already have deployed, e.g., `StorageMap` keys. In the future, we can provide this breaking change behind a feature flag. Enums that can benefit from being trivially hashed are marked in code with `TODO: (HASH-TRIVIAL-ENUMS)`. ## Checklist - [ ] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 1 个月前 | |
Better `Debug` tests and impls for primitives and std lib types (#7119) ## Description This PR is a continuation of https://github.com/FuelLabs/sway/pull/7015. It is fixing the number printing function, which was not working correctly for zero. It also fixes a problem when printing `enum` variants. To improve `__dbg`, we are also now printing the argument span. An improved test now tests if all relevant `strucs` and `enums` from the `std` library are debug and show how they are printed. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: kaya <kaya.gokalp@fuel.sh> | 1 年前 | |
Optimize hashing by implementing `is_hash_trivial` (#7695) ## Description This PR extends the `Hash` trait with the `is_hash_trivial() -> bool` associated function. This function is supposed to return true if the hash byte representation of the type is the same as its runtime memory representation. By using `is_hash_trivial`, `std::hash::sha256` and `keccak256` module functions can skip expensive `Bytes` creation in the `Hasher` and directly hash the value's memory content. This optimization is similar to what `is_encode/decode_trivial()` associated functions are providing for ABI encoding/decoding. Similar to ABI encoding/decoding, implementation of hashing for a type is in full control of the Sway package that owns the type. In practice, and in `std` in particular, non-dynamic types are in general trivially hashable if their packed memory representation is the same as their runtime memory representation. Because of this, when implementing `Hash` for tuples, we use the `__runtime_mem_id` and the `__encoding_mem_id` intrinsics. While using the `__encoding_mem_id` might look like coupling encoding and hashing, it is not. What we are actually using is the notion of the "packed memory representation" that the `__encoding_mem_id` provides. Unfortunately, the intrinsic that provides this information was originally created for ABI encoding and not for a more generic usage, e.g., `__packed__mem_id`. To make the distinction clear and remove what looks like coupling of unrelated concepts, we will provide a follow-up PR that introduces intrinsics for use case based memory layouts: - `__mem_repr_id_runtime` - `__mem_repr_id_encoding` - `__mem_repr_id_hashing` Currently, all enums in the `std` hash their descriminators as `u8`. This makes them all being non-trivially hashable. For many of them, hashing the descriminator as `u64` would make them trivially hashable. This is however a breaking change that potentially affects the hashed data we already have deployed, e.g., `StorageMap` keys. In the future, we can provide this breaking change behind a feature flag. Enums that can benefit from being trivially hashed are marked in code with `TODO: (HASH-TRIVIAL-ENUMS)`. ## Checklist - [ ] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 1 个月前 | |
Support `GM_GET_CHAIN_ID` GM opcode with `chain_id()` function (#7222) ## Description Adds a `chain_id()` function to return the current chain id using the `GM_GET_CHAIN_ID` opcode. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [x] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 1 年前 | |
Optimize dynamic `std` types (#7683) ## Description This PR optimizes several aspects of dynamic `std` types: - Hashing of string arrays, by properly accommodating initial `Hasher` buffer capacity for the string length prefix. - `Bytes::clear`, by reusing the already allocated buffer, the same way `Vec` is doing it. - Removing expensive double-allocation and memory-copy in the `Bytes::append_raw_slice`. - Adding `from_moved_...` constructors to types that own their buffers, for supporting taking ownership of the content without copying it. - Adding `from_ascii_str_array` constructor to `String` to create a string directly from string array without a need to first copy it to `str` via `from_str_array`. Additionally, the PR: - fixes invalid doc-comment examples on `String` methods, that were using a non-existing `String::push` method. ## Performance Improvements Performance improvements are given in the comment below. Although the PR obviously only removes runtime overhead, we still have some smaller numbers of regressions. Regressions are analyzed and have the same root-cause, the one we already encountered before. The leaner `Bytes::append_raw_slice` now leads to more inlining in hashing code like `sha256` that brings `CastPtr` to caller scope suppressing potential optimizations in the caller. The regressions on real-life o2 code are small and in contract methods that are not frequently used while improvements are bigger and in often use contract methods. Improving this particular issue will be done in #7492. Also, analysis of regressions in `sha256` and `keccak256` calls revealed another potentially high future performance improvement. E.g., hashing a `b256` using `s256` opcode directly costs ~60 gas units, while using `sha256` function will cost ~250 gas units. Similar values for are for `u8`, .., `u256` and even worse for larger structured types. One way to improve our hashing abstractions is to introduce a concept of "trivially hashable types", similar to trivially encodeable and decodeable. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 1 个月前 | |
Add bytes conversions and move array conversions to std lib (#5180) ## Description Add bytes conversions and move array conversions to std lib ## Checklist - [ ] I have linked to any relevant issues. - [ ] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [ ] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [ ] I have requested a review from the relevant team or maintainers. | 2 年前 | |
Better `Debug` tests and impls for primitives and std lib types (#7119) ## Description This PR is a continuation of https://github.com/FuelLabs/sway/pull/7015. It is fixing the number printing function, which was not working correctly for zero. It also fixes a problem when printing `enum` variants. To improve `__dbg`, we are also now printing the argument span. An improved test now tests if all relevant `strucs` and `enums` from the `std` library are debug and show how they are printed. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: kaya <kaya.gokalp@fuel.sh> | 1 年前 | |
Refactor and tidy up `std` tests for execution speed and discoverability (#7669) ## Description This PR represents a major cleanup and refactoring of tests covering `std` and closes #7617. The PR brings: - **consistency**: all `std` tests are now in `in_language_tests` and not scattered anymore on four different places (`sway-lib-std`, `stdlib`, `sdk-harness`, and `in_language_tests`). - **better discoverability**: test Sway files have the same name as their tested modules and appear in IDE file searches next to each other. - **better execution speed**: by removing redundant test projects and grouping existing `in_language_tests` projects per tested `std` modules we reduced the number of projects to compile and tests to run noticeably gaining on test execution speed. The above benefits are gained via: - porting E2E `stdlib` tests to `in_language_tests` and deleting redundant test projects. - porting `std` related SDK harness tests to `in_language_tests` and deleting redundant test projects. - moving 11 unit tests found in `sway-lib-std` to `in_language_tests` and forbidding writing unit tests in the `sway-lib-std`. `std` test **must** now be situated in in-language tests. The consequence of this decision is losing the possibility to test private members. Currently this is not a limitation. If it ever becomes, we can allow intentional testing of private members, e.g., via special test naming conventions or some other approach. - restructuring `in_language_tests` for better discoverability and test execution speed. The guidelines for writing in-language tests are fully documented in the accompanied README.md. The PR also acknowledges the control and flexibility we gained by introducing `run_in_language_tests.sh`. Although initially introduced as a workaround for #7613 the script proved to be more powerful and useful for development than using plain `forc test` of the workspace. Therefore, the PR removes TODOs related to switching back to `forc test`ing the whole workspace. The new structure of in-language tests reflects the `std` module structure. Having test modules being named the same as their tested `std` modules allows for quicker finding of both the module and its tests in IDEs. The new convention also removes the verbosity of the `_inline_tests` and `_contract_tests` prefixes. It turned out that this verbose additional information didn't bring a concrete benefit, while producing visual clutter. The faster test execution is noticeable. By grouping several in-language projects into a single one we have less `std` compilations. Number of initial in-language projects dropped from 72 to 47 causing parallel execution time of whole suite to drop from ~55s to ~40s. Similarly, we deleted the following number of other test projects that were redundant and already covered by in-language tests: 1. 35 out of 39 `stdlib` test projects from E2E tests, 1. 8 SDK harness test projects. - Closes #7617. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 2 个月前 | |
Implement `__mem_rep_eq` intrinsic (#7697) ## Description This PR introduces a new `__mem_repr_eq` intrinsic for comparing memory representation of types, and removes the existing `__runtime_mem_id` and `__encoding_mem_id` intrinsics. We decided to introduce `__mem_repr_eq` to mitigate the following issues we had with existing intrinsics: - `mem_id`s were `u64` values computed using `DefaultHasher` whose results are not guaranteed to be stable across different runs of the same Sway compiler or being same on different target architectures. - even if we switched to a stable hasher, hashing to `u64` was not giving a strong no-collision guarantee. A hash collision between different, e.g. runtime and encoding representation, would in case of false positives result in wrong encoding or decoding. The `__mem_repr_eq` is defined as: ```sway __mem_repr_eq<T>(repr_a: str, repr_b: str) -> bool ``` It returns `true` if the memory representation `repr_a` of the type `T` is equal to its memory representation `repr_b`, assuming `T` has both memory representations. If `T` does not have any of the representations `repr_a` or `repr_b`, returns `false`. The valid values for `repr_a` and `repr_b` are `"runtime"`, `"encoding"`, and `"hashing"`: - `"runtime"` is how the type is represented inside the VM's memory. This is the Sway runtime memory representation (e.g., struct fields are aligned to word boundaries, arrays are packed, etc.). This memory representation is defined for every type. - `"encoding"` is the packed memory representation of a type, as defined by the canonical ABI encoding. Not all types have a canonical ABI encoding defined, e.g., dynamic types like `Vec` or `raw_slice`. In that case, `"encoding"` never compares equal to any other memory representation, __including to itself__. - `"hashing"` is the packed memory representation of a type, as defined by the canonical hashing introduced in #7695. Not all types have a canonical hashing defined, e.g., dynamic types like `Vec` or `raw_slice`. In that case, `"hashing"` never compares equal to any other memory representation, __including to itself__. To test if a type `T` has `"encoding"` or `"hashing"` memory representation defined, compare that representation to itself. E.g.: `let has_encoding_repr = __mem_repr_eq<T>("encoding", "encoding");` `repr_a` and `repr_b` must be compile-time constant `str`s, whose values are one of `"runtime"`, `"encoding"`, or `"hashing"`. The constant `str`s never end up in the bytecode. Additionally, the PR moves existing E2E intrinsics tests that were not in the `language/intrinsics` into `language/intrinsics`. ## Breaking Change The old `__runtime_mem_id` and `__encoding_mem_id` intrinsics are removed. The code that is using them must switch to the new `__mem_repr_eq`. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 1 个月前 | |
Defining, parsing, and checking `#[attribute]`s (#6986) ## Description This PR reimplements how `#[attribute]`s are parsed, defined, and checked. It fixes the following issues we had with attributes: - attributes were in general not checked for their expected and allowed usage. - when checked, checks were fixing particular reported issues and were scattered through various compilation phases: lexing, parsing, and tree conversion. - when checked, reported errors in some cases had bugs and were overalapping with other errors and warnings. - attribute handling was not centralized, but rahter scattered throught the whole code base, and mostly done at use sites. For concrete examples of these issues, see the list of closed issues below. The PR: - encapsulates the attributes handling within a single abstraction: `Attributes`. - assigns the following properties to every attribute: - _target_: what kind of elements an attribute can annotate. - _multiplicity_: if more then one attribute of the same kind can be applied to an element. - _arguments multiplicity_: a range defining how many arguments an attribute can or must have. - _arguments value expectation_: if attribute arguments are expected to have values. - validates those properties in a single place, during the `convert_parse_tree`. Note that this means that modules with attribute issues will now consistently not reach the type checking phase. This was previously the case for some of the issues with attributes where custom checks where done during the type checking phase. #6987 proposes to move those checks after the tree conversion phase, allowing the continuation of compilation. - adds the `AttributeKind::Unknow` to preserve unknown attributes in the typed tree. - removes redundant code related to attributes: specific warnings and errors, specialized parsing, repetitive and error-prone at use site checks, etc. - removes the unused `Doc` attribute. The PR also introduces a new pattern in emitting errors. The `attr_decls_to_attributes` function will always return `Attributes` even if they have errors, because: - we expect the compilation to continue even in the case of errors. - we expect those errors to be ignored if a valid `#[cfg]` attribute among those evaluates to false. - we expect them to be emitted with eventual other errors, or alone, at the end of the tree conversion of the annotated element. For more details, see the comment on `attr_decls_to_attributes` and `cfg_eval`. Closes #6880; closes #6913; closes #6914; closes #6915; closes #6916; closes #6917; closes #6918; closes #6931; closes #6981; closes #6983; closes #6984; closes #6985. ## Breaking changes Strictly seen, this PR can cause breaking changes, but only in the case of invalid existing attribute usage. We treat those breaking changes as bug fixes in the compiler and, thus, do not have them behind a feature flag. E.g., this kind of code was possible before, but will now emit and error: ```sway #[storage(read, write, read, write)] struct Struct {} ``` ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 1 年前 | |
Remove `contract_id()` in favor of `ContractId::this()` (#5867) ## Description We currently support 2 methods of getting the contract id of a contract in an internal context: - `contract_id()` - `ContractId::this()` The `this()` associated function is a constructor that returns `Self` and should be the primary method of getting the contract id. This idiomatically follows Rust's syntax and `contract_id()` has been removed. The same syntax is followed with `AssetId::base()`. Closes #5834 ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: SwayStar123 <46050679+SwayStar123@users.noreply.github.com> | 2 年前 | |
Optimize hashing by implementing `is_hash_trivial` (#7695) ## Description This PR extends the `Hash` trait with the `is_hash_trivial() -> bool` associated function. This function is supposed to return true if the hash byte representation of the type is the same as its runtime memory representation. By using `is_hash_trivial`, `std::hash::sha256` and `keccak256` module functions can skip expensive `Bytes` creation in the `Hasher` and directly hash the value's memory content. This optimization is similar to what `is_encode/decode_trivial()` associated functions are providing for ABI encoding/decoding. Similar to ABI encoding/decoding, implementation of hashing for a type is in full control of the Sway package that owns the type. In practice, and in `std` in particular, non-dynamic types are in general trivially hashable if their packed memory representation is the same as their runtime memory representation. Because of this, when implementing `Hash` for tuples, we use the `__runtime_mem_id` and the `__encoding_mem_id` intrinsics. While using the `__encoding_mem_id` might look like coupling encoding and hashing, it is not. What we are actually using is the notion of the "packed memory representation" that the `__encoding_mem_id` provides. Unfortunately, the intrinsic that provides this information was originally created for ABI encoding and not for a more generic usage, e.g., `__packed__mem_id`. To make the distinction clear and remove what looks like coupling of unrelated concepts, we will provide a follow-up PR that introduces intrinsics for use case based memory layouts: - `__mem_repr_id_runtime` - `__mem_repr_id_encoding` - `__mem_repr_id_hashing` Currently, all enums in the `std` hash their descriminators as `u8`. This makes them all being non-trivially hashable. For many of them, hashing the descriminator as `u64` would make them trivially hashable. This is however a breaking change that potentially affects the hashed data we already have deployed, e.g., `StorageMap` keys. In the future, we can provide this breaking change behind a feature flag. Enums that can benefit from being trivially hashed are marked in code with `TODO: (HASH-TRIVIAL-ENUMS)`. ## Checklist - [ ] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 1 个月前 | |
Redesign From trait into From/Into pair (#5259) ## Description Change `From` conversion trait into the expected `From`/`Into` rust-like trait pair and `TryFrom` into a `TryFrom`/`TryInto` pair. ## Checklist - [ ] I have linked to any relevant issues. - [ ] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: Marcos Henrich <marcoshenrich@gmail.com> Co-authored-by: João Matos <joao@tritao.eu> Co-authored-by: Joshua Batty <joshpbatty@gmail.com> | 2 年前 | |
Std-lib support for ZK opcodes (#6832) ## Description This PR adds support for the `ecop` and `epar` opcodes in the std-lib. It also introduces the `Point2D` and `Scalar` type support cryptographic operations. The new crypto module follows the same format as developed in https://github.com/FuelLabs/sway/pull/5747 which is still yet to come, ensuring compatibility. The `Point2D` and `Scalar` types also use `Bytes` under the hood to ensure future curves with points larger than 32 bytes are still supported. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [x] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: green <xgreenx9999@gmail.com> Co-authored-by: Vaivaswatha Nagaraj <vaivaswatha.nagaraj@fuel.sh> | 1 年前 | |
Optimize type casting by using `__transmute` instead of `asm` blocks (#7675) ## Description This PR improves gas costs and bytecode sizes by consistently replacing `asm`-based conversions of _reference types_ in `std` with `__transmute`. Note that **copy-types are still converted using `asm` blocks**, because currently we didn't extend `__transmute` to handle copy-types without demoting transmuted values to stack and actually casting pointers. This gives a performance penalty when transmuting copy-types which we don't want to have. As expected, removing `asm` blocks unlocked existing IR performance optimizations and resulted in performance improvements given in the comment below. Note that we might think of temporarily forbidding using `__transmute` with copy-types until it is properly supported. But we have code in `ops.sw` where `__transmute` must be used to convert between copy-types, because the operator trait methods must be const-evaluable and if they use `asm` for conversion, they cannot be. Historically, making them const-evaluable was the reason for adding `__transmute` in the first place. Note that in the future, we plan to improve IR optimizations by letting them be aware of "safe `asm` blocks". Pure conversion blocks will be considered safe. That improvement would likely bring the same performance benefits as rolling out `__transmute`, but: - it will take some time before we get it implemented, - regardless, `__transmute` is the expected way to convert types and we should use it consistentlty across the codebase. Note that the PR changes snapshot files in the `sway-ir` tests. These changes are not related to this PR, but likely to the snapshots not being updated because of the `insta` checks being silent. For more info see https://github.com/FuelLabs/sway/pull/7666#pullrequestreview-4589675640. ## Checklist - [x] I have linked to any relevant issues. - [ ] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [ ] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 2 个月前 | |
Better `Debug` tests and impls for primitives and std lib types (#7119) ## Description This PR is a continuation of https://github.com/FuelLabs/sway/pull/7015. It is fixing the number printing function, which was not working correctly for zero. It also fixes a problem when printing `enum` variants. To improve `__dbg`, we are also now printing the argument span. An improved test now tests if all relevant `strucs` and `enums` from the `std` library are debug and show how they are printed. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: kaya <kaya.gokalp@fuel.sh> | 1 年前 | |
Attribute for checking of trivial encoding and decoding (#7575) ## Description Closes https://github.com/FuelLabs/sway/issues/7567. ## Checklist - [ ] I have linked to any relevant issues. - [ ] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [ ] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [ ] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [ ] I have requested a review from the relevant team or maintainers. | 3 个月前 | |
Updates JSON ABI, LDC, BSIZ, BLDD and ED19. (#6254) ## Description Updates all the dependencies for the current release. Implements the fuel ABI generation changes proposed in https://github.com/FuelLabs/fuel-specs/pull/599. Removes the flag `--json-abi-with-callpaths` and the behavior is as if it were true. We removed the flag because it is unsafe to produce JSON ABIs without callpaths, so we shouldn't allow it. Includes the LDC, BSIZ, BLDD and ED19 changes from:https://github.com/FuelLabs/sway/pull/6409. Fixes https://github.com/FuelLabs/sway/issues/5954 Fixes https://github.com/FuelLabs/sway/issues/5151 ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: Vaivaswatha Nagaraj <vaivaswatha.nagaraj@fuel.sh> Co-authored-by: Kaya Gokalp <kayagokalp123@gmail.com> Co-authored-by: Kaya Gökalp <kaya.gokalp@fuel.sh> Co-authored-by: Igor Rončević <ironcev@hotmail.com> Co-authored-by: IGI-111 <igi-111@protonmail.com> Co-authored-by: Sophie Dankel <47993817+sdankel@users.noreply.github.com> | 2 年前 | |
Increase test coverage on std-lib (#6087) ## Description Completes in-language tests for https://github.com/FuelLabs/sway/issues/6038. Any tests in the std-lib have been moved into the `test/src/in_language_tests` folder. This has been done to ensure imports behave as expected and fields that should be public are. While many of the functions that have new tests are used elsewhere in the tests, there were no tests to explicitly check that it is behaving as expected. # The following tests have been added: ## Address: - bits() - Eq - Neq - b256.into() - b256::from() - Hash - is_zero() ## Assert - Assert revert when not true - Assert_eq revert when not true - Assert_ne revert when not false ## Asset Id - Eq - Neq - b256.into() - b256::from() - new() - default() - bits() - is_zero() ## B512 - Eq - Neq - Into - b256::from - b256.into() - new() - bits() - is_zero() ## Bytes - with_capacity() - capacity() - is_empty() - ptr() - b256.into() - b256::from() - clone() ## ContractId - bits() - Eq - Neq - b256.into() - b256::from() - is_zero() ## Hash - write_str_array() - Hash for 2, 3, 4, 5 tuple - Hash 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 arrays - sha256() - sha256_str_array() - kekkack() ## Identity - Eq - Neq - Hash ## Option - Neq - ok_or() - expect() ## Result - Neq - expect() ## String - ptr() - Bytes::from() - Bytes.into() - as_raw_slice() ## U128 - into u8 - into u16 - into u32 - into u64 - From (u64, u64) - Into (u64, u64) - (u64, u64)::from - (u64, u64).into() - Eq - Neq - Ord - new() - min() - max() - bits() - upper() - lower() - log2 - u8.into() - u8::from() - u16.into() - u16::from() - u32.into() - u32::from() - u64.into() - u64::from() - u256.into() - u256::from() ## Primitive Conversions ### b256 - into u256 ### u16 - into u8 ### u32 - into u8 - into u16 ### u64 - into u8 - into u16 - into u32 ### u256 - into u8 - into u16 - into u32 - into u64 - into b256 - into u256 - into tuple ## EvmAddrsss - bits() - Eq - Neq - is_zero() - b256::from() - b256.into() # Additional Edge cases have been added: ## Address - Min & max edge cases ## Alloc - Check alloc() does not exceed bounds - Check realloc() same size - Check realloc() less size does nothing - Check realloc() excludes values if less than current - realloc() reverts on unallocated memory - alloc_bytes() does not exceed bounds - realloc_bytes() same size - realloc_bytes() less size does nothing - realloc_bytes() excludes values if less than current - realloc_bytes() reverts on unallocated memory ## Assert - No tests for array ## AssetId - Min & max edge cases ## B512 - Min & max edge cases ## Bytes - Push increases capacity - Pop does not change capacity - Check get result when out of bounds - Set front - Set back - Set does not change capacity - Set twice - Set behavior when out of bounds - Insert front - Insert back - Insert changes capacity - Insert behavior when out of bounds - Remove front - Remove back - Remove does not change capacity - Remove all - Remove behavior when out of bounds - Swap front - Swap back - Swap does not change capacity - Swap behavior when out of bounds - len() updates - Split twice - Split capacity checks - Split behavior when out of bounds - Append changes capacity ## ContractId - Min & max edge cases ## Hash - Min & max edge cases ## Identity - Min & max edge cases ## Option - Coverage on all primitive types ## Result - Coverage on all primitive types ## Revert - Require reverts on false ## U128 - Revert on add when overflow - Revert on sub when negative - Revert on mul when overflow - Revert on divide by zero - Min & max edge cases ## Primitive Conversions ### b256 - Min & max edge cases ### u8 - Min & max edge cases ### u16 - Min & max edge cases ### u32 - Min & max edge cases ### u64 - Min & max edge cases ### u256 - Min & max edge cases ## EvmAddress - Min & max edge cases ## evm ecr recover - Result error when failed to recover The following issue have been discovered by writing these tests: - https://github.com/FuelLabs/sway/issues/6085 - https://github.com/FuelLabs/sway/issues/6077 - https://github.com/FuelLabs/sway/issues/6086 - https://github.com/FuelLabs/sway/issues/6073 - https://github.com/FuelLabs/sway/pull/6037 - https://github.com/FuelLabs/sway/issues/6088 - https://github.com/FuelLabs/sway/issues/6104 - Addtional changes made in this PR. These include docs updates and a private enum that should be public ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: IGI-111 <igi-111@protonmail.com> Co-authored-by: K1-R1 <77465250+K1-R1@users.noreply.github.com> | 2 年前 | |
Merge std and core libraries (#6729) ## Description Merges the two libraries. They were initially separate to separate the core logic and fuel vm specific functionality, but that separation is no longer maintained so having a merged library is better. Closes #6708 ## Checklist - [ ] I have linked to any relevant issues. - [ ] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [ ] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [ ] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [ ] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: Sophie <47993817+sdankel@users.noreply.github.com> Co-authored-by: Igor Rončević <ironcev@hotmail.com> | 1 年前 | |
Implement `__mem_rep_eq` intrinsic (#7697) ## Description This PR introduces a new `__mem_repr_eq` intrinsic for comparing memory representation of types, and removes the existing `__runtime_mem_id` and `__encoding_mem_id` intrinsics. We decided to introduce `__mem_repr_eq` to mitigate the following issues we had with existing intrinsics: - `mem_id`s were `u64` values computed using `DefaultHasher` whose results are not guaranteed to be stable across different runs of the same Sway compiler or being same on different target architectures. - even if we switched to a stable hasher, hashing to `u64` was not giving a strong no-collision guarantee. A hash collision between different, e.g. runtime and encoding representation, would in case of false positives result in wrong encoding or decoding. The `__mem_repr_eq` is defined as: ```sway __mem_repr_eq<T>(repr_a: str, repr_b: str) -> bool ``` It returns `true` if the memory representation `repr_a` of the type `T` is equal to its memory representation `repr_b`, assuming `T` has both memory representations. If `T` does not have any of the representations `repr_a` or `repr_b`, returns `false`. The valid values for `repr_a` and `repr_b` are `"runtime"`, `"encoding"`, and `"hashing"`: - `"runtime"` is how the type is represented inside the VM's memory. This is the Sway runtime memory representation (e.g., struct fields are aligned to word boundaries, arrays are packed, etc.). This memory representation is defined for every type. - `"encoding"` is the packed memory representation of a type, as defined by the canonical ABI encoding. Not all types have a canonical ABI encoding defined, e.g., dynamic types like `Vec` or `raw_slice`. In that case, `"encoding"` never compares equal to any other memory representation, __including to itself__. - `"hashing"` is the packed memory representation of a type, as defined by the canonical hashing introduced in #7695. Not all types have a canonical hashing defined, e.g., dynamic types like `Vec` or `raw_slice`. In that case, `"hashing"` never compares equal to any other memory representation, __including to itself__. To test if a type `T` has `"encoding"` or `"hashing"` memory representation defined, compare that representation to itself. E.g.: `let has_encoding_repr = __mem_repr_eq<T>("encoding", "encoding");` `repr_a` and `repr_b` must be compile-time constant `str`s, whose values are one of `"runtime"`, `"encoding"`, or `"hashing"`. The constant `str`s never end up in the bytecode. Additionally, the PR moves existing E2E intrinsics tests that were not in the `language/intrinsics` into `language/intrinsics`. ## Breaking Change The old `__runtime_mem_id` and `__encoding_mem_id` intrinsics are removed. The code that is using them must switch to the new `__mem_repr_eq`. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 1 个月前 | |
Optimize hashing by implementing `is_hash_trivial` (#7695) ## Description This PR extends the `Hash` trait with the `is_hash_trivial() -> bool` associated function. This function is supposed to return true if the hash byte representation of the type is the same as its runtime memory representation. By using `is_hash_trivial`, `std::hash::sha256` and `keccak256` module functions can skip expensive `Bytes` creation in the `Hasher` and directly hash the value's memory content. This optimization is similar to what `is_encode/decode_trivial()` associated functions are providing for ABI encoding/decoding. Similar to ABI encoding/decoding, implementation of hashing for a type is in full control of the Sway package that owns the type. In practice, and in `std` in particular, non-dynamic types are in general trivially hashable if their packed memory representation is the same as their runtime memory representation. Because of this, when implementing `Hash` for tuples, we use the `__runtime_mem_id` and the `__encoding_mem_id` intrinsics. While using the `__encoding_mem_id` might look like coupling encoding and hashing, it is not. What we are actually using is the notion of the "packed memory representation" that the `__encoding_mem_id` provides. Unfortunately, the intrinsic that provides this information was originally created for ABI encoding and not for a more generic usage, e.g., `__packed__mem_id`. To make the distinction clear and remove what looks like coupling of unrelated concepts, we will provide a follow-up PR that introduces intrinsics for use case based memory layouts: - `__mem_repr_id_runtime` - `__mem_repr_id_encoding` - `__mem_repr_id_hashing` Currently, all enums in the `std` hash their descriminators as `u8`. This makes them all being non-trivially hashable. For many of them, hashing the descriminator as `u64` would make them trivially hashable. This is however a breaking change that potentially affects the hashed data we already have deployed, e.g., `StorageMap` keys. In the future, we can provide this breaking change behind a feature flag. Enums that can benefit from being trivially hashed are marked in code with `TODO: (HASH-TRIVIAL-ENUMS)`. ## Checklist - [ ] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 1 个月前 | |
Optimize hashing by implementing `is_hash_trivial` (#7695) ## Description This PR extends the `Hash` trait with the `is_hash_trivial() -> bool` associated function. This function is supposed to return true if the hash byte representation of the type is the same as its runtime memory representation. By using `is_hash_trivial`, `std::hash::sha256` and `keccak256` module functions can skip expensive `Bytes` creation in the `Hasher` and directly hash the value's memory content. This optimization is similar to what `is_encode/decode_trivial()` associated functions are providing for ABI encoding/decoding. Similar to ABI encoding/decoding, implementation of hashing for a type is in full control of the Sway package that owns the type. In practice, and in `std` in particular, non-dynamic types are in general trivially hashable if their packed memory representation is the same as their runtime memory representation. Because of this, when implementing `Hash` for tuples, we use the `__runtime_mem_id` and the `__encoding_mem_id` intrinsics. While using the `__encoding_mem_id` might look like coupling encoding and hashing, it is not. What we are actually using is the notion of the "packed memory representation" that the `__encoding_mem_id` provides. Unfortunately, the intrinsic that provides this information was originally created for ABI encoding and not for a more generic usage, e.g., `__packed__mem_id`. To make the distinction clear and remove what looks like coupling of unrelated concepts, we will provide a follow-up PR that introduces intrinsics for use case based memory layouts: - `__mem_repr_id_runtime` - `__mem_repr_id_encoding` - `__mem_repr_id_hashing` Currently, all enums in the `std` hash their descriminators as `u8`. This makes them all being non-trivially hashable. For many of them, hashing the descriminator as `u64` would make them trivially hashable. This is however a breaking change that potentially affects the hashed data we already have deployed, e.g., `StorageMap` keys. In the future, we can provide this breaking change behind a feature flag. Enums that can benefit from being trivially hashed are marked in code with `TODO: (HASH-TRIVIAL-ENUMS)`. ## Checklist - [ ] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 1 个月前 | |
Run `forc fmt` on std-lib (#5404) ## Description Run `forc fmt` on the std-lib ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 2 年前 | |
Refactor and tidy up `std` tests for execution speed and discoverability (#7669) ## Description This PR represents a major cleanup and refactoring of tests covering `std` and closes #7617. The PR brings: - **consistency**: all `std` tests are now in `in_language_tests` and not scattered anymore on four different places (`sway-lib-std`, `stdlib`, `sdk-harness`, and `in_language_tests`). - **better discoverability**: test Sway files have the same name as their tested modules and appear in IDE file searches next to each other. - **better execution speed**: by removing redundant test projects and grouping existing `in_language_tests` projects per tested `std` modules we reduced the number of projects to compile and tests to run noticeably gaining on test execution speed. The above benefits are gained via: - porting E2E `stdlib` tests to `in_language_tests` and deleting redundant test projects. - porting `std` related SDK harness tests to `in_language_tests` and deleting redundant test projects. - moving 11 unit tests found in `sway-lib-std` to `in_language_tests` and forbidding writing unit tests in the `sway-lib-std`. `std` test **must** now be situated in in-language tests. The consequence of this decision is losing the possibility to test private members. Currently this is not a limitation. If it ever becomes, we can allow intentional testing of private members, e.g., via special test naming conventions or some other approach. - restructuring `in_language_tests` for better discoverability and test execution speed. The guidelines for writing in-language tests are fully documented in the accompanied README.md. The PR also acknowledges the control and flexibility we gained by introducing `run_in_language_tests.sh`. Although initially introduced as a workaround for #7613 the script proved to be more powerful and useful for development than using plain `forc test` of the workspace. Therefore, the PR removes TODOs related to switching back to `forc test`ing the whole workspace. The new structure of in-language tests reflects the `std` module structure. Having test modules being named the same as their tested `std` modules allows for quicker finding of both the module and its tests in IDEs. The new convention also removes the verbosity of the `_inline_tests` and `_contract_tests` prefixes. It turned out that this verbose additional information didn't bring a concrete benefit, while producing visual clutter. The faster test execution is noticeable. By grouping several in-language projects into a single one we have less `std` compilations. Number of initial in-language projects dropped from 72 to 47 causing parallel execution time of whole suite to drop from ~55s to ~40s. Similarly, we deleted the following number of other test projects that were redundant and already covered by in-language tests: 1. 35 out of 39 `stdlib` test projects from E2E tests, 1. 8 SDK harness test projects. - Closes #7617. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 2 个月前 | |
Attribute for checking of trivial encoding and decoding (#7575) ## Description Closes https://github.com/FuelLabs/sway/issues/7567. ## Checklist - [ ] I have linked to any relevant issues. - [ ] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [ ] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [ ] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [ ] I have requested a review from the relevant team or maintainers. | 3 个月前 | |
Better `Debug` tests and impls for primitives and std lib types (#7119) ## Description This PR is a continuation of https://github.com/FuelLabs/sway/pull/7015. It is fixing the number printing function, which was not working correctly for zero. It also fixes a problem when printing `enum` variants. To improve `__dbg`, we are also now printing the argument span. An improved test now tests if all relevant `strucs` and `enums` from the `std` library are debug and show how they are printed. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: kaya <kaya.gokalp@fuel.sh> | 1 年前 | |
Optimize hashing by implementing `is_hash_trivial` (#7695) ## Description This PR extends the `Hash` trait with the `is_hash_trivial() -> bool` associated function. This function is supposed to return true if the hash byte representation of the type is the same as its runtime memory representation. By using `is_hash_trivial`, `std::hash::sha256` and `keccak256` module functions can skip expensive `Bytes` creation in the `Hasher` and directly hash the value's memory content. This optimization is similar to what `is_encode/decode_trivial()` associated functions are providing for ABI encoding/decoding. Similar to ABI encoding/decoding, implementation of hashing for a type is in full control of the Sway package that owns the type. In practice, and in `std` in particular, non-dynamic types are in general trivially hashable if their packed memory representation is the same as their runtime memory representation. Because of this, when implementing `Hash` for tuples, we use the `__runtime_mem_id` and the `__encoding_mem_id` intrinsics. While using the `__encoding_mem_id` might look like coupling encoding and hashing, it is not. What we are actually using is the notion of the "packed memory representation" that the `__encoding_mem_id` provides. Unfortunately, the intrinsic that provides this information was originally created for ABI encoding and not for a more generic usage, e.g., `__packed__mem_id`. To make the distinction clear and remove what looks like coupling of unrelated concepts, we will provide a follow-up PR that introduces intrinsics for use case based memory layouts: - `__mem_repr_id_runtime` - `__mem_repr_id_encoding` - `__mem_repr_id_hashing` Currently, all enums in the `std` hash their descriminators as `u8`. This makes them all being non-trivially hashable. For many of them, hashing the descriminator as `u64` would make them trivially hashable. This is however a breaking change that potentially affects the hashed data we already have deployed, e.g., `StorageMap` keys. In the future, we can provide this breaking change behind a feature flag. Enums that can benefit from being trivially hashed are marked in code with `TODO: (HASH-TRIVIAL-ENUMS)`. ## Checklist - [ ] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 1 个月前 | |
Stabilize ABI errors (#7241) ## Description Stabilize the `error_type` feature. Fixes #6765 ## Checklist - [ ] I have linked to any relevant issues. - [ ] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [ ] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [ ] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [ ] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: Igor Rončević <ironcev@hotmail.com> | 1 年前 | |
Optimize type casting by using `__transmute` instead of `asm` blocks (#7675) ## Description This PR improves gas costs and bytecode sizes by consistently replacing `asm`-based conversions of _reference types_ in `std` with `__transmute`. Note that **copy-types are still converted using `asm` blocks**, because currently we didn't extend `__transmute` to handle copy-types without demoting transmuted values to stack and actually casting pointers. This gives a performance penalty when transmuting copy-types which we don't want to have. As expected, removing `asm` blocks unlocked existing IR performance optimizations and resulted in performance improvements given in the comment below. Note that we might think of temporarily forbidding using `__transmute` with copy-types until it is properly supported. But we have code in `ops.sw` where `__transmute` must be used to convert between copy-types, because the operator trait methods must be const-evaluable and if they use `asm` for conversion, they cannot be. Historically, making them const-evaluable was the reason for adding `__transmute` in the first place. Note that in the future, we plan to improve IR optimizations by letting them be aware of "safe `asm` blocks". Pure conversion blocks will be considered safe. That improvement would likely bring the same performance benefits as rolling out `__transmute`, but: - it will take some time before we get it implemented, - regardless, `__transmute` is the expected way to convert types and we should use it consistentlty across the codebase. Note that the PR changes snapshot files in the `sway-ir` tests. These changes are not related to this PR, but likely to the snapshots not being updated because of the `insta` checks being silent. For more info see https://github.com/FuelLabs/sway/pull/7666#pullrequestreview-4589675640. ## Checklist - [x] I have linked to any relevant issues. - [ ] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [ ] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 2 个月前 | |
Merge std and core libraries (#6729) ## Description Merges the two libraries. They were initially separate to separate the core logic and fuel vm specific functionality, but that separation is no longer maintained so having a merged library is better. Closes #6708 ## Checklist - [ ] I have linked to any relevant issues. - [ ] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [ ] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [ ] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [ ] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: Sophie <47993817+sdankel@users.noreply.github.com> Co-authored-by: Igor Rončević <ironcev@hotmail.com> | 1 年前 | |
Promote experimental features (#7016) ## Description This PR promotes the following experimental features to standard ones: - #6701 - #6883 - #6994 - #7006 Additionally, the PR stenghtens the migration infrastructure by checking some additional cases in selecting corresponding typed elements in desugared code which were not checked before. Closes #6701. Closes #6883. Closes #6994. Closes #7006. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 1 年前 | |
Refactor and tidy up `std` tests for execution speed and discoverability (#7669) ## Description This PR represents a major cleanup and refactoring of tests covering `std` and closes #7617. The PR brings: - **consistency**: all `std` tests are now in `in_language_tests` and not scattered anymore on four different places (`sway-lib-std`, `stdlib`, `sdk-harness`, and `in_language_tests`). - **better discoverability**: test Sway files have the same name as their tested modules and appear in IDE file searches next to each other. - **better execution speed**: by removing redundant test projects and grouping existing `in_language_tests` projects per tested `std` modules we reduced the number of projects to compile and tests to run noticeably gaining on test execution speed. The above benefits are gained via: - porting E2E `stdlib` tests to `in_language_tests` and deleting redundant test projects. - porting `std` related SDK harness tests to `in_language_tests` and deleting redundant test projects. - moving 11 unit tests found in `sway-lib-std` to `in_language_tests` and forbidding writing unit tests in the `sway-lib-std`. `std` test **must** now be situated in in-language tests. The consequence of this decision is losing the possibility to test private members. Currently this is not a limitation. If it ever becomes, we can allow intentional testing of private members, e.g., via special test naming conventions or some other approach. - restructuring `in_language_tests` for better discoverability and test execution speed. The guidelines for writing in-language tests are fully documented in the accompanied README.md. The PR also acknowledges the control and flexibility we gained by introducing `run_in_language_tests.sh`. Although initially introduced as a workaround for #7613 the script proved to be more powerful and useful for development than using plain `forc test` of the workspace. Therefore, the PR removes TODOs related to switching back to `forc test`ing the whole workspace. The new structure of in-language tests reflects the `std` module structure. Having test modules being named the same as their tested `std` modules allows for quicker finding of both the module and its tests in IDEs. The new convention also removes the verbosity of the `_inline_tests` and `_contract_tests` prefixes. It turned out that this verbose additional information didn't bring a concrete benefit, while producing visual clutter. The faster test execution is noticeable. By grouping several in-language projects into a single one we have less `std` compilations. Number of initial in-language projects dropped from 72 to 47 causing parallel execution time of whole suite to drop from ~55s to ~40s. Similarly, we deleted the following number of other test projects that were redundant and already covered by in-language tests: 1. 35 out of 39 `stdlib` test projects from E2E tests, 1. 8 SDK harness test projects. - Closes #7617. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 2 个月前 | |
Optimize existing and add missing `Hash` implementations (#7238) ## Description This PR: - optimizes the existing `std::hash::Hash` implementations in the `std`, for bytecode size and gas usage. The optimizations are based on eliminations of intensive memory allocations and memory copying. On a sample application, the **bytcode size reduction was ~10%**, and the **gas usage reduction >50%**. The detailed results are presented below. - fixes #7234 - adds `Hash` implementations for: - unit type `()`, - tuples of a single element `(T, )`, - empty arrays `[T; 0]`, - other `std` types that were missing `Hash` implementations, like, e.g.: `Duration`, `Time`, `U128`, `B512`, etc. Note that `Hash` implementations were not provided for various Error enums. ## Performance Optimizations To measure performance gains, a sample application was used, that: - hashed all built-in types individually, as well as tuples and array of those, and `Bytes` and `Vec`. - hashed all the above types within a same `Hasher`, simulating hashing of complex types like, e.g., structs. The bytcode size of the sample application got **reduced from 9560 to 8584 bytes (10.21% reduction)**. The overall gas usage for hashing types individually **got reduced from 35826 to 15562 (56.56% reduction)**. The overall gas usage for hashing types within a same `Hasher` **got reduced from 34951 to 14443 (58.67% reduction)**. The `in_language` tests for hashing, `hash_inline_tests`, also demonstrated a **significant reduction in gas usage, up to 57.82%**. A small regression is noticable when hashing empty types, e.g., unit. We expect that regression also to disappear once `const fn` is implemented, and local constants could be evaluated from generic functions. <details> <summary>Expand to see the detailed gas cost comparison for all `hash_inline_tests`</summary> | Test | Before | After | Percentage | |------|--------|-------|------------| | hash_address | 10070 | 6366 | 36.78% | | hash_array_10 | 33691 | 15867 | 52.90% | | hash_array_1 | 4870 | 3102 | 36.30% | | hash_array_2 | 8069 | 4517 | 44.02% | | hash_array_3 | 11219 | 5883 | 47.56% | | hash_array_4 | 14369 | 7249 | 49.55% | | hash_array_5 | 17519 | 8615 | 50.82% | | hash_array_6 | 20917 | 10229 | 51.10% | | hash_array_7 | 24109 | 11637 | 51.73% | | hash_array_8 | 27302 | 13046 | 52.22% | | hash_array_9 | 30494 | 14454 | 52.60% | | hash_array_empty | 773 | 777 | -0.52% | | hash_asset_id | 10070 | 6366 | 36.78% | | hash_b256 | 9604 | 5900 | 38.57% | | hash_b512 | 6028 | 4476 | 25.75% | | hash_bool | 3885 | 1993 | 48.70% | | hash_bytes | 8200 | 7112 | 13.27% | | hash_call_params | 11439 | 6019 | 47.38% | | hash_contract_id | 10070 | 6366 | 36.78% | | hash_duration | 4753 | 2985 | 37.20% | | hash_ed25519 | 18268 | 14780 | 19.09% | | hash_evm_address | 10098 | 6394 | 36.68% | | hash_fn_sha256_str_array | 1953 | 1167 | 40.25% | | hash_hasher_write_str | 2512 | 2013 | 19.86% | | hash_hasher_write_str_array | 2306 | 1807 | 21.64% | | hash_identity | 30526 | 14998 | 50.87% | | hash_input | 11766 | 5718 | 51.40% | | hash_message | 3003 | 3099 | -3.20% | | hash_option | 21373 | 9511 | 55.50% | | hash_output | 19649 | 9569 | 51.30% | | hash_point2d | 6861 | 4801 | 30.02% | | hash_public_key | 7372 | 7692 | -4.34% | | hash_result | 27083 | 11423 | 57.82% | | hash_scalar | 4159 | 3313 | 20.34% | | hash_secp256k1 | 18268 | 14780 | 19.09% | | hash_secp256r1 | 18268 | 14780 | 19.09% | | hash_signature | 31213 | 16936 | 45.74% | | hash_str | 6902 | 5417 | 21.52% | | hash_string | 5453 | 5252 | 3.69% | | hash_time | 4753 | 2985 | 37.20% | | hash_transaction | 23604 | 11508 | 51.25% | | hash_tuple_1 | 4834 | 3066 | 36.57% | | hash_tuple_2 | 7997 | 4445 | 44.42% | | hash_tuple_3 | 11147 | 5811 | 47.87% | | hash_tuple_4 | 14297 | 7177 | 49.80% | | hash_tuple_5 | 17447 | 8543 | 51.03% | | hash_u128 | 7943 | 4391 | 44.72% | | hash_u16 | 9384 | 5860 | 37.55% | | hash_u256 | 9600 | 5896 | 38.58% | | hash_u32 | 9384 | 5860 | 37.55% | | hash_u64 | 9372 | 5836 | 37.73% | | hash_u8 | 7740 | 3704 | 52.14% | | hash_unit | 771 | 775 | -0.52% | | hash_vec | 53077 | 33733 | 36.45% | </details> ## Breaking Changes Strictly seen, adding `Hash` implementations for `std` types like `Option<T>` represents a breaking change for those who eventually had their own implementations. However, if such implementations existed, after introducing strict trait coherence checks, they already became invalid, because neither the `Hash` trait nor the types `Hash` is implemented for are part of third party packages, but contained within the `std`. Thus, we can have a breaking change only if someone migrates from an older version that does not have trait coherence in place. But in that case, the trait coherence itself will already report breaking change errors. Because `Hash` implementations for `std` types must and should have already been provided within the `std`, we can treat adding those implementations as a bug fix. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 1 年前 | |
Optimize hashing by implementing `is_hash_trivial` (#7695) ## Description This PR extends the `Hash` trait with the `is_hash_trivial() -> bool` associated function. This function is supposed to return true if the hash byte representation of the type is the same as its runtime memory representation. By using `is_hash_trivial`, `std::hash::sha256` and `keccak256` module functions can skip expensive `Bytes` creation in the `Hasher` and directly hash the value's memory content. This optimization is similar to what `is_encode/decode_trivial()` associated functions are providing for ABI encoding/decoding. Similar to ABI encoding/decoding, implementation of hashing for a type is in full control of the Sway package that owns the type. In practice, and in `std` in particular, non-dynamic types are in general trivially hashable if their packed memory representation is the same as their runtime memory representation. Because of this, when implementing `Hash` for tuples, we use the `__runtime_mem_id` and the `__encoding_mem_id` intrinsics. While using the `__encoding_mem_id` might look like coupling encoding and hashing, it is not. What we are actually using is the notion of the "packed memory representation" that the `__encoding_mem_id` provides. Unfortunately, the intrinsic that provides this information was originally created for ABI encoding and not for a more generic usage, e.g., `__packed__mem_id`. To make the distinction clear and remove what looks like coupling of unrelated concepts, we will provide a follow-up PR that introduces intrinsics for use case based memory layouts: - `__mem_repr_id_runtime` - `__mem_repr_id_encoding` - `__mem_repr_id_hashing` Currently, all enums in the `std` hash their descriminators as `u8`. This makes them all being non-trivially hashable. For many of them, hashing the descriminator as `u64` would make them trivially hashable. This is however a breaking change that potentially affects the hashed data we already have deployed, e.g., `StorageMap` keys. In the future, we can provide this breaking change behind a feature flag. Enums that can benefit from being trivially hashed are marked in code with `TODO: (HASH-TRIVIAL-ENUMS)`. ## Checklist - [ ] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 1 个月前 | |
Implement dynamic storage for `storage` declaration and `std` (#7598) ## Description This PR is a part of #7560 implementation and implements: - `storage` fields access compilation for dynamic storage. - dynamic storage for all the types and functions in the `std::storage` module, except the `StorageVec`. In the `storage_api`, support for dynamic storage is added as the extension to the existing API based on quads. The reason is that we will need to support quad-based storage for backwards compatibility, for contracts that cannot migrate all the data, but still want to use, in parallel, the benefits of dynamic storage. The existing API is marked as deprecated in favor of the new API in which the function suffix, either `quads` or `slot(s)`, clearly indicates what kind of storage access the function performs. Additionally, the existing `clear` API that returned boolean information about slot occupancy is split into two distinctive APIs: `clear` that only clears and doesn't return occupancy information, and `clear_existed` that returns boolean information about slot occupancy. Introducing two variants for clearing is done for performance reasons. Returning the occupancy information in dynamic storage case requires more gas, and in many of the cases that information is not needed. Having two distinctive function allows developers to opt-in for the cost. Additionally, the PR: - fixes bug in `ir_generation::purity::check_function_purity` where `StateUpdateSlot` IR instruction and `supd/supi` opcodes were still be considered as reading and writing operations instead of only writing. - closes #6829 by properly documenting the semantic of zero-sized types in relation to storage. Planned next steps are: - Adding additional comprehensive test coverage. Some of the existing tests are adapted to test the new API and dynamic storage in this PR. Considering the impact of the change, unlike for other experimental feature, we want dynamic storage test to be included in all the tests that are currently testing storage. - Further optimizing writing to storage by supporting `__state_store_slot` in the `StorageKey`. `__state_store_slot` intrinsic is used in storage types, e.g. when storing slices or inserting into a `StorageMap`, but currently not in the `StorageKey` in general. There, `__state_update_slot` is always used. Supporting `__state_store_slot` in the `StorageKey` requires introduction of an additional abstraction that will allow us to express that a `StorageKey` points to a value that is guaranteed to be the only value in the slot. - Enabling SDK tests for `StorageVec`s that are temporarily disabled. This will be done when dynamic storage version of `StorageVec` is implemented. - Emitting `<project>-storage_slots.json` for dynamic storage and properly consuming them in the SDK. Until then, some of the tests are disabled and marked as `TODO: (INIT-STORAGE)`. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 4 个月前 | |
Add u256 conversions (#5767) ## Description Adds conversion methods from u8, u16, u32, u64, b256 to u256, and u256 to b256 Closes #4800 ## Checklist - [ ] I have linked to any relevant issues. - [ ] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [ ] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [ ] I have requested a review from the relevant team or maintainers. | 2 年前 | |
Promote `const_generics` to a standard feature (#7592) ## Description This PR promotes `const_generics` to a standard feature not anymore behind a feature flag. #7512 made `const_generic` experimental feature enabled by default, but still kept it as experimental, with the decision to remove the feature flag as a part of the next breaking release 0.71.0. - Closes #6860. ## Breaking change The `const_generic` experimental feature is removed. If a compilation used `--experimental/no-experimental const_generic` or `#[cfg(experimental_const_generics)]` it will fail now. The solution is to simply remove all the usages of the feature flag. ## Checklist - [x] I have linked to any relevant issues. - [ ] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 4 个月前 | |
Fix forc-fmt empty if-body + else collapsing onto one line (#7628) ## Description Fixes #7625 `forc-fmt` collapses empty if-body + else onto a single line: ```sway // Before (wrong): if __size_of::<T>() == 0 { } else if __is_reference_type::<T>() { // After (correct): if __size_of::<T>() == 0 { } else if __is_reference_type::<T>() { ``` **Root cause**: In `format_then_block`, when the then-block is empty and has an else clause, `block_unindent()` was called but no newline was written — so the closing `}` from `format_else_opt` ended up on the same line. **Fix**: Write a newline after the empty body when an else clause exists, and skip `block_unindent` since `close_curly_brace` in `format_else_opt` already handles unindentation. Guarded with `LineStyle::Inline` to avoid injecting newlines during width measurement probes. ## Checklist - [x] I have linked to any relevant issues. - [ ] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [ ] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: Igor Rončević <ironcev@hotmail.com> | 2 个月前 | |
Optimize dynamic `std` types (#7683) ## Description This PR optimizes several aspects of dynamic `std` types: - Hashing of string arrays, by properly accommodating initial `Hasher` buffer capacity for the string length prefix. - `Bytes::clear`, by reusing the already allocated buffer, the same way `Vec` is doing it. - Removing expensive double-allocation and memory-copy in the `Bytes::append_raw_slice`. - Adding `from_moved_...` constructors to types that own their buffers, for supporting taking ownership of the content without copying it. - Adding `from_ascii_str_array` constructor to `String` to create a string directly from string array without a need to first copy it to `str` via `from_str_array`. Additionally, the PR: - fixes invalid doc-comment examples on `String` methods, that were using a non-existing `String::push` method. ## Performance Improvements Performance improvements are given in the comment below. Although the PR obviously only removes runtime overhead, we still have some smaller numbers of regressions. Regressions are analyzed and have the same root-cause, the one we already encountered before. The leaner `Bytes::append_raw_slice` now leads to more inlining in hashing code like `sha256` that brings `CastPtr` to caller scope suppressing potential optimizations in the caller. The regressions on real-life o2 code are small and in contract methods that are not frequently used while improvements are bigger and in often use contract methods. Improving this particular issue will be done in #7492. Also, analysis of regressions in `sha256` and `keccak256` calls revealed another potentially high future performance improvement. E.g., hashing a `b256` using `s256` opcode directly costs ~60 gas units, while using `sha256` function will cost ~250 gas units. Similar values for are for `u8`, .., `u256` and even worse for larger structured types. One way to improve our hashing abstractions is to introduce a concept of "trivially hashable types", similar to trivially encodeable and decodeable. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 1 个月前 | |
ci: fixing typos programmatically (#5975) ## Description Adds a CI check for typos and fixes all* typos in code, comments, and docs. *found by [typos-cli](https://github.com/crate-ci/typos) `typos` doesn't catch everything, but it seems to work better than codespell and cargo-spellcheck (fewer false positives). ## Checklist - [ ] I have linked to any relevant issues. - [ ] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [ ] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [ ] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [ ] I have requested a review from the relevant team or maintainers. | 2 年前 | |
Optimize existing and add missing `Hash` implementations (#7238) ## Description This PR: - optimizes the existing `std::hash::Hash` implementations in the `std`, for bytecode size and gas usage. The optimizations are based on eliminations of intensive memory allocations and memory copying. On a sample application, the **bytcode size reduction was ~10%**, and the **gas usage reduction >50%**. The detailed results are presented below. - fixes #7234 - adds `Hash` implementations for: - unit type `()`, - tuples of a single element `(T, )`, - empty arrays `[T; 0]`, - other `std` types that were missing `Hash` implementations, like, e.g.: `Duration`, `Time`, `U128`, `B512`, etc. Note that `Hash` implementations were not provided for various Error enums. ## Performance Optimizations To measure performance gains, a sample application was used, that: - hashed all built-in types individually, as well as tuples and array of those, and `Bytes` and `Vec`. - hashed all the above types within a same `Hasher`, simulating hashing of complex types like, e.g., structs. The bytcode size of the sample application got **reduced from 9560 to 8584 bytes (10.21% reduction)**. The overall gas usage for hashing types individually **got reduced from 35826 to 15562 (56.56% reduction)**. The overall gas usage for hashing types within a same `Hasher` **got reduced from 34951 to 14443 (58.67% reduction)**. The `in_language` tests for hashing, `hash_inline_tests`, also demonstrated a **significant reduction in gas usage, up to 57.82%**. A small regression is noticable when hashing empty types, e.g., unit. We expect that regression also to disappear once `const fn` is implemented, and local constants could be evaluated from generic functions. <details> <summary>Expand to see the detailed gas cost comparison for all `hash_inline_tests`</summary> | Test | Before | After | Percentage | |------|--------|-------|------------| | hash_address | 10070 | 6366 | 36.78% | | hash_array_10 | 33691 | 15867 | 52.90% | | hash_array_1 | 4870 | 3102 | 36.30% | | hash_array_2 | 8069 | 4517 | 44.02% | | hash_array_3 | 11219 | 5883 | 47.56% | | hash_array_4 | 14369 | 7249 | 49.55% | | hash_array_5 | 17519 | 8615 | 50.82% | | hash_array_6 | 20917 | 10229 | 51.10% | | hash_array_7 | 24109 | 11637 | 51.73% | | hash_array_8 | 27302 | 13046 | 52.22% | | hash_array_9 | 30494 | 14454 | 52.60% | | hash_array_empty | 773 | 777 | -0.52% | | hash_asset_id | 10070 | 6366 | 36.78% | | hash_b256 | 9604 | 5900 | 38.57% | | hash_b512 | 6028 | 4476 | 25.75% | | hash_bool | 3885 | 1993 | 48.70% | | hash_bytes | 8200 | 7112 | 13.27% | | hash_call_params | 11439 | 6019 | 47.38% | | hash_contract_id | 10070 | 6366 | 36.78% | | hash_duration | 4753 | 2985 | 37.20% | | hash_ed25519 | 18268 | 14780 | 19.09% | | hash_evm_address | 10098 | 6394 | 36.68% | | hash_fn_sha256_str_array | 1953 | 1167 | 40.25% | | hash_hasher_write_str | 2512 | 2013 | 19.86% | | hash_hasher_write_str_array | 2306 | 1807 | 21.64% | | hash_identity | 30526 | 14998 | 50.87% | | hash_input | 11766 | 5718 | 51.40% | | hash_message | 3003 | 3099 | -3.20% | | hash_option | 21373 | 9511 | 55.50% | | hash_output | 19649 | 9569 | 51.30% | | hash_point2d | 6861 | 4801 | 30.02% | | hash_public_key | 7372 | 7692 | -4.34% | | hash_result | 27083 | 11423 | 57.82% | | hash_scalar | 4159 | 3313 | 20.34% | | hash_secp256k1 | 18268 | 14780 | 19.09% | | hash_secp256r1 | 18268 | 14780 | 19.09% | | hash_signature | 31213 | 16936 | 45.74% | | hash_str | 6902 | 5417 | 21.52% | | hash_string | 5453 | 5252 | 3.69% | | hash_time | 4753 | 2985 | 37.20% | | hash_transaction | 23604 | 11508 | 51.25% | | hash_tuple_1 | 4834 | 3066 | 36.57% | | hash_tuple_2 | 7997 | 4445 | 44.42% | | hash_tuple_3 | 11147 | 5811 | 47.87% | | hash_tuple_4 | 14297 | 7177 | 49.80% | | hash_tuple_5 | 17447 | 8543 | 51.03% | | hash_u128 | 7943 | 4391 | 44.72% | | hash_u16 | 9384 | 5860 | 37.55% | | hash_u256 | 9600 | 5896 | 38.58% | | hash_u32 | 9384 | 5860 | 37.55% | | hash_u64 | 9372 | 5836 | 37.73% | | hash_u8 | 7740 | 3704 | 52.14% | | hash_unit | 771 | 775 | -0.52% | | hash_vec | 53077 | 33733 | 36.45% | </details> ## Breaking Changes Strictly seen, adding `Hash` implementations for `std` types like `Option<T>` represents a breaking change for those who eventually had their own implementations. However, if such implementations existed, after introducing strict trait coherence checks, they already became invalid, because neither the `Hash` trait nor the types `Hash` is implemented for are part of third party packages, but contained within the `std`. Thus, we can have a breaking change only if someone migrates from an older version that does not have trait coherence in place. But in that case, the trait coherence itself will already report breaking change errors. Because `Hash` implementations for `std` types must and should have already been provided within the `std`, we can treat adding those implementations as a bug fix. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 1 年前 | |
Merge std and core libraries (#6729) ## Description Merges the two libraries. They were initially separate to separate the core logic and fuel vm specific functionality, but that separation is no longer maintained so having a merged library is better. Closes #6708 ## Checklist - [ ] I have linked to any relevant issues. - [ ] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [ ] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [ ] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [ ] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: Sophie <47993817+sdankel@users.noreply.github.com> Co-authored-by: Igor Rončević <ironcev@hotmail.com> | 1 年前 | |
Optimize type casting by using `__transmute` instead of `asm` blocks (#7675) ## Description This PR improves gas costs and bytecode sizes by consistently replacing `asm`-based conversions of _reference types_ in `std` with `__transmute`. Note that **copy-types are still converted using `asm` blocks**, because currently we didn't extend `__transmute` to handle copy-types without demoting transmuted values to stack and actually casting pointers. This gives a performance penalty when transmuting copy-types which we don't want to have. As expected, removing `asm` blocks unlocked existing IR performance optimizations and resulted in performance improvements given in the comment below. Note that we might think of temporarily forbidding using `__transmute` with copy-types until it is properly supported. But we have code in `ops.sw` where `__transmute` must be used to convert between copy-types, because the operator trait methods must be const-evaluable and if they use `asm` for conversion, they cannot be. Historically, making them const-evaluable was the reason for adding `__transmute` in the first place. Note that in the future, we plan to improve IR optimizations by letting them be aware of "safe `asm` blocks". Pure conversion blocks will be considered safe. That improvement would likely bring the same performance benefits as rolling out `__transmute`, but: - it will take some time before we get it implemented, - regardless, `__transmute` is the expected way to convert types and we should use it consistentlty across the codebase. Note that the PR changes snapshot files in the `sway-ir` tests. These changes are not related to this PR, but likely to the snapshots not being updated because of the `insta` checks being silent. For more info see https://github.com/FuelLabs/sway/pull/7666#pullrequestreview-4589675640. ## Checklist - [x] I have linked to any relevant issues. - [ ] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [ ] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 2 个月前 | |
Implement `StorageString` to std-lib (#4725) ## Description The `String` type has recently been move/introduced to the std-lib. This is a heap type and does not allow for any storage. The `StorageString` type allows for storage. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: bitzoic <bitzoic.eth@gmail.com> | 3 年前 | |
Optimize type casting by using `__transmute` instead of `asm` blocks (#7675) ## Description This PR improves gas costs and bytecode sizes by consistently replacing `asm`-based conversions of _reference types_ in `std` with `__transmute`. Note that **copy-types are still converted using `asm` blocks**, because currently we didn't extend `__transmute` to handle copy-types without demoting transmuted values to stack and actually casting pointers. This gives a performance penalty when transmuting copy-types which we don't want to have. As expected, removing `asm` blocks unlocked existing IR performance optimizations and resulted in performance improvements given in the comment below. Note that we might think of temporarily forbidding using `__transmute` with copy-types until it is properly supported. But we have code in `ops.sw` where `__transmute` must be used to convert between copy-types, because the operator trait methods must be const-evaluable and if they use `asm` for conversion, they cannot be. Historically, making them const-evaluable was the reason for adding `__transmute` in the first place. Note that in the future, we plan to improve IR optimizations by letting them be aware of "safe `asm` blocks". Pure conversion blocks will be considered safe. That improvement would likely bring the same performance benefits as rolling out `__transmute`, but: - it will take some time before we get it implemented, - regardless, `__transmute` is the expected way to convert types and we should use it consistentlty across the codebase. Note that the PR changes snapshot files in the `sway-ir` tests. These changes are not related to this PR, but likely to the snapshots not being updated because of the `insta` checks being silent. For more info see https://github.com/FuelLabs/sway/pull/7666#pullrequestreview-4589675640. ## Checklist - [x] I have linked to any relevant issues. - [ ] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [ ] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 2 个月前 | |
Optimize hashing by implementing `is_hash_trivial` (#7695) ## Description This PR extends the `Hash` trait with the `is_hash_trivial() -> bool` associated function. This function is supposed to return true if the hash byte representation of the type is the same as its runtime memory representation. By using `is_hash_trivial`, `std::hash::sha256` and `keccak256` module functions can skip expensive `Bytes` creation in the `Hasher` and directly hash the value's memory content. This optimization is similar to what `is_encode/decode_trivial()` associated functions are providing for ABI encoding/decoding. Similar to ABI encoding/decoding, implementation of hashing for a type is in full control of the Sway package that owns the type. In practice, and in `std` in particular, non-dynamic types are in general trivially hashable if their packed memory representation is the same as their runtime memory representation. Because of this, when implementing `Hash` for tuples, we use the `__runtime_mem_id` and the `__encoding_mem_id` intrinsics. While using the `__encoding_mem_id` might look like coupling encoding and hashing, it is not. What we are actually using is the notion of the "packed memory representation" that the `__encoding_mem_id` provides. Unfortunately, the intrinsic that provides this information was originally created for ABI encoding and not for a more generic usage, e.g., `__packed__mem_id`. To make the distinction clear and remove what looks like coupling of unrelated concepts, we will provide a follow-up PR that introduces intrinsics for use case based memory layouts: - `__mem_repr_id_runtime` - `__mem_repr_id_encoding` - `__mem_repr_id_hashing` Currently, all enums in the `std` hash their descriminators as `u8`. This makes them all being non-trivially hashable. For many of them, hashing the descriminator as `u64` would make them trivially hashable. This is however a breaking change that potentially affects the hashed data we already have deployed, e.g., `StorageMap` keys. In the future, we can provide this breaking change behind a feature flag. Enums that can benefit from being trivially hashed are marked in code with `TODO: (HASH-TRIVIAL-ENUMS)`. ## Checklist - [ ] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 1 个月前 | |
Optimize hashing by implementing `is_hash_trivial` (#7695) ## Description This PR extends the `Hash` trait with the `is_hash_trivial() -> bool` associated function. This function is supposed to return true if the hash byte representation of the type is the same as its runtime memory representation. By using `is_hash_trivial`, `std::hash::sha256` and `keccak256` module functions can skip expensive `Bytes` creation in the `Hasher` and directly hash the value's memory content. This optimization is similar to what `is_encode/decode_trivial()` associated functions are providing for ABI encoding/decoding. Similar to ABI encoding/decoding, implementation of hashing for a type is in full control of the Sway package that owns the type. In practice, and in `std` in particular, non-dynamic types are in general trivially hashable if their packed memory representation is the same as their runtime memory representation. Because of this, when implementing `Hash` for tuples, we use the `__runtime_mem_id` and the `__encoding_mem_id` intrinsics. While using the `__encoding_mem_id` might look like coupling encoding and hashing, it is not. What we are actually using is the notion of the "packed memory representation" that the `__encoding_mem_id` provides. Unfortunately, the intrinsic that provides this information was originally created for ABI encoding and not for a more generic usage, e.g., `__packed__mem_id`. To make the distinction clear and remove what looks like coupling of unrelated concepts, we will provide a follow-up PR that introduces intrinsics for use case based memory layouts: - `__mem_repr_id_runtime` - `__mem_repr_id_encoding` - `__mem_repr_id_hashing` Currently, all enums in the `std` hash their descriminators as `u8`. This makes them all being non-trivially hashable. For many of them, hashing the descriminator as `u64` would make them trivially hashable. This is however a breaking change that potentially affects the hashed data we already have deployed, e.g., `StorageMap` keys. In the future, we can provide this breaking change behind a feature flag. Enums that can benefit from being trivially hashed are marked in code with `TODO: (HASH-TRIVIAL-ENUMS)`. ## Checklist - [ ] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 1 个月前 | |
Optimize hashing by implementing `is_hash_trivial` (#7695) ## Description This PR extends the `Hash` trait with the `is_hash_trivial() -> bool` associated function. This function is supposed to return true if the hash byte representation of the type is the same as its runtime memory representation. By using `is_hash_trivial`, `std::hash::sha256` and `keccak256` module functions can skip expensive `Bytes` creation in the `Hasher` and directly hash the value's memory content. This optimization is similar to what `is_encode/decode_trivial()` associated functions are providing for ABI encoding/decoding. Similar to ABI encoding/decoding, implementation of hashing for a type is in full control of the Sway package that owns the type. In practice, and in `std` in particular, non-dynamic types are in general trivially hashable if their packed memory representation is the same as their runtime memory representation. Because of this, when implementing `Hash` for tuples, we use the `__runtime_mem_id` and the `__encoding_mem_id` intrinsics. While using the `__encoding_mem_id` might look like coupling encoding and hashing, it is not. What we are actually using is the notion of the "packed memory representation" that the `__encoding_mem_id` provides. Unfortunately, the intrinsic that provides this information was originally created for ABI encoding and not for a more generic usage, e.g., `__packed__mem_id`. To make the distinction clear and remove what looks like coupling of unrelated concepts, we will provide a follow-up PR that introduces intrinsics for use case based memory layouts: - `__mem_repr_id_runtime` - `__mem_repr_id_encoding` - `__mem_repr_id_hashing` Currently, all enums in the `std` hash their descriminators as `u8`. This makes them all being non-trivially hashable. For many of them, hashing the descriminator as `u64` would make them trivially hashable. This is however a breaking change that potentially affects the hashed data we already have deployed, e.g., `StorageMap` keys. In the future, we can provide this breaking change behind a feature flag. Enums that can benefit from being trivially hashed are marked in code with `TODO: (HASH-TRIVIAL-ENUMS)`. ## Checklist - [ ] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 1 个月前 | |
Optimize hashing by implementing `is_hash_trivial` (#7695) ## Description This PR extends the `Hash` trait with the `is_hash_trivial() -> bool` associated function. This function is supposed to return true if the hash byte representation of the type is the same as its runtime memory representation. By using `is_hash_trivial`, `std::hash::sha256` and `keccak256` module functions can skip expensive `Bytes` creation in the `Hasher` and directly hash the value's memory content. This optimization is similar to what `is_encode/decode_trivial()` associated functions are providing for ABI encoding/decoding. Similar to ABI encoding/decoding, implementation of hashing for a type is in full control of the Sway package that owns the type. In practice, and in `std` in particular, non-dynamic types are in general trivially hashable if their packed memory representation is the same as their runtime memory representation. Because of this, when implementing `Hash` for tuples, we use the `__runtime_mem_id` and the `__encoding_mem_id` intrinsics. While using the `__encoding_mem_id` might look like coupling encoding and hashing, it is not. What we are actually using is the notion of the "packed memory representation" that the `__encoding_mem_id` provides. Unfortunately, the intrinsic that provides this information was originally created for ABI encoding and not for a more generic usage, e.g., `__packed__mem_id`. To make the distinction clear and remove what looks like coupling of unrelated concepts, we will provide a follow-up PR that introduces intrinsics for use case based memory layouts: - `__mem_repr_id_runtime` - `__mem_repr_id_encoding` - `__mem_repr_id_hashing` Currently, all enums in the `std` hash their descriminators as `u8`. This makes them all being non-trivially hashable. For many of them, hashing the descriminator as `u64` would make them trivially hashable. This is however a breaking change that potentially affects the hashed data we already have deployed, e.g., `StorageMap` keys. In the future, we can provide this breaking change behind a feature flag. Enums that can benefit from being trivially hashed are marked in code with `TODO: (HASH-TRIVIAL-ENUMS)`. ## Checklist - [ ] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 1 个月前 | |
Optimize dynamic `std` types (#7683) ## Description This PR optimizes several aspects of dynamic `std` types: - Hashing of string arrays, by properly accommodating initial `Hasher` buffer capacity for the string length prefix. - `Bytes::clear`, by reusing the already allocated buffer, the same way `Vec` is doing it. - Removing expensive double-allocation and memory-copy in the `Bytes::append_raw_slice`. - Adding `from_moved_...` constructors to types that own their buffers, for supporting taking ownership of the content without copying it. - Adding `from_ascii_str_array` constructor to `String` to create a string directly from string array without a need to first copy it to `str` via `from_str_array`. Additionally, the PR: - fixes invalid doc-comment examples on `String` methods, that were using a non-existing `String::push` method. ## Performance Improvements Performance improvements are given in the comment below. Although the PR obviously only removes runtime overhead, we still have some smaller numbers of regressions. Regressions are analyzed and have the same root-cause, the one we already encountered before. The leaner `Bytes::append_raw_slice` now leads to more inlining in hashing code like `sha256` that brings `CastPtr` to caller scope suppressing potential optimizations in the caller. The regressions on real-life o2 code are small and in contract methods that are not frequently used while improvements are bigger and in often use contract methods. Improving this particular issue will be done in #7492. Also, analysis of regressions in `sha256` and `keccak256` calls revealed another potentially high future performance improvement. E.g., hashing a `b256` using `s256` opcode directly costs ~60 gas units, while using `sha256` function will cost ~250 gas units. Similar values for are for `u8`, .., `u256` and even worse for larger structured types. One way to improve our hashing abstractions is to introduce a concept of "trivially hashable types", similar to trivially encodeable and decodeable. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 1 个月前 | |
Implement module privacy rules (#4474) ## Description This change mainly adds checks to enforce the new module privacy rules and supporting changes for it. Changes include updating std and core to use public modules, updating the parser to allow the use of the `pub mod` syntax and adding an error type for private modules. This change is implemented behind a `--experimental-private-modules` experimental flag and not enabled by default. It implements part of https://github.com/FuelLabs/sway/issues/4446, the `pub use` syntax is yet to be implemented. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. Co-authored-by: Joshua Batty <joshpbatty@gmail.com> | 3 年前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 2 个月前 | ||
| 1 个月前 | ||
| 2 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 2 年前 | ||
| 9 个月前 | ||
| 2 年前 | ||
| 1 年前 | ||
| 2 年前 | ||
| 1 个月前 | ||
| 1 年前 | ||
| 1 个月前 | ||
| 1 年前 | ||
| 1 个月前 | ||
| 2 年前 | ||
| 1 年前 | ||
| 2 个月前 | ||
| 1 个月前 | ||
| 1 年前 | ||
| 2 年前 | ||
| 1 个月前 | ||
| 2 年前 | ||
| 1 年前 | ||
| 2 个月前 | ||
| 1 年前 | ||
| 3 个月前 | ||
| 2 年前 | ||
| 2 年前 | ||
| 1 年前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 2 年前 | ||
| 2 个月前 | ||
| 3 个月前 | ||
| 1 年前 | ||
| 1 个月前 | ||
| 1 年前 | ||
| 2 个月前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 2 个月前 | ||
| 1 年前 | ||
| 1 个月前 | ||
| 4 个月前 | ||
| 2 年前 | ||
| 4 个月前 | ||
| 2 个月前 | ||
| 1 个月前 | ||
| 2 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 2 个月前 | ||
| 3 年前 | ||
| 2 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 3 年前 |