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

fix(world): dedupe functions in getWorldAbi result #3025

Merged
merged 13 commits into from
Aug 13, 2024

Conversation

karooolis
Copy link
Contributor

@karooolis karooolis commented Aug 12, 2024

Dynamically fetched ABI from a deployed world returns user-created custom functions along with default world methods such as batchCall. However, it is not able to fetch system methods such as setField that should also be included in the final ABI for completion.

To include all system methods, the dynamically fetched ABI is concatenated with statically generated World's ABI, resulting in some duplicated functions.

deduplicateABI removes all the duplicate functions, and in case a duplicate is encountered, favors the ABI item that has named imports (i.e. statically generated World ABI), so that the ABI contains as much information as possible. In explorer case, for example, it's helpful to see the function parameter names when interacting with various functions.

@karooolis karooolis requested review from alvrs and holic as code owners August 12, 2024 13:02
Copy link

changeset-bot bot commented Aug 12, 2024

⚠️ No Changeset found

Latest commit: 520e634

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@holic
Copy link
Member

holic commented Aug 12, 2024

can you fill in the PR description about why this is important to do? Unclear if the side effects of duplicate entries (and seems intended given solidity supports overloads)

@karooolis
Copy link
Contributor Author

karooolis commented Aug 12, 2024

can you fill in the PR description about why this is important to do? Unclear if the side effects of duplicate entries (and seems intended given solidity supports overloads)

Definitely, solidity overloads should be taken into account but ABI should contain no duplicates imo. Included change description.

@holic
Copy link
Member

holic commented Aug 12, 2024

thinking about another approach where, instead of deduplicating an ABI as a whole, we just construct to the world a bit differently for our use case, starting with the base ABI (since it has named params) and add the functions registered on the world that we haven't seen yet (using function selectors as the "key" for uniqueness check, since its ultimately what is called)

const baseFunctionSelectors = IBaseWorldAbi.filter(isAbiFunction).map(toFunctionSelector);
const worldFunctionsAbi = worldFunctions
  .map((func) => functionSignatureToAbiItem(`function ${func.signature}`))
  .filter((abiItem) => !baseFunctionSelectors.includes(toFunctionSelector(abiItem)));

const worldAbi = [
  ...IBaseWorldAbi,
  ...worldFunctionsAbi,
];

@karooolis
Copy link
Contributor Author

karooolis commented Aug 12, 2024

thinking about another approach where, instead of deduplicating an ABI as a whole, we just construct to the world a bit differently for our use case, starting with the base ABI (since it has named params) and add the functions registered on the world that we haven't seen yet (using function selectors as the "key" for uniqueness check, since its ultimately what is called)

const baseFunctionSelectors = IBaseWorldAbi.filter(isAbiFunction).map(toFunctionSelector);
const worldFunctionsAbi = worldFunctions
  .map((func) => functionSignatureToAbiItem(`function ${func.signature}`))
  .filter((abiItem) => !baseFunctionSelectors.includes(toFunctionSelector(abiItem)));

const worldAbi = [
  ...IBaseWorldAbi,
  ...worldFunctionsAbi,
];

I ended up liking this approach more too, somehow feels more clean. Only renamed the function to concatBaseAbi instead of deduplicate, and added a test. Note I'm purposefully not filtering functions because I'd like to return the full ABI here including errors, events, etc. It can be filtered on the consumer-side however is needed imo.

@karooolis karooolis changed the title fix(world): deduplicated world abi fix(world): concat base ABI to getWorldAbi result Aug 13, 2024
@@ -20,7 +24,10 @@ export async function getWorldAbi({
fromBlock,
toBlock,
});
const worldFunctionsAbi = worldFunctions.map((func) => functionSignatureToAbiItem(func.signature));
const baseFunctionSelectors = (IBaseWorldAbi as Abi).filter(isAbiFunction).map(toFunctionSelector);
Copy link
Member

Choose a reason for hiding this comment

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

is as Abi casting necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Without it, even with type predicate, typescript fails to recognize in the .map(..) that it's of type AbiFunction

const baseFunctionSelectors = (IBaseWorldAbi as Abi).filter(isAbiFunction).map(toFunctionSelector);
const worldFunctionsAbi = worldFunctions
.map((func) => functionSignatureToAbiItem(func.signature))
.filter((abiItem) => !baseFunctionSelectors.includes(toFunctionSelector(abiItem as AbiFunction)));
Copy link
Member

Choose a reason for hiding this comment

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

we could prob improve the return type of functionSignatureToAbiItem so we don't have to cast this

Copy link
Contributor Author

@karooolis karooolis Aug 13, 2024

Choose a reason for hiding this comment

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

Adjusted to return AbiFunction but in order for that to work, have to ensure that it indeed returns function ABI item, otherwise the function throws. Not sure how else to handle it

packages/world/ts/common.ts Outdated Show resolved Hide resolved
@holic holic changed the title fix(world): concat base ABI to getWorldAbi result fix(world): dedupe functions in getWorldAbi result Aug 13, 2024
@karooolis karooolis merged commit 5cee9a0 into main Aug 13, 2024
14 checks passed
@karooolis karooolis deleted the kumpis/deduplicate-world-abi branch August 13, 2024 13:27
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.

2 participants