Skip to content
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

feat!: adding abi transpiler #2856

Merged
merged 80 commits into from
Aug 19, 2024
Merged

feat!: adding abi transpiler #2856

merged 80 commits into from
Aug 19, 2024

Conversation

arboleya
Copy link
Member

@arboleya arboleya commented Jul 29, 2024

Release notes

In this release, we:

Summary

Given the amount of structural changes we had in the new ABI and the impact it will have on the codebase, and provided the fact we have a lot of technical debt to clear regarding ABI coder and typegen packages (#1795, #2346, #2686), this proposal aim at releasing the pressure of the moment by transpiling the old format into the new one, while still:

  • Supporting the new ABI spec
  • Introducing the least amount of changes possible
  • Keeping all tests and coverage intact

Transpilation occurs internally between public and private APIs.

  • Transpilation is an internal detail on the Interface level
  • Typegen includes the new abi format in its generated code but doesn't transpile it
  • All public-facing APIs use the new spec ABI under JsonAbi, and the old one is available as JsonAbiOld
  • AbiCoder is no longer exported, and its methods moved to Interface via encodeType/decodeType (ee734b9)
  • We removed the Interface.findTypeById method in 157bdba because the concept of a type in the new ABI differs from the old one. Whoever wants to get a specific concrete or metadata type can do so directly from the ABI they have on the Interface.jsonAbi property

Special thanks ❤️

Huge shoutout to @nedsalk, who was crucial for this work and ensured everything around this was working as expected everywhere and finalized all the heavy lifting around public vs private APIs via:

Also, to @petertonysmith94, for the thorough reviews and additional bug-fixing via:

Breaking Changes

New ABI spec

The SDK now adheres to the new specs introduced via:

Check these out to understand all its changes.

AbiCoder is no longer available to import

The class AbiCoder is no longer exported, and the way to do encoding and decoding of specific types is now via the Interface.encodeType and Interface.decodeType methods:

// before
const abi = yourAbi;
const functionArg = abi.functions.inputs[0];

const encoded = AbiCoder.encode(abi, functionArg, valueToEncode);
const decoded = AbiCoder.decode(abi, functionArg, valueToDecode, 0);
// after
import { Interface } from 'fuels';

const abi = yourAbi;
const functionArg = abi.functions.inputs[0];

const abiInterface = new Interface(abi);

const encoded = abiInterface.encodeType(functionArg.concreteTypeId, valueToEncode);
const decoded = abiInterface.decodeType(functionArg.concreteTypeId, valueToDecode);

Interface.findTypeById has been removed

Previously, you could get a type from the ABI via the Interface.findTypeById. This method was removed after introducing the new abi specification because the concept of a type has been split into concrete and metadata types. If you want a specific type, you can get it directly from the ABI.

// before
const abiInterface = new Interface(abi);

// internally this method searched the abi types:
// abi.types.find(t => t.typeId === id);
const type = abiInterface.findTypeById(id);
// after
import { Interface } from 'fuels';

// search the types on the abi directly
const concreteType = abi.concreteTypes.find(ct => ct.concreteTypeId === id);
const metadataType = abiInterface.jsonAbi.metadataTypes.find(mt => mt.metadataTypeId === id);

JsonAbiArgument is no longer exported

The JsonAbiArgument type isn't part of the new ABI spec (#596, #599) as such so we stopped exporting it. Its closest equivalent now would be a concrete type because it fully defines a type.

// before
const arg: JsonAbiArgument = {...};
// after
import { Interface } from 'fuels';

type ConcreteType = JsonAbi["concreteTypes"][number]
const arg: ConcreteType = {...};

Checklist

  • I addedtests to prove my changes
  • I updated — all the necessary docs
  • I reviewed — the entire PR myself, using the GitHub UI
  • I described — all breaking changes and the Migration Guide

@arboleya arboleya added the feat Issue is a feature label Jul 29, 2024
@arboleya arboleya self-assigned this Jul 29, 2024
internal/forc/lib/shared.js Dismissed Show dismissed Hide dismissed
internal/forc/lib/shared.js Dismissed Show dismissed Hide dismissed
internal/forc/lib/shared.js Fixed Show fixed Hide fixed
internal/forc/lib/shared.js Dismissed Show dismissed Hide dismissed
Copy link
Contributor

@petertonysmith94 petertonysmith94 left a comment

Choose a reason for hiding this comment

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

🚀 🚢

Torres-ssf
Torres-ssf previously approved these changes Aug 19, 2024
danielbate
danielbate previously approved these changes Aug 19, 2024
Copy link
Contributor

@danielbate danielbate left a comment

Choose a reason for hiding this comment

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

:shipit:

Copy link
Contributor

Coverage Report:

Lines Branches Functions Statements
79.43%(+0.22%) 71.89%(+0.51%) 77.77%(+0.4%) 79.56%(+0.22%)
Changed Files:
Ok File (✨=New File) Lines Branches Functions Statements
🔴 packages/abi-coder/src/AbiCoder.ts 100%
(+25%)
0%
(+0%)
100%
(+33.34%)
100%
(+25%)
🔴 packages/abi-coder/src/FunctionFragment.ts 63.15%
(+0.99%)
37.5%
(+0%)
69.23%
(+2.57%)
63.41%
(+1.88%)
🔴 packages/abi-coder/src/Interface.ts 76%
(+4.58%)
63.63%
(+0%)
75%
(+2.28%)
75%
(+4.17%)
🔴 packages/abi-coder/src/encoding/strategies/getCoderV1.ts 91.83%
(+0.17%)
88.57%
(+1.48%)
100%
(+0%)
92%
(+0.17%)
🔴 packages/abi-coder/src/utils/constants.ts 97.56%
(+0.06%)
100%
(+0%)
0%
(+0%)
97.56%
(+0.06%)
🔴 ✨ packages/abi-coder/src/utils/transpile-abi.ts 97.36%
(+97.36%)
87.5%
(+87.5%)
94.11%
(+94.11%)
95.45%
(+95.45%)
packages/abi-typegen/src/templates/utils/formatEnums.ts 100%
(+0%)
100%
(+50%)
100%
(+0%)
100%
(+0%)
packages/abi-typegen/src/templates/utils/formatStructs.ts 100%
(+0%)
100%
(+50%)
100%
(+0%)
100%
(+0%)
🔴 ✨ packages/abi-typegen/src/utils/transpile-abi.ts 100%
(+100%)
95.83%
(+95.83%)
94.11%
(+94.11%)
97.72%
(+97.72%)
🔴 packages/account/src/providers/transaction-request/transaction-request.ts 88.48%
(+0%)
79.71%
(+1.45%)
84%
(+0%)
88.73%
(+0%)

@arboleya arboleya merged commit 4c653d0 into master Aug 19, 2024
20 checks passed
@arboleya arboleya deleted the aa/feat/adding-abi-transpiler branch August 19, 2024 22:22
@arboleya arboleya mentioned this pull request Aug 20, 2024
readonly type: string;
readonly metadataTypeId: number;
readonly components?: readonly Component[];
readonly typeParameters?: readonly number[];
Copy link
Member

Choose a reason for hiding this comment

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

Is this an array of concrete type indexes or metadata type indexes? It's hard to tell which array this refers to.

Copy link
Contributor

Choose a reason for hiding this comment

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

It is an array of metadata type ids:

"typeParameters": an array of type metadata declaration ID of the type parameters of the type, if the type is generic, otherwise nonexistent. Each type parameter is a type declaration and is represented as described in Generic Type Parameter.

Copy link
Member

Choose a reason for hiding this comment

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

IDs as in the hashes or the array indexes? Everywhere else, it looks like the hashes are stored as strings. Are these hashes stored as numbers instead or are these array indexes?

The spec itself is unclear on this.

Copy link
Contributor

Choose a reason for hiding this comment

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

Metadata type ids are always numbers. On the topic of array indexes, I wouldn't use array indexes for anything; they might correlate with the metadataTypeId of an entry in the metadataTypes array, but the spec doesn't define that relationship.

export interface ConcreteType {
readonly type: string;
readonly concreteTypeId: string;
readonly metadataTypeId?: number;
Copy link
Member

@sdankel sdankel Aug 20, 2024

Choose a reason for hiding this comment

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

Per the spec, this should be a string (hash). It would help reduce complexity if this were consistent.

Copy link
Contributor

Choose a reason for hiding this comment

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

The link you gave us points to this same field the comment is on...

Regardless, the spec says this for concreteType.metadataTypeId:

"metadataTypeId": the type metadata declaration ID of this type, if the type metadata has components or is generic, otherwise nonexistent.

And it defines metadataType.metadataTypeId as this:

"metadataTypeId": a unique integer ID.

So this conforms with the specification.

Copy link
Member

Choose a reason for hiding this comment

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

Sorry, updated the link. It also says this:

- _type metadata declaration_: the declaration or definition of a type which can be generic. `struct Foo { .. }` and `struct Bar<T> { .. }` in the example above are both type declarations. The metadata declaration contains component details about the type. And a single _type metadata declaration_ is generated per type, even for generic types.

Which makes it sound like "type metadata declaration ID" is the string hash, not an array index.

Copy link
Contributor

Choose a reason for hiding this comment

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

The string hashes are exclusively related to concrete types (hashes of their type property). The spec doesn't mention array indexes in relation to metadataTypeIds, it just defines them as a field of the object. I wouldn't rely on that correlation to build anything as it might change: a metadata type with id 12 might be put onto index 24 and it would still be spec-compliant.

Comment on lines +18 to +19
readonly type: string;
readonly concreteTypeId: string;
Copy link
Member

Choose a reason for hiding this comment

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

Is type just the type name, or is it the full type string? i.e. MyStruct or path::to::MyStruct<T>

Copy link
Contributor

Choose a reason for hiding this comment

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

It's the full type string. You can find examples lower down in the spec.

export interface AbiFunction {
readonly name: string;
readonly inputs: readonly AbiFunctionInput[];
readonly output: string;
Copy link
Member

Choose a reason for hiding this comment

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

Is this string the concrete type hash or the decoded full type string?

Copy link
Contributor

@nedsalk nedsalk Aug 21, 2024

Choose a reason for hiding this comment

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

It's the concrete type hash. From the spec:

"output": the type concrete declaration hash based ID of the type being returned by the function.

maschad pushed a commit that referenced this pull request Aug 21, 2024
* Upgrading forc to temp branch

* Adding ABI transpiler and integrating it with related areas

* Updating typegen fixtures

* Fixing broken typegen tests; updating outdated IDs

* Re-instating the order

* Loading forc projects the standard and proper way

* Updating coder’s types, regexes, and fixing type matching everywhere

* Updating test using callpath-based naming for Option

* Fixing test, intercepting ABI loading so it can be transpiled

* Adding changeset

* Adjusting changeset

* Excluding sway-repo source files in `forc:check` script

* Ensuring branches are up to date before building

* Building internal packages in `--release` mode

* Fixing directory path for new build target

* Merging duplicated variables, standardizing terminologies

* Improving validation to handle strings / non-objects as well

* fix: option coder decoding incorrect value (#2870)

* Revert "Improving validation to handle strings / non-objects as well"

This reverts commit 45f3ef2.

* chore: fixing types on OptionCoder

* fix: match full qualifying type name with regex

* chore: added test groups

Co-authored-by: Daniel Bate <djbate23@gmail.com>

* chore: revert StructCoder name change

---------

Co-authored-by: Daniel Bate <djbate23@gmail.com>

* Standardizing timeout limits across workflows

* Ignoring `sway-repo`in links check  when building things from source

* Fixing ignore path

* Stop deleting `concreteTypeId`, used in public API

* Update .changeset/odd-horses-cheer.md

* Ignoring also `fuel-core-repo` for the same reasons as `sway-repo`

* Update .changeset/odd-horses-cheer.md

* Updating more fixtures

* Updating snippet

* Fixing random lint warning

* Incrasing test timeout limit

* Fixing ignored paths

* chore!: internalize old `JsonAbi` format (#2862)

* use `transpileAbi` in `Interface`

* add new interfaces to typegen

* no need for `debug` build anymore

* fix `getTypegenForcProject` return type

* added `as JsonAbi` type assertions to fix type errors

* fix typegen tests

* rename variable

* stop exporting `JsonAbi` from typegen

* revert changes that should be in another PR

* contttinue exporting

* rename to match `master`

* fix encode-and-decode test

* Renamed `JsonAbiNew` to `JsonAbi` and the old format to `JsonAbiOld`

* fix compilation errors

* Stop exporting `AbiCoder` and update `encode-and-decode` example

* Removed `Interface.findTypeById` method

* stop casting `as unknown as JsonAbi`

* use `argument` directly

* fix import

* fix: `Interface.encodeType/decodeType`

* Update packages/abi-coder/src/types/JsonAbi.ts

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

* Update packages/abi-coder/src/types/JsonAbiNew.ts

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

* Update packages/abi-typegen/src/types/interfaces/JsonAbi.ts

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

* Update packages/account/test/fuel-wallet-connector.test.ts

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

* Update packages/abi-typegen/src/utils/transpile-abi.ts

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

* copy/paste transpile-abi

* fix compilation error

* eslint disable todo type

* use `{ transpile: T }` params object

* update `encode-and-decode.md` docs

* fix: spellcheck

* Update apps/docs/src/guide/encoding/encode-and-decode.md

Co-authored-by: Anderson Arboleya <anderson@arboleya.me>

* Update apps/docs/src/guide/encoding/encode-and-decode.md

Co-authored-by: Anderson Arboleya <anderson@arboleya.me>

* Update apps/docs/src/guide/encoding/encode-and-decode.md

Co-authored-by: Anderson Arboleya <anderson@arboleya.me>

---------

Co-authored-by: Anderson Arboleya <anderson@arboleya.me>
Co-authored-by: Peter Smith <peter@blueoceancomputing.co.uk>

* Getting around non-null assertions

* Adjusting changeset

* Adjusting scripts

* Updating template fixtures/snapshots

* Triggering CI

* The branch is gone - temporarily switching to `master`

* Temporarily patching sway std lib

* Temporarily skipping problematic sway projects and related tests

* Lintfix - deprecations, types mismatch, and broken imports

* DRYing test setup/teardown

* Fixing broken tests

* Patching base library individually

* Unskipping problematic workspace members

* Adjusting predicate data handling

* Undoing undesired changed

* Adjuting more projects

* Revert "Temporarily skipping problematic sway projects and related tests"

This reverts commit dc054ff.

* Formatting

* Revert "Temporarily patching sway std lib"

This reverts commit 48b0ab3.

* Revert "Patching base library individually"

This reverts commit b97c944.

* Replacing sway `branch` by `0.63.0` version

* Update .changeset/odd-horses-cheer.md

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

* Updating forc version

---------

Co-authored-by: Peter Smith <peter@blueoceancomputing.co.uk>
Co-authored-by: Nedim Salkić <nedim.salkic@fuel.sh>
Co-authored-by: Daniel Bate <djbate23@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feat Issue is a feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Adapt ABI format to new specification
7 participants