From c273b6e476aa0d5bd78840cb66830b312e47da9e Mon Sep 17 00:00:00 2001 From: Peter Smith Date: Wed, 15 Jan 2025 13:12:15 +0000 Subject: [PATCH 1/5] fix: incorrect offset --- packages/abi-coder/src/FunctionFragment.ts | 2 +- .../fuel-gauge/src/abi/abi-script.test.ts | 83 +++++++++++++++++++ .../test/fixtures/forc-projects/Forc.toml | 1 + .../script-with-complex-args/Forc.toml | 7 ++ .../script-with-complex-args/src/main.sw | 16 ++++ 5 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 packages/fuel-gauge/src/abi/abi-script.test.ts create mode 100644 packages/fuel-gauge/test/fixtures/forc-projects/script-with-complex-args/Forc.toml create mode 100644 packages/fuel-gauge/test/fixtures/forc-projects/script-with-complex-args/src/main.sw diff --git a/packages/abi-coder/src/FunctionFragment.ts b/packages/abi-coder/src/FunctionFragment.ts index 7565564dc35..f9c97f6a1b2 100644 --- a/packages/abi-coder/src/FunctionFragment.ts +++ b/packages/abi-coder/src/FunctionFragment.ts @@ -109,7 +109,7 @@ export class FunctionFragment { return { decoded: [...obj.decoded, decodedValue], - offset: obj.offset + decodedValueByteSize, + offset: decodedValueByteSize, }; }, { decoded: [], offset: 0 } diff --git a/packages/fuel-gauge/src/abi/abi-script.test.ts b/packages/fuel-gauge/src/abi/abi-script.test.ts new file mode 100644 index 00000000000..e92ef9b448d --- /dev/null +++ b/packages/fuel-gauge/src/abi/abi-script.test.ts @@ -0,0 +1,83 @@ +import { getRandomB256 } from 'fuels'; +import { launchTestNode } from 'fuels/test-utils'; + +import { ScriptMainReturnStruct } from '../../test/typegen/scripts/ScriptMainReturnStruct'; +import type { ScriptMainReturnStructInputs } from '../../test/typegen/scripts/ScriptMainReturnStruct'; +import { + ScriptWithComplexArgs, + type AssetIdInput, + type ScriptWithComplexArgsInputs, +} from '../../test/typegen/scripts/ScriptWithComplexArgs'; +import type { Vec } from '../../test/typegen/scripts/common'; + +describe('abi-script', () => { + describe('decodeArguments', () => { + it('should decode arguments with a simple script', async () => { + using launched = await launchTestNode(); + const { + wallets: [funder], + } = launched; + + const args: ScriptMainReturnStructInputs = [1, { x: 2 }]; + + // Run script + const script = new ScriptMainReturnStruct(funder); + const tx = await script.functions.main(...args).call(); + const { value, transactionResult } = await tx.waitForResult(); + expect(value).toEqual({ x: 3 }); + + // Assert script data + const scriptData = transactionResult.transaction.scriptData; + if (!scriptData) { + throw new Error('No script data'); + } + + // Assert the decoded script data matches the input arguments + const fn = script.interface.getFunction('main'); + const decoded = fn.decodeArguments(scriptData); + expect(decoded).toEqual(args); + }); + + it('should decode arguments with a complex script', async () => { + using launched = await launchTestNode(); + + const { + wallets: [wallet], + } = launched; + + const arg1 = 100; + const arg2 = { bits: getRandomB256() }; + const arg3 = 100; + const arg4 = [[{ bits: getRandomB256() }, { bits: getRandomB256() }, true]] as Vec< + [AssetIdInput, AssetIdInput, boolean] + >; + const arg5 = { Address: { bits: getRandomB256() } }; + const arg6 = 100; + + // Run script + const script = new ScriptWithComplexArgs(wallet); + const args: ScriptWithComplexArgsInputs = [arg1, arg2, arg3, arg4, arg5, arg6]; + const tx = await script.functions.main(...args).call(); + const { value, transactionResult } = await tx.waitForResult(); + expect(value).toEqual(true); + + // Assert script data + const scriptData = transactionResult.transaction.scriptData; + if (!scriptData) { + throw new Error('No script data'); + } + + // Assert the decoded script data matches the input arguments + const fn = script.interface.getFunction('main'); + const decoded = fn.decodeArguments(scriptData); + expect(decoded).toEqual([ + expect.toEqualBn(arg1), + arg2, + expect.toEqualBn(arg3), + arg4, + arg5, + expect.toEqualBn(arg6), + ]); + }); + }); +}); diff --git a/packages/fuel-gauge/test/fixtures/forc-projects/Forc.toml b/packages/fuel-gauge/test/fixtures/forc-projects/Forc.toml index 0c656a9f286..7a4dc974141 100644 --- a/packages/fuel-gauge/test/fixtures/forc-projects/Forc.toml +++ b/packages/fuel-gauge/test/fixtures/forc-projects/Forc.toml @@ -64,6 +64,7 @@ members = [ "script-with-more-configurable", "script-with-vector", "script-with-options", + "script-with-complex-args", "script-with-vector-advanced", "script-with-vector-mixed", "small-bytes", diff --git a/packages/fuel-gauge/test/fixtures/forc-projects/script-with-complex-args/Forc.toml b/packages/fuel-gauge/test/fixtures/forc-projects/script-with-complex-args/Forc.toml new file mode 100644 index 00000000000..882c1cc41a4 --- /dev/null +++ b/packages/fuel-gauge/test/fixtures/forc-projects/script-with-complex-args/Forc.toml @@ -0,0 +1,7 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "script-with-complex-args" + +[dependencies] diff --git a/packages/fuel-gauge/test/fixtures/forc-projects/script-with-complex-args/src/main.sw b/packages/fuel-gauge/test/fixtures/forc-projects/script-with-complex-args/src/main.sw new file mode 100644 index 00000000000..4e6291450d6 --- /dev/null +++ b/packages/fuel-gauge/test/fixtures/forc-projects/script-with-complex-args/src/main.sw @@ -0,0 +1,16 @@ +script; + +use std::bytes::Bytes; + +pub type PoolId = (AssetId, AssetId, bool); + +fn main( + amount_in: u64, + asset_in: AssetId, + amount_out_min: u64, + pools: Vec, + recipient: Identity, + deadline: u32, +) -> bool { + return true; +} From af11094d1c563c6b53cebbcdcffc465a8c13f320 Mon Sep 17 00:00:00 2001 From: Peter Smith Date: Wed, 15 Jan 2025 13:13:37 +0000 Subject: [PATCH 2/5] chore: changeset --- .changeset/nasty-carrots-report.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/nasty-carrots-report.md diff --git a/.changeset/nasty-carrots-report.md b/.changeset/nasty-carrots-report.md new file mode 100644 index 00000000000..fc24ba121c6 --- /dev/null +++ b/.changeset/nasty-carrots-report.md @@ -0,0 +1,5 @@ +--- +"@fuel-ts/abi-coder": patch +--- + +fix: incorrect function coder offset usage From 640c1a80beb07de9bcafc7d31c3f24980bf54348 Mon Sep 17 00:00:00 2001 From: Peter Smith Date: Wed, 15 Jan 2025 13:14:20 +0000 Subject: [PATCH 3/5] chore: added missing @groups --- packages/fuel-gauge/src/abi/abi-script.test.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/fuel-gauge/src/abi/abi-script.test.ts b/packages/fuel-gauge/src/abi/abi-script.test.ts index e92ef9b448d..dd3ab7b4b14 100644 --- a/packages/fuel-gauge/src/abi/abi-script.test.ts +++ b/packages/fuel-gauge/src/abi/abi-script.test.ts @@ -10,6 +10,10 @@ import { } from '../../test/typegen/scripts/ScriptWithComplexArgs'; import type { Vec } from '../../test/typegen/scripts/common'; +/** + * @group browser + * @group node + */ describe('abi-script', () => { describe('decodeArguments', () => { it('should decode arguments with a simple script', async () => { From a0bec43df1c357879c928064bfab75e448bbbd21 Mon Sep 17 00:00:00 2001 From: Peter Smith Date: Wed, 15 Jan 2025 13:19:30 +0000 Subject: [PATCH 4/5] chore: change name of variable --- packages/abi-coder/src/FunctionFragment.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/abi-coder/src/FunctionFragment.ts b/packages/abi-coder/src/FunctionFragment.ts index f9c97f6a1b2..32087c21d19 100644 --- a/packages/abi-coder/src/FunctionFragment.ts +++ b/packages/abi-coder/src/FunctionFragment.ts @@ -105,11 +105,11 @@ export class FunctionFragment { const result = this.jsonFnOld.inputs.reduce( (obj: { decoded: unknown[]; offset: number }, input) => { const coder = AbiCoder.getCoder(this.jsonAbiOld, input, { encoding: this.encoding }); - const [decodedValue, decodedValueByteSize] = coder.decode(bytes, obj.offset); + const [decodedValue, decodedOffset] = coder.decode(bytes, obj.offset); return { decoded: [...obj.decoded, decodedValue], - offset: decodedValueByteSize, + offset: decodedOffset, }; }, { decoded: [], offset: 0 } From a9a2625790054b8517a77d96aca7c327658894bf Mon Sep 17 00:00:00 2001 From: Peter Smith Date: Wed, 15 Jan 2025 16:57:23 +0000 Subject: [PATCH 5/5] chore: added expectations for the script result --- .../fuel-gauge/src/abi/abi-script.test.ts | 19 ++++++++++--------- .../script-with-complex-args/src/main.sw | 8 +++++--- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/packages/fuel-gauge/src/abi/abi-script.test.ts b/packages/fuel-gauge/src/abi/abi-script.test.ts index dd3ab7b4b14..c6eb5eecb05 100644 --- a/packages/fuel-gauge/src/abi/abi-script.test.ts +++ b/packages/fuel-gauge/src/abi/abi-script.test.ts @@ -57,13 +57,21 @@ describe('abi-script', () => { >; const arg5 = { Address: { bits: getRandomB256() } }; const arg6 = 100; + const expected = [ + expect.toEqualBn(arg1), + arg2, + expect.toEqualBn(arg3), + arg4, + arg5, + expect.toEqualBn(arg6), + ]; // Run script const script = new ScriptWithComplexArgs(wallet); const args: ScriptWithComplexArgsInputs = [arg1, arg2, arg3, arg4, arg5, arg6]; const tx = await script.functions.main(...args).call(); const { value, transactionResult } = await tx.waitForResult(); - expect(value).toEqual(true); + expect(value).toEqual(expected); // Assert script data const scriptData = transactionResult.transaction.scriptData; @@ -74,14 +82,7 @@ describe('abi-script', () => { // Assert the decoded script data matches the input arguments const fn = script.interface.getFunction('main'); const decoded = fn.decodeArguments(scriptData); - expect(decoded).toEqual([ - expect.toEqualBn(arg1), - arg2, - expect.toEqualBn(arg3), - arg4, - arg5, - expect.toEqualBn(arg6), - ]); + expect(decoded).toEqual(expected); }); }); }); diff --git a/packages/fuel-gauge/test/fixtures/forc-projects/script-with-complex-args/src/main.sw b/packages/fuel-gauge/test/fixtures/forc-projects/script-with-complex-args/src/main.sw index 4e6291450d6..5431991fcfc 100644 --- a/packages/fuel-gauge/test/fixtures/forc-projects/script-with-complex-args/src/main.sw +++ b/packages/fuel-gauge/test/fixtures/forc-projects/script-with-complex-args/src/main.sw @@ -2,7 +2,9 @@ script; use std::bytes::Bytes; -pub type PoolId = (AssetId, AssetId, bool); +type PoolId = (AssetId, AssetId, bool); + +type ScriptResult = (u64, AssetId, u64, Vec, Identity, u32); fn main( amount_in: u64, @@ -11,6 +13,6 @@ fn main( pools: Vec, recipient: Identity, deadline: u32, -) -> bool { - return true; +) -> ScriptResult { + return (amount_in, asset_in, amount_out_min, pools, recipient, deadline); }