Skip to content
New issue

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

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

Already on GitHub? # to your account

feat: ABI refactor #3085

Draft
wants to merge 55 commits into
base: master
Choose a base branch
from
Draft

feat: ABI refactor #3085

wants to merge 55 commits into from

Conversation

petertonysmith94
Copy link
Contributor

@petertonysmith94 petertonysmith94 commented Sep 3, 2024

Closes TS-598, TS-599, TS-600
Part of TS-597, TS-601

Release notes

In this release, we:

  • A brand new package @fuel-ts/abi for all things ABI related

Summary

  • Introduction of the AbiParser which will transform an ABI into an easier to use entity.

Breakdown

ABI Parser

Summary

  • Adds the parsing functionality for an ABI. The Abi interface outputted by AbiParser will be the (hopefully) unchanging interface that will be used both by us in coders and typers, as well as external users who wish to work with the abi but not be affected by changing specifications.

  • The AbiParser output is tested both by a comprehensive test in this PR as well as feat!: ABI Gen #3249 and feat: ABI coder #3402 which are based off of this PR and are directly consuming the output.

Flow diagrams

image

image

ABI Typegen

Summary

The implementation has two parts:
1. AbiGen and its type generation which is done by using the AbiParser outputs,
2. The CLI providing inputs to AbiGen and saving its outputs to disk

ABI Coder

Summary

  • This PR encompasses the refactoring and revamping of the encoding.
  • The following diagram outlines all the different encoding types and how the encoded types look in bytes.

image

Breaking Changes

fuels typegen no longer accepts -s, -p and -c flags

pnpm fuels typegen can now automatically recognize the type of program it's building so the flags --script, --predicate and --contract and their shorthands have been removed.

The storageSlots static field has been moved from a typegen'd contract into its factory

Storage slots don't need to be on the typegen'd Contract because they are only used during contract deployment.

// before
import { MyContract } from './typegend/contracts'

const defaultStorageSlots = MyContract.storageSlots;
// after
import { MyContractFactory } from './typegend/contracts'

const defaultStorageSlots = MyContractFactory.storageSlots;

Typegen'd simple sway enums don't have the Input/Output suffix anymore

Given the following enum:

enum Color {
    Red: (),
    Green: (),
}

The outputted type looks like this:

// before
import { ColorInput, ColorOutput } from './typegend/contracts/MyContract';
// after
import { Color } from './typegend/contracts/MyContract';

Vec<T> has been removed in favor of T[] and cannot be imported anymore

// before
import { Vec } from './typegend/common';
type MyInputVector = Vec<number>;
// now
type MyInputVector = number[];

The Interface class has been removed in favour of the AbiCoder.

// Before
const abiInterface = new Interface({ ...abi });
// After
const abiCoder = new AbiCoder({ ...abi });

The Interface.decodeFunctionResult has moved to the AbiCoderFunction.decodeOutput

// Before
const data = new Uint8Array(...);
abiInterface.decodeFunctionResult('fn_name', data)
// After
const data = new Uint8Array(...);
abiCoder.getFunction('fn_name').decodeOutput(data)

The Interface.decodeLog has moved to the AbiCoderLog.decode

// Before
const data = new Uint8Array(...);
abiInterface.decodeLog(data, 'log_id')
// After
const data = new Uint8Array(...);
abiCoder.getLog('log_id').decode(data);

The Interface.encodeConfigurable has moved to the AbiCoderConfigurable.encode

// Before
const value = 'Configurable Value';
abiInterface.encodeConfigurable('configurable_name', value);
// After
const value = 'Configurable Value';
abiInterface.getConfigurable('configurable_name').encode(value);

The Interface.encodeType and Interface.encodeType has moved to the AbiCoderType

// Before
abiInterface.encodeType('concrete_type_id', 'Type value');
abiInterface.decodeType('concrete_type_id', new Uint8Array(...));
// After
abiInterface.getType('concrete_type_id').encode('Type value');
abiInterface.getType('concrete_type_id').decode(new Uint8Array(...));

Accessing underlying coders is now achieved through a convenient class, AbiEncoding.

// Before
import { NumberCoder, BigNumberCoder, B256Coder, B512Coder, VoidCoder, BooleanCoder, RawSliceCoder, StrSliceCoder, StdStringCoder } from '@fuel-ts/abi-coder';

const u8Coder = new NumberCoder('u8');
const u16Coder = new NumberCoder('u16');
const u32Coder = new NumberCoder('u32');
const u64Coder = new BigNumberCoder('u64');
const u256Coder = new BigNumberCoder('u256');
const b256Coder = new B256Coder();
const b512Coder = new B512Coder();
const boolCoder = new BooleanCoder();
const voidCoder = new VoidCoder();

const byteCoder = new ByteCoder();
const rawSliceCoder = new RawSliceCoder();
const strSliceCoder = new StrSliceCoder();
const stdStringCoder = new StdStringCoder();
const stringCoder = new StringCoder(4);

const arrayCoder = new ArrayCoder(u8Coder, 3);
const tupleCoder = new TupleCoder([u8Coder, u8Coder]);
const vectorCoder = new VecCoder(u8Coder);

const enumCoder = new EnumCoder('name of enum', { u8: u8Coder });
const optionCoder = new OptionCoder('name of option', { None: voidCoder, Some: voidCoder });
const structCoder = new StructCoder('name of struct', { u8: u8Coder });
// After
import { encoding } from '@fuel-ts/abi';

const u8Coder = encoding.u8;
const u16Coder = encoding.u16;
const u32Coder = encoding.u32;
const u64Coder = encoding.u64;
const u256Coder = encoding.u256;
const b256Coder = encoding.b256;
const b512Coder = encoding.b512;
const boolCoder = encoding.bool;
const voidCoder = encoding.void;

const byteCoder = encoding.byte;
const rawSliceCoder = encoding.rawSlice;
const strSliceCoder = encoding.str;
const stdStringCoder = encoding.stdString;
const stringCoder = encoding.string(4);

const arrayCoder = encoding.array(u8Coder, 3);
const tupleCoder = encoding.tuple([u8Coder, u8Coder]);
const vectorCoder = encoding.vector(u8Coder);

const enumCoder = encoding.enum({ u8: u8Coder });
const optionCoder = encoding.option({ None: voidCoder, Some: voidCoder });
const structCoder = encoding.struct({ u8: u8Coder });

Removal of the constant INPUT_COIN_FIXED_SIZE

import { INPUT_COIN_FIXED_SIZE } from 'fuels';

Renamed Encoding from the @fuel-ts/crypto package to BufferEncoding.

// Before
import { Encoding } from '@fuel-ts/crypto';
// After
import { BufferEncoding } from '@fuel-ts/crypto';

