Support efficient `getField` on non-dupable datatype
Clarification and motivation
Usually getField
is implemented as mere dup; toField
, where toField
is a sequence of car
s and cdr
s. However this does not work with non-dupable datatypes.
If my datatype contains tickets, I have to do unpair; recurse OR dip recurse; pair
, and this is much less efficient.
One option is to forbid using getField
on non-dupable types.
Another option, sort of workaround, would be to represent the datatype as pair (all-dupable-types) (all-non-dupable-types)
. In this case, if we want to pick a durable field, we perform one unpair; recurseDupable; pair
, where recurseDupable
is again the efficient implementation.
Let's figure out which option do we need here.
Use cases analysis
I see two main use cases for tickets.
-
An authentication token that is attached to an entrypoint argument.
I think a good design here is to mostly always carry
(Ticket a, arg)
, and not flattenTicket a
intoarg
, because that would facilitate decoupling authorization logic. -
Ticket kept and storage that remembers amount of tokens permitted to spent.
Here we don't have much of a choice and have to assume that storage may be flattened, and
Ticket
may be just one of the fields in it.
Solution
We want to allow the user to have large datatypes with tickets, but we have to facilitate making this structure efficient.
Probably the proper way is to help the user to put all non-dupable types in his datatype separately from dupable types.
- Add a rule for
customGeneric
to handle this. - Make sure that
getField
compiles efficiently for such structures. 2.1. Ensure that it is morally hard for a user to rungetField
on a datatype where it will be inefficient.
Another probable solution would be using Edo's instructions for right-comb trees, but looks like they don't cover this case unfortunatelly.
Acceptance criteria
- It is possible to use
getField
on tickets without being afraid of accidentally generating an inefficient contract.