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: replace ethers abi coder with ours #6385

Merged
merged 16 commits into from
Sep 28, 2023
Merged

feat: replace ethers abi coder with ours #6385

merged 16 commits into from
Sep 28, 2023

Conversation

mpetrunic
Copy link
Contributor

@mpetrunic mpetrunic commented Aug 28, 2023

Description

Fresh abi code implementation to replace ethers implementation. Should be checked but afaik it adds abilities to encode/decode dynamic array and tuples with dynamic children.
There are probably bugs lurking so I would suggest to add more tests.

P.S. Improved build with concurrently because using '&' means previous scripts are run in the background so there can be concurrency issues with packages that depend on build causing weird type errors from time to time.

resolves #6270 #6211 #6269

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

TODO

Checklist:

  • I have selected the correct base branch.
  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have made corresponding changes to the documentation.
  • My changes generate no new warnings.
  • Any dependent changes have been merged and published in downstream modules.
  • I ran npm run lint with success and extended the tests and types if necessary.
  • I ran npm run test:unit with success.
  • I ran npm run test:coverage and my test cases cover all the lines and branches of the added code.
  • I ran npm run build and tested dist/web3.min.js in a browser.
  • I have tested my code on the live network.
  • I have checked the Deploy Preview and it looks correct.
  • I have updated the CHANGELOG.md file in the root folder.
  • I have linked Issue(s) with this PR in "Linked Issues" menu.

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Aug 28, 2023

Deploying with  Cloudflare Pages  Cloudflare Pages

Latest commit: 305391c
Status: ✅  Deploy successful!
Preview URL: https://e9ee390d.web3-js-docs.pages.dev
Branch Preview URL: https://feat-web3-abi-coder.web3-js-docs.pages.dev

View logs

@github-actions
Copy link

github-actions bot commented Aug 28, 2023

Bundle Stats

Hey there, this message comes from a github action that helps you and reviewers to understand how these changes affect the size of this project's bundle.

As this PR is updated, I'll keep you updated on how the bundle size is impacted.

Total

Asset Old size New size Diff Diff %
Total 657 KB 581 KB -75.5 KB -11.50%
View detailed bundle breakdown

Added

No assets were added

Removed

No assets were removed

Bigger

No assets were bigger

Smaller

Asset Old size New size Diff Diff %
web3.min.js 640 KB 564 KB -75.5 KB -11.81%

Unchanged

Asset Old size New size Diff Diff %
../lib/commonjs/index.d.ts 8.56 KB 8.56 KB 0 0.00%
../lib/commonjs/accounts.d.ts 3.67 KB 3.67 KB 0 0.00%
../lib/commonjs/types.d.ts 2.45 KB 2.45 KB 0 0.00%
../lib/commonjs/web3.d.ts 1.14 KB 1.14 KB 0 0.00%
../lib/commonjs/abi.d.ts 1000 bytes 1000 bytes 0 0.00%
../lib/commonjs/eth.exports.d.ts 280 bytes 280 bytes 0 0.00%
../lib/commonjs/providers.exports.d.ts 148 bytes 148 bytes 0 0.00%
../lib/commonjs/version.d.ts 60 bytes 60 bytes 0 0.00%

@codecov
Copy link

codecov bot commented Aug 28, 2023

Codecov Report

Merging #6385 (305391c) into 4.x (b8fa712) will decrease coverage by 0.50%.
The diff coverage is 91.84%.

Additional details and impacted files
@@            Coverage Diff             @@
##              4.x    #6385      +/-   ##
==========================================
- Coverage   89.88%   89.39%   -0.50%     
==========================================
  Files         201      212      +11     
  Lines        7780     8135     +355     
  Branches     2128     2212      +84     
==========================================
+ Hits         6993     7272     +279     
- Misses        787      863      +76     
Flag Coverage Δ
UnitTests 89.39% <91.84%> (-0.50%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
web3 ∅ <ø> (∅)
web3-core ∅ <ø> (∅)
web3-errors ∅ <ø> (∅)
web3-eth ∅ <ø> (∅)
web3-eth-abi ∅ <ø> (∅)
web3-eth-accounts ∅ <ø> (∅)
web3-eth-contract ∅ <ø> (∅)
web3-eth-ens ∅ <ø> (∅)
web3-eth-iban ∅ <ø> (∅)
web3-eth-personal ∅ <ø> (∅)
web3-net ∅ <ø> (∅)
web3-providers-http ∅ <ø> (∅)
web3-providers-ipc ∅ <ø> (∅)
web3-providers-ws ∅ <ø> (∅)
web3-rpc-methods ∅ <ø> (∅)
web3-utils ∅ <ø> (∅)
web3-validator ∅ <ø> (∅)

Signed-off-by: Marin Petrunic <[email protected]>
}
return {
result: numberResult,
encoded: bytes.subarray(WORD_SIZE),
Copy link
Contributor

Choose a reason for hiding this comment

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

subarray creates a new view on existing buffer, and changes on new obj will impact original and vice versa. so I think a copy should be made of bytes with required data and sent back from this function.

Copy link
Contributor

Choose a reason for hiding this comment

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

same for other places of code in this PR

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That was the goal as it will reduce memory and performance impact. And there is no fear here since decoders never modify any bytes. Better option would be to find a way to freeze internal array buffer but I do not know a way to do it.

Copy link
Contributor

Choose a reason for hiding this comment

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

ok, Its tradeoff between memory+performance vs safety( so data is not corrupted by maintainers misuse of it).

I'll also lean towards UX as compared to maintainers. btw I like this approach of using uint8arry / buffers instead of padding using high level functions, its great.

Signed-off-by: Marin Petrunic <[email protected]>
Signed-off-by: Marin Petrunic <[email protected]>
Signed-off-by: Marin Petrunic <[email protected]>
Copy link
Contributor

@avkos avkos left a comment

Choose a reason for hiding this comment

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

The size was decreased a lot - that's amazing!
But coverage was also decreased.
I think having as many as possible tests of new functionality will be great. Do you consider an option to copy test cases from the open-source project?

packages/web3-eth-abi/src/api/parameters_api.ts Outdated Show resolved Hide resolved
@mpetrunic
Copy link
Contributor Author

mpetrunic commented Sep 7, 2023

But coverage was also decreased. I think having as many as possible tests of new functionality will be great.

Diff coverage is actually >90%. I assume total coverage decreased as we used a library before so that code had "100%" coverage^^

Do you consider an option to copy test cases from the open-source project?

I mentioned that in PR description as todo. That said, I noticed ethers test cases uses human readable abi and I do think we will hit a lot of cases where abitype is not really parsing them well (afaik they are not standardized).

We could use https://github.com/wagmi-dev/viem/blob/main/src/_test/abis.ts instead^^

Copy link
Contributor

@Muhammad-Altabba Muhammad-Altabba left a comment

Choose a reason for hiding this comment

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

Thanks for your great contributions!

However, I have a special concern regarding the breaking change that would be introduced with the new errors (mentioned here). Or, what do you think?

const dynamic = size === -1;
const dynamicItems = encodedParams.length > 0 && encodedParams[0].dynamic;
if (!dynamic && values.length !== size) {
throw new AbiError("Given arguments count doesn't match array length", {
Copy link
Contributor

Choose a reason for hiding this comment

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

Errors here and everywhere else in the MR seems to inturduce breaking changes, right?
Are we planning on upgreading the major version after this MR? Or else we need to keep the errors as they where, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What do you mean? its the same error instance as before. Adding new error messages is not a breaking chnage

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this is not just a new error message. The code used to throw an error for this case, and for others, but with a different message and a different structure, right?
The old message was according to the old deleted code:
throw new AbiError(`Parameter encoding error`, err as Error); And the innerError was the error object we get from the encoder.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Code still throws AbiError error and our api doesn't guarantee inner error type will stay the same (It will be of type Error | Error[] if present). It's user's fault if he expected something that typescript types did not guarantee.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks @mpetrunic,
Yes, it is not guaranteed by typescript types here. But still the user can even use JavaScript which has no types. I am thinking here about the actual strings and values that the user used to get and might already has ifs checks on. And if we think it is the user's fault to depend on types we did not specify, changing them is still considered a breaking change, as far as I know.

So, as far as I know, if we do not maintain to provide the exact message string and the exact internal properties for every error, as we used to, then we are introducing a breaking change. And yes we can add more properties to the error object. But we are not supposed to remove or update the string or a property value, without pumping the major version.

And yes, our API has been used to guarantee the same message and properties's values for the innerError message because the early used library is following semver.

And I think keeping the error messages and properties, as they were, is possible even though it might be a bit tricky.

Please correct me if changing an error message, or a value of an internal property inside an error object, is not considered a breaking change.

Thanks,

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Afaik, error messages are implementation details intended for the developer's eyes. No one should rely on their exact content or even worse make an if/else statement based on their content (fixing a typo in an error message would then be a breaking change). If the developer intended for you to handle those errors, errors would either be different instances or contain error codes along with the list of error codes the function might throw.

packages/web3-eth-abi/src/coders/base/bool.ts Show resolved Hide resolved
Signed-off-by: Marin Petrunic <[email protected]>
Copy link
Contributor

@jdevcs jdevcs left a comment

Choose a reason for hiding this comment

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

As discussed, if loosedecoding is enabled it skips checking strict padding rules, due to some old solidity versions bug for event data emitted from external functions.
we are not using loosedecoding feature by passing false, so we can skip this feature in this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Rollout own ABI coder: implement complex encoders
4 participants