Skip to content

Optimize tx module for bytecode size and gas usage #7087

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 14, 2025

Conversation

ironcev
Copy link
Member

@ironcev ironcev commented Apr 14, 2025

Description

This PR optimizes functions in the tx module for bytecode size and gas usage. E.g., the bytecode size of the following script that calls all of the optimized functions got reduced from 1792 bytes to 648 bytes:

fn main() {
    let _ = std::tx::tx_script_length();
    let _ = std::tx::tx_script_data_length();
    let _ = std::tx::tx_script_data::<u64>();
    let _ = std::tx::tx_script_bytecode::<u64>();
    let _ = std::tx::tx_script_bytecode_hash();
    let _ = std::tx::tx_witnesses_count();
    let _ = std::tx::tx_witness_data::<u64>(0);
}

The optimization:

  • mostly removes the duplicated checks for tx_type() and where necessary, replaces calls to tx_type() to a single if.
  • removes the private helper function tx_script_start_pointer. The function was re-checking the tx_type() to be a script, although always being called only if the tx_type was already checked for being a script. Additionally, it was wrapping the result in Option requiring an additional unnecessary indirection.
  • removes the private helper function tx_script_data_start_pointer for similar reasons.
  • rewrites tx_witness_data by removing unnecessary length calculation and duplicated code.
  • simplifies match expressions by replacing duplicated match arms with a single arm.

The PR introduces a slight change in the semantics of functions like, e.g., tx_script_length that return Option. Before, if the tx_type was Mint they would panic instead of returning None. Now they return None. The new behavior actually looks like the proper one to me. A function returning Option shouldn't panic.

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.
  • I have requested a review from the relevant team or maintainers.

@ironcev ironcev self-assigned this Apr 14, 2025
@ironcev ironcev added the lib: std Standard library label Apr 14, 2025
@ironcev ironcev marked this pull request as ready for review April 14, 2025 13:17
@ironcev ironcev requested review from a team as code owners April 14, 2025 13:17
@ironcev ironcev enabled auto-merge (squash) April 14, 2025 13:21
@ironcev ironcev requested a review from bitzoic April 14, 2025 13:21
@ironcev ironcev merged commit 8c132f1 into master Apr 14, 2025
39 checks passed
@ironcev ironcev deleted the ironcev/optimize-tx-module branch April 14, 2025 14:54
ironcev added a commit that referenced this pull request Apr 15, 2025
…ge (#7092)

## Description

This PR optimizes the `std::inputs` and `std::outputs` modules for
bytcode size and gas cost using the same optimization techinques like in
#7087.

The optimized public functions are listed in the below code snippet.
**The bytcode size of that code got reduced from 5688 bytes to 2544
bytes.**

```sway
fn main() {
    let _ = std::tx::tx_witnesses_count();

    let _ = std::inputs::input_count();
    let _ = std::inputs::input_amount(0);
    let _ = std::inputs::input_coin_owner(0);
    let _ = std::inputs::input_predicate_data::<u64>(0);
    let _ = std::inputs::input_asset_id(0);
    let _ = std::inputs::input_witness_index(0);
    let _ = std::inputs::input_predicate_length(0);
    let _ = std::inputs::input_predicate(0);
    let _ = std::inputs::input_predicate_data_length(0);
    let _ = std::inputs::input_message_sender(0);
    let _ = std::inputs::input_message_recipient(0);
    let _ = std::inputs::input_message_nonce(0);
    let _ = std::inputs::input_message_data_length(0);
    let _ = std::inputs::input_message_data(0, 0);

    let _ = std::outputs::output_count();
    let _ = std::outputs::output_amount(0);
    let _ = std::outputs::output_asset_id(0);
    let _ = std::outputs::output_asset_to(0);
}
```

Additionally, the PR adds a new function
`std::outputs::output_asset_id_and_to` to efficiently retrieve the id
and the receiver of the output asset in a single call. Calling this
function is more performant that calling `output_asset_id` and
`output_asset_to` separately.

## 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.
ironcev added a commit that referenced this pull request Apr 19, 2025
## Description

This PR optimizes the `std::auth` module for bytecode size and gas cost
by using optimization techniques similar to those used in #7087 and
#7092.

The optimized public functions are listed in the below code snippet.
**The bytecode size of that code got reduced from 2480 bytes to 1200
bytes.**

```sway
fn main() {
    let _ = std::auth::predicate_address();
    let _ = std::auth::caller_addresses();
    let _ = std::auth::caller_address();
}
```

## 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)
- [ ] 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.
ironcev added a commit that referenced this pull request May 7, 2025
## Description

This PR optimizes the `std::crypto` module for bytecode size and gas
cost by using optimization techniques similar to those used in #7087,
#7092, and #7096.

The optimized public functions are listed in the below code snippet.
**The bytecode size of that code got reduced from 46104 bytes to 44288
bytes.**

We actually expect a bigger gain here. At one point in the optimization,
the bytecode size went down to 33896 bytes. Bouncing back to ~44600 is
related to the issue described in #7150. Once that issue is solved, we
expect even smaller bytcode sizes.

```sway
script;

use std::crypto::ed25519::*;
use std::crypto::point2d::*;
use std::crypto::public_key::*;
use std::crypto::scalar::*;
use std::crypto::secp256k1::*;
use std::crypto::secp256r1::*;
use std::crypto::signature::*;

use std::vm::evm::evm_address::EvmAddress;

fn main() {
    let ed25519 = std::crypto::ed25519::Ed25519::new();
    let _ = ed25519 == ed25519;

    let point2d = std::crypto::point2d::Point2D::new();
    let _ = point2d == point2d;

    let public_key = std::crypto::public_key::PublicKey::new();
    let _ = public_key == public_key;

    let _ = public_key.is_zero();

    let scalar = std::crypto::scalar::Scalar::new();
    let _ = scalar == scalar;

    let message = std::crypto::message::Message::new();

    let secp256k1 = std::crypto::secp256k1::Secp256k1::new();
    let _ = secp256k1 == secp256k1;
    let _ = secp256k1.address(message);
    let _ = secp256k1.evm_address(message);
    let _ = secp256k1.verify(public_key, message);
    let _ = secp256k1.verify_address(Address::zero(), message);
    let _ = secp256k1.verify_evm_address(EvmAddress::zero(), message);

    let secp256r1 = std::crypto::secp256r1::Secp256r1::new();
    let _ = secp256r1 == secp256r1;
    let _ = secp256r1.address(message);
    let _ = secp256r1.evm_address(message);
    let _ = secp256r1.verify(public_key, message);
    let _ = secp256r1.verify_address(Address::zero(), message);
    let _ = secp256r1.verify_evm_address(EvmAddress::zero(), message);
}
```

## 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)
- [ ] 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lib: std Standard library
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants