This is true as long as resource logics are directly circuits, but would not be true if we used an additional layer of recursion / a zkVM for resource logics, right? (in which case, we could select at runtime how many and which resources to pass in, as long as the logic is able to understand them).
Iām afraid not. Circuits are a worst-case check and donāt depend on how they are created. If Iām wrong, pls correct me.
we could select at runtime how many and which resources to pass in, as long as the logic is able to understand them
It could be possible and leads to different kinds of resource logics by passing different numbers of resources in. But it might not be one kind of resource logic that can accept variable resources.
It makes sense for ephemeral/intent resources because they can be created after the number is determined in the ptx. But for normal resources (like a Token), the logic is fixed. If the number passed to the logic changes, the Token type changes.
For now, resource logic loads all the resources and treats them equally in Taiga so that we can do forall/negative checks.
It would be an architecture modification to support the variable inputs.
I mean in the sense discussed e.g. here.
Summary of requests for clarification from @mariari:
- Need to specific what public inputs and what private inputs for resource logic proofs are.
- Need to specify how correspondence of public inputs to resource logic proofs is checked.
- Need to specify how public inputs for resource logic proofs relate to transactions which are āin progressā in the flow (i.e. not yet balanced).
- Need to work out an example of a post-ordering counter increment.
- Need to work out an example with a token swap where one of the tokens (X) requires that a counter be incremented every time it is transferred (checked with an ephemeral resource), both where the counter increment is performed pre-ordering by the solver and where it is performed post-ordering by the executor.
- Need to specify how binding signatures currently work (even if this will change).
- Need to work out example timelines (orderings of events) with more details on what the inputs are in the specific examples and who does what computation, makes what proofs, etc.
cc @vveiln
Most requests I can come up with were already in the summary from @mariari
Just a few additions:
- need to specify what statement, private inputs, and public inputs are for compliance proofs.
- need to specify how to check the correspondence of public inputs between resource logic proofs and compliance proofs
- Do we still have the sub-vp(dynamic vp) conception in RM?
- Note encryption
- VP commitments(resource logic commitments?) and functional privacy: even without functional privacy atm, we may still need a trivial vp commitment in compliance proof to enforce the specified resource logic to execute.
- more details about nullifier keys would be better(e.g., nullifier keys are needed to consume resources, but only nullifier public keys are required to create resources.)
- more details about ephemeral flag mechanism(e.g. when the flag should be true or false; a fake but existed merkle root is required when consuming a ephemeral resource)
- Is
Pi_ptx
in the examples the compliance proof?
A general question: is the Spec for an abstract and generic conception description or development documentation? Itās good enough for an abstraction. Developers may expect a very concrete and detailed
definition of parameters and protocols like the Zcash protocol.
Here are a minor thing and an actual question.
an atom is a natural number
ānatural numberāāāfield element of \mathbb{F}_hā
Could we (ab-)use .^
notation instead of SCRY or have the analogy to urbit complete?
https://docs.urbit.org/language/hoon/reference/rune/dot#-dotket
multiplication operation Z_n Ć Z_n ā Z_n Ć F_2 (with overflow indicator)
The product of two Z_n should be a Z_{n^2} (or a Z_n Ć Z_n).
Why does the preference function have to return a real? That raises a lot of uncomfortable questions for me, and I assume thereās a need for application/domain-specific sidebands to direct composition and guide solvers anyway; so why not just make it an ordering function taking two ptx and returning a tristate?
It makes sense to me to use a disjoint union to compose commitments and nullifiersāI assume thatās what prevents double-spendābut why is it necessary for proofs?
Just to take on this part of your question - a real preference function is structured in a way that we want; namely, preferences must take a consistent partial order - if pref x > pref y, and pref y > pref z, pref x > pref z. This is not necessarily true of a simple ordering function, which could rank x > y, y > z, and z > x. A real preference function is also much more conducive to mathematical analysis of e.g. structure of the preference space, degree of preferences, etc. What uncomfortable questions are raised?
Ah yes, I see.
Mainly the problem I have is that itās suggesting the existence of some policy issues early but not actually dealing with them. EG: the paper uses the example of a linear function, but maybe you would want to use a logarithmic function? And how are preference functions composed; can I make my preference function have a higher weight than somebody elseās by putting my result always in [0.9 1] rather than using the full [0 1] range? Those are questions that probably do need to be answered, but on an application/domain-specific basis, with application/domain-specific sidebands.
I was thinking: for a given ordering, we can derive lots of order-preserving functions from the domain to R (or whatever), so this increases expressiveness (since you can choose which such function to use), but not in a useful way. But youāre right the set of functions Ptx x Ptx ā 2 or 3 is also larger than the set of orderings on Ptx. So thatās not so nice. Hrm.
Need to specific what public inputs and what private inputs for resource logic proofs are
Some of that started here: VP Runtime Environment - HackMD
If expression of preference (and it having weight) is free, any self interested actor is incentivized to game it.
If some cost is tied to preferences being taken into account, systems with some robustness properties against the above can be built. The cost could be expressed in resources, or it could be requiring some amount of preexisting trust.
Could someone help elaborate the timestamp design in the CMtree? What is its purpose?
The Merkle tree and merkle path are maintained in shielded cases to prove the existence of consumed resources in compliance circuits without revealing which resources are consumed. However, for transparent resources, do we really need an explicit merkle tree structure? The existence of transparent resources can be easily checked by looking them up in the database.
I think the purpose of timestamps in Merkle tree is to optimize storage. If there is a timestamp associated with each node, and there is an expiration date set, the nodes of a full subtree (that will never be modified) are deleted by the storage after the expiration date. In case it happens, the clients will be responsible for storing the subpath of the subtree themselves if they ever want to create proofs for commitments stored in that subtree.
Here is the thread where it was initially discussed: Stored data format: resource machine <> storage
Iām not sure how storage policies work in the shielded case though, perhaps, @isheff has some idea.
The reason we have an explicit Merkle tree structure for resources in the transparent case (and anything else that seems inconvenient from the transparent perspective) is that transparent resource machine implementation implements a resource machine specification that is a shared interface that has to apply to both transparent and shielded systems (and anything in between) in a way that a shielded system is not underspecified, so that resource machine implementations can interoperate regardless of their privacy properties
The spec specifies that any implementation must work with resource commitments stored in a cryptographic accumulator, and we can produce proofs of inclusion for them. It also currently describes the use of Merkle trees as the accumulator of choice, but they can be abstracted away if needed. If you donāt want to use Merkle trees in the transparent system, you can either:
- find another way to satisfy the spec, potentially using another kind of accumulator (it doesnāt have to be exactly like in taiga as long as it still satisfies the spec)
- suggest another design for accounting and storing commitments that suits better the transparent system and doesnāt break (or keep underspecified) the shielded implementation that implements the proposed design
So we donāt need to care about the timestamps inside of RM, right? The storage engine would maintain the timestamps.
The Merkle tree is a simple structure and can be easily used in transparent systems as well. I want to discuss if we need a cryptographic accumulator for transparent commitments in our system. The cryptographic accumulator is used to prove the existence of resources without exposing them, but since we donāt need to conceal transparent resources when checking them, we can simply store transparent commitments in a modern database and look them up when needed. Do we still need to maintain an extra accumulator?
Yeah, rm doesnāt care about timestamps
Here is my perspective (it might be wrong, and if so, please correct me @cwgoes):
- We almost exclusively talk about transparent and shielded instantiations, but privacy is assumed to be configurable. The reason we talk about the two is that they are the edge cases, and if they work, the other flavours should work too. But they are not implied to be the only ways
- Right now we are the only developers of the rm instantiations, but it wonāt necesarily be true in the future. We have to make sure the spec specifies necessary and sufficient interface to implement a resource machine of either privacy flavour. Whatever we donāt define in the spec we cannot assume
- We want all instantiations to have a unified interface. We want privacy to be configured on the instantiation level, which confusingly requires ensuring the structures we define work for shielded instantiations specifically
Is it important to ensure there is always a way to verify resourceās existence, no matter how much privacy is provided? I would guess so. Then we have to describe a way in the spec that would be sufficient for all flavours and the shielded one in particular. It doesnāt have to be Merkle tree specifically, but it has to work for all cases
I understand our desire for a unified interface and abstract definition. For any rm instantiations, the basic requirement(or the interface we need) is to verify resourceās existence. The Merkle tree is one of solutions, which is commonly used in shielded RMs. But the Specs explicitly specifies the Merkle tree to be used in all RMs. So It makes sense that @ray uses the Merkle tree for transparent commitments in the current Anoma implementation according to the Specs. However, it may not be the best option for transparent RMs IMP.
I wanted to discuss if the Merkle tree is a mandatory structure to store commitments. If not, we could provide explanations in the Specs to allow for flexibility in different situations.
If we talk about the current state of the spec, it is mandatory to use Merkle trees to store commitments. But we can change the spec to describe some other mandatory approach that would work better
Awesome, I believe we understand each other now
Iām suggesting abstracting it as an interface (e.g. for resource existence check) instead of specifying the concrete merkle tree/path approach, if that makes sense.
As you described in Specs, the ARM leverages commitment accumulators to ensure transaction privacy. For transparent transactions, I think we can simply check the resourceās existence in storage instead of using an accumulator. The approach can be further discussed to verify its feasibility.
Iām not saying merkle tree doesnāt work for transparent commitments. I just have some feedback while reviewing code and specs. If we use the path and root to check resourceās existence as in shielded cases, we have to provide a path(32(depth) * 32Bytes(one node) = 1KB) in plaintext for each resource in the transaction, which is awful. @ray told me we wonāt use the path and root to check transparent resource, but use some complex timestamps instead, which I didnāt fully understand atm. Iām thinking we probably can use the position. The root terminology in transactions may no longer be precise, even when we use Merkle tree for transparent commitments.