Skip to content

Commit

Permalink
feat: disable option length validation at enum Option level (#2336)
Browse files Browse the repository at this point in the history
* feat: disable option size validation

* chore: changeset

* chore: changeset

* chore: update changeset
  • Loading branch information
danielbate authored May 18, 2024
1 parent 63a9d55 commit 64b90a9
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/kind-flowers-chew.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@fuel-ts/abi-coder": patch
---

feat: disable `option` length validation at `enum Option` level
8 changes: 4 additions & 4 deletions packages/abi-coder/src/encoding/coders/EnumCoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { toNumber } from '@fuel-ts/math';
import { concat } from '@fuel-ts/utils';
import type { RequireExactlyOne } from 'type-fest';

import { WORD_SIZE } from '../../utils/constants';
import { OPTION_CODER_TYPE, WORD_SIZE } from '../../utils/constants';
import { hasNestedOption } from '../../utils/utilities';

import type { TypesOfCoder } from './AbstractCoder';
Expand Down Expand Up @@ -31,7 +31,7 @@ export class EnumCoder<TCoders extends Record<string, Coder>> extends Coder<
coders: TCoders;
#caseIndexCoder: BigNumberCoder;
#encodedValueSize: number;
#hasNestedOption: boolean;
#shouldValidateLength: boolean;

constructor(name: string, coders: TCoders) {
const caseIndexCoder = new BigNumberCoder('u64');
Expand All @@ -44,7 +44,7 @@ export class EnumCoder<TCoders extends Record<string, Coder>> extends Coder<
this.coders = coders;
this.#caseIndexCoder = caseIndexCoder;
this.#encodedValueSize = encodedValueSize;
this.#hasNestedOption = hasNestedOption(coders);
this.#shouldValidateLength = !(this.type === OPTION_CODER_TYPE || hasNestedOption(coders));
}

#encodeNativeEnum(value: string): Uint8Array {
Expand Down Expand Up @@ -80,7 +80,7 @@ export class EnumCoder<TCoders extends Record<string, Coder>> extends Coder<
}

decode(data: Uint8Array, offset: number): [DecodedValueOf<TCoders>, number] {
if (!this.#hasNestedOption && data.length < this.#encodedValueSize) {
if (this.#shouldValidateLength && data.length < this.#encodedValueSize) {
throw new FuelError(ErrorCode.DECODE_ERROR, `Invalid enum data size.`);
}

Expand Down
15 changes: 14 additions & 1 deletion packages/fuel-gauge/src/options.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Contract } from 'fuels';
import { generateTestWallet } from '@fuel-ts/account/test-utils';
import type { Contract, WalletUnlocked } from 'fuels';

import { getSetupContract } from './utils';

Expand All @@ -8,8 +9,12 @@ const U32_MAX = 4294967295;

const setupContract = getSetupContract('options');
let contractInstance: Contract;
let wallet: WalletUnlocked;
beforeAll(async () => {
contractInstance = await setupContract();
wallet = await generateTestWallet(contractInstance.provider, [
[200_000, contractInstance.provider.getBaseAssetId()],
]);
});

/**
Expand Down Expand Up @@ -179,4 +184,12 @@ describe('Options Tests', () => {

expect(value).toStrictEqual(input);
});

it('prints struct option', async () => {
const { value } = await contractInstance.functions
.get_some_struct({ Address: { bits: wallet.address.toB256() } })
.call();

expect(value).toStrictEqual(undefined);
});
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
contract;

use {std::{auth::msg_sender, hash::Hash,},};

enum OptionEnum {
a: Option<u8>,
b: Option<u16>,
Expand Down Expand Up @@ -49,7 +51,18 @@ struct DeepStruct {
DeepEnum: DeepEnum,
}

struct SomeStruct {
a: u64,
b: u64,
}

storage {
stuff: StorageMap<Identity, SomeStruct> = StorageMap {},
}

abi OptionContract {
#[storage(read)]
fn get_some_struct(id: Identity) -> Option<SomeStruct>;
fn echo_option(arg: Option<u8>) -> Option<u8>;
fn echo_struct_enum_option(arg: OptionStruct) -> OptionStruct;
fn echo_vec_option(arg: Vec<Option<u32>>) -> Vec<Option<u32>>;
Expand All @@ -61,6 +74,11 @@ abi OptionContract {
}

impl OptionContract for Contract {
#[storage(read)]
fn get_some_struct(id: Identity) -> Option<SomeStruct> {
storage.stuff.get(id).try_read()
}

fn echo_option(arg: Option<u8>) -> Option<u8> {
arg
}
Expand Down

0 comments on commit 64b90a9

Please sign in to comment.