Checklist

  • All changes are covered by tests (or not applicable)
  • All changes are documented (or not applicable)
  • I reviewed the entire PR myself (preferably, on GH UI)
  • I described all Breaking Changes (or there's none)

Copy link

vercel bot commented Sep 3, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
create-fuels-template ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jan 23, 2025 3:15pm
fuels-template ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jan 23, 2025 3:15pm
ts-api-docs ❌ Failed (Inspect) Jan 23, 2025 3:15pm
ts-docs ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jan 23, 2025 3:15pm
ts-docs-api ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jan 23, 2025 3:15pm
1 Skipped Deployment
Name Status Preview Comments Updated (UTC)
create-fuels-counter-example ⬜️ Ignored (Inspect) Jan 23, 2025 3:15pm

---
---

feat: ABI refactor
Copy link
Contributor Author

@petertonysmith94 petertonysmith94 Sep 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

This is not to be merged until we've concluded development

@petertonysmith94 petertonysmith94 added this to the Caterpillar v1 milestone Sep 3, 2024
Copy link
Contributor

github-actions bot commented Sep 4, 2024

Coverage Report:

Lines Branches Functions Statements
79.26%(+0%) 71.93%(+0%) 77.55%(+0%) 79.33%(+0%)
Changed Files:

Coverage values did not change👌.

* feat: ABI parser

* remove casts

* remove unnecessary throw

* centralize abi cleanup logic

* remove rawUntypedPtr from swayTypeMatchers

* rename method

* Update cleanup-abi.ts

* Update cleanup-abi.ts

* refactor abi type mappers

* refactor into using maps for types

* refactor from array of tuples into `Map`

* rename variables

* refactorings, comments

* split test up into multiple tests

---------

Co-authored-by: Peter Smith <peter@blueoceancomputing.co.uk>
* parser scaffolding

* lint fix

* chore: ABI parser - API alterations (#3164)

* Add `AbiTypeMetadata` and fix bug

* chore: adjust attributes to match spec

* chore: added `FuelError`

* chore: fixed test for matchers

* fix generic type resolution edge case

* changeset

* refactoring, commenting

* chore: favour `concreteTypeId`

* chore: fix up errors for the parser specification

* docs: added error code

* chore: nit

* chore: attribute arguments always defined

* chore: fix incorrect inline attribute arguments

* chore: re-adjusted `mapAttribute`

* chore: added helper functions for finding concreteTypes and metadataTypes

* chore: removed static methods + further `findConcreteType` + `findMetadataType` simplifications

* chore: more verbose variable names

* chore: constructor as first public method

* chore: rename `type` for `swayType`

* chore: removed `specVersion`

* add comments

* chore: added name to typeArguments

* comments

* fix?

* fix?

* chore: rollback to working state

* refactoring

* add test group

* revert changes

* format projects

* export parser from fuels

* cleanup

* renamings

* renamings

* add comments to `Abi`

* add docs

* update docs

* rename test

* rename  to

* formatting

* more explanations

* cleaner

* formatting

* comments

* add double generic case

* fix test

* update changeset

* revert

* fix changeset

* not breaking

* fix test

* add import check

* fix linting

* fix lint

* add comments to abi interface

* Update .changeset/tender-tigers-fry.md

Co-authored-by: Chad Nehemiah <chad.nehemiah94@gmail.com>

* fix changeset

* add implicit generic edge case

* feat: ABI Gen

* fix storage slots and imports in tests

* fix linting

* fix linting

* Update .changeset/poor-years-hang.md

Co-authored-by: Peter Smith <peter@blueoceancomputing.co.uk>

* improve type arguments representation

* fix type arguments

* explanatory comment

* move types to separate file

* move fixtures into folders

* move `mapComponents` and add explanations

* move logic to shared folder

* add type docs explaining functions

* add doc blocks for `AbiGen` and related types

* remove unnecessary flags

* remove todo

* input/output

* feat: ABI parser

* remove casts

* remove unnecessary throw

* centralize abi cleanup logic

* remove rawUntypedPtr from swayTypeMatchers

* remove rawUntypedPtr

* made `abi` and `storage-slots` ts files

* move from linting to cast

* remove usage of `fuels-typegen`

* change to `FuelError`

* simplify inputs/output types for script and predicate

* improve index file rendering

* export types from base program file (and thus index)

* cleanup type rendering

* simplified program rendering

* fix recipes

* reorder deps

* refactor render-index-files

* remove file

* update changeset

* fix changeset

* fix recipes build

* fix test

* cleanup

* fix knip

* fix lint

* export inputs, outputs and configurables

* rename method

* Update cleanup-abi.ts

* Update cleanup-abi.ts

* refactor abi type mappers

* refactor into using maps for types

* refactor from array of tuples into `Map`

* rename variables

* refactorings, comments

* split test up into multiple tests

* remove already included --silent flag

* added non-happy paths testing

* mvoed cli into abi package

* cleanup

* export types from contract/predicate/script

* improve upon index exports now that types are also re-exported

* fix pnpm-lock.yaml

* rename

* fix recipes

* log instead of throwing

* fix lint

* add `forc` and `fuel-core` to path

* try again

* try again

* fix lint

* Increase timeout

* cleanup

* revert timeout

* chore: use playwright in browser tests

* revert isolate flag for safety

* revert some changes

* update docs

* update imports

* revert file

* revert input

* fix import

* update

* revert file

* remove flags

* fix lint

* lock file fix

* fix tests

* fix lint

* fix lint 2

* fix lock file

* chore: sync build

* chore: removed `Vec`

---------

Co-authored-by: nedsalk <nedim.salkic@fuel.sh>
Co-authored-by: Chad Nehemiah <chad.nehemiah94@gmail.com>
export function getProgramDetails(paths: string[]) {
const details: ProgramDetails[] = [];
paths.forEach((path) => {
const abiPath = path.match(/.+-abi\.json/) ? path : globSync(`${path}/*-abi.json`)[0];

Check failure

Code scanning / CodeQL

Polynomial regular expression used on uncontrolled data High generated

This
regular expression
that depends on
library input
may run slow on strings with many repetitions of 'a'.
return;
}

const dir = abiPath.match(/.*\//)?.[0] as string;

Check failure

Code scanning / CodeQL

Polynomial regular expression used on uncontrolled data High generated

This
regular expression
that depends on
library input
may run slow on strings with many repetitions of 'a'.
}

const dir = abiPath.match(/.*\//)?.[0] as string;
const projectName = abiPath.match(/([^/])+(?=-abi\.json)/)?.[0] as string;

Check failure

Code scanning / CodeQL

Polynomial regular expression used on uncontrolled data High generated

This
regular expression
that depends on
library input
may run slow on strings with many repetitions of '.'.
petertonysmith94 and others added 2 commits January 23, 2025 15:02
* feat: ABI parser

* feat: ABI coder

* remove casts

* remove unnecessary throw

* centralize abi cleanup logic

* fix function signature for bytes

* remove rawUntypedPtr from swayTypeMatchers

* remove rawUntypedPtr from swayTypeMatchers

* remove rawUntypedPtr

* fix lint

* rename method

* Update cleanup-abi.ts

* Update cleanup-abi.ts

* refactor abi type mappers

* refactor into using maps for types

* refactor from array of tuples into `Map`

* rename variables

* refactor out function

* fix comments, add comments

* refactorings, comments

* split test up into multiple tests

* docs: update variable

* chore: applying unsafe integer validation

* chore: refactored coder matchers

* chore: perform renames

* chore: fix package version

* chore: missing lock file

* chore: finalize integration with the ABI

* chore: remove parser from export

* chore: added auto-update for typegen fixtures

* chore: added auto-update for typegen fixtures

* chore: updated fixtures

* chore: removed unused dependency

---------

Co-authored-by: nedsalk <nedim.salkic@fuel.sh>
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
feat Issue is a feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Abi - Refactor / Gen Abi - Refactor / Coder Abi - Refactor / Parser
6 participants