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

ARC-51: Method Reference Discovery #230

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

joe-p
Copy link
Contributor

@joe-p joe-p commented Jul 28, 2023

This ARC proposes a way to discover references required for a method. Eventually this will be superceeded by simulation endpoint's unnamed resources functionality, but it serves as a viable intermediate solution for ARCs like ARC200 (#223) and ARC72 (#147)

@joe-p
Copy link
Contributor Author

joe-p commented Jul 28, 2023

I think a similar approach could be used for fee and MBR discoverability as well, but I think that should be a separate ARC since the reference discoverability will eventually be provided algod.

@jannotti
Copy link
Contributor

jannotti commented Jul 28, 2023

This is great. I think you might consider a couple additions.

Report information on box sizes so that callers can know whether they need to pack extra box refs for quota. You might also want to report whether a box is being read or written, as that can matter.

Report "cross-product" requirements separately. With resource sharing coming into play, there's a difference between needing account A and asset X, vs needing holding AxX, as the caller could put A and X in separate transactions.

Report on payment expectations. If the contract will only work if the caller gives it some extra algos for MBR, it would be nice to report that. I don't think it's worth the complexity of coming up with some scheme where the discovery call explains where the payment has to go - I would say this is only for contracts that don't care about that, they aren't explicitly looking for the algo payment, they just won't work if they don't have enough balance.

Consider reporting each requirement as log statement, as it will be more extensible. Each such requirement might be something like <type byte> || <requirement data> so that, for example, you get 0x01 <asset id>, 0x01 <another asset>, 0x2 <app id> etc.

@joe-p
Copy link
Contributor Author

joe-p commented Jul 28, 2023

Report information on box sizes so that callers can know whether they need to pack extra box refs for quota.

I was thinking it'd just return the total number of references needed, but if the parameter for the read/write allocation per reference were to ever change we'd need to supply the total size. And the latter is more space efficient. So the value indicating box refs will be a (uint64,byte[],uint8) for appID, key, and size.

You might also want to report whether a box is being read or written, as that can matter.

How does this affect references?

Report "cross-product" requirements separately. With resource sharing coming into play, there's a difference between needing account A and asset X, vs needing holding AxX, as the caller could put A and X in separate transactions.

Ah yes didn't think about this. This would definitely be valuable to add.

Report on payment expectations. If the contract will only work if the caller gives it some extra algos for MBR, it would be nice to report that. I don't think it's worth the complexity of coming up with some scheme where the discovery call explains where the payment has to go - I would say this is only for contracts that don't care about that, they aren't explicitly looking for the algo payment, they just won't work if they don't have enough balance.

Yeah I think the simplest implementation is simply report the total amount of ALGO the contract expects to receive. This includes MBR but could also be other necessary expenses (for example, the contract needs to pay some other account). This alone is only useful is certain contexts, but if we go with your logging idea it could be expanded in the future

Consider reporting each requirement as log statement, as it will be more extensible. Each such requirement might be something like || so that, for example, you get 0x01 , 0x01 , 0x2 etc.

Love this approach. Makes it easier to add future information as well if we wanted to without affecting the method signature.

@jannotti
Copy link
Contributor

jannotti commented Jul 28, 2023

You might also want to report whether a box is being read or written, as that can matter.

How does this affect references?

Suppose you intend to create a box named X of size 5k. You also intend to read a box named Y, of size 4k (but not modify it). You only need 5 box refs, one for X, one for Y, and three empties to increase your read/write budget from 2k up to 5k.

But if you were writing to Y, you'd need 7 empties, as you'd need a 9k write budget.

@jannotti
Copy link
Contributor

jannotti commented Jul 28, 2023

Consider reporting each requirement as log statement, as it will be more extensible. Each such requirement might be something like || so that, for example, you get 0x01 , 0x01 , 0x2 etc.

Love this approach. Makes it easier to add future information as well if we wanted to without affecting the method signature.

If you go this way, I'd avoid arcXXX_ in the prefix. Instead, something generic like "explain_", as the prefix. ARCs in the future might simply add a new thing a method can report. The new tag byte would be defined in a new arc, and I wouldn't want to imply they should create a new arcYYY_method() to convey it.

Oh, perhaps the better way to describe this log mechanism is by describing it with the event mechanism. So that there is a clear way to encode structure.

## Specification
If an application has a method and the contract wants to make the required resources for calling the method discoverable, it **MUST** implement a readonly method with the same exact signature with an `arcXXXX_` prefix and a return type of `(address[],uint64[],uint64[],(uint64,byte[]))`.

The return value corresponds to arrays containing the required account, application, asset, and box references respectively.
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be nice to provide clarity in the case of a method which takes reference type arguments.

I.e. does its arcXXXX_ function need to return the already specified reference types, or can it omit them?


### ARC200 example

In this example, let's say `arc200_totalSupply()uint256` requires two box refences `"baseSupply"` and `"supplyMultiplier"`, each encoded as `byte[]`.
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: it would be nice to show an example with arguments to reenforce the restriction that the arcXXXX_ must be declared with the same set of arguments.

@jasonpaulos
Copy link
Contributor

jasonpaulos commented Jul 28, 2023

+1 to the event mechanism idea. ARC-28 already defines how events can work

@pbennett
Copy link
Contributor

When contract A needs to call contract B as part of its implementation, would the expectation be that A hard-codes B's requirements as part of what it returns for this discovery method?
Ideally, it would get B's requirements and add them to its own, but if it requires A to 'parse an ARC28' message then I think that might get awkward (or at least make sure it's part of delivered tooling for developers to use in pyteal, etc.)

@SudoWeezy SudoWeezy changed the title ARCXXXX: Method Reference Discovery ARC-51: Method Reference Discovery Jul 31, 2023
@joe-p
Copy link
Contributor Author

joe-p commented Aug 7, 2023

When contract A needs to call contract B as part of its implementation, would the expectation be that A hard-codes B's requirements as part of what it returns for this discovery method?

The contract can handle this however it sees fit. Could be hard-coded or could use the requirements_ method of the inner app if implemented.

Ideally, it would get B's requirements and add them to its own, but if it requires A to 'parse an ARC28' message then I think that might get awkward (or at least make sure it's part of delivered tooling for developers to use in pyteal, etc.)

The latest version uses the event specification, so if languages support events then it will trivial to parse the events. To be fair, I don't believe events are supported by PyTeal right now

@emg110
Copy link

emg110 commented Oct 1, 2023

When this ARC would be living standard? It's a great ARC proposal!

@joe-p joe-p marked this pull request as draft March 14, 2024 15:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants