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

CIP-0118? | Validation zones #780

Closed

Conversation

michaelpj
Copy link
Contributor

@michaelpj michaelpj commented Mar 11, 2024

This is a possible answer to part of #779, references to "CIP-????" in the doc refer to that CIP.

This design came out of the work on Babel Fees, but has wider applications. This is partly scoped out in the CPS, in this CIP we point to what parts of that we think we can address.


Rendered on author's fork

@Quantumplation
Copy link
Contributor

This is great, I love this evolution of the liabilities stuff.

My only comment after my first read through is that it's not clear how datums, redeemers, or reference scripts interact with these features.

for example, when specifying an UTXI, do I specify the value, datum, and redeemer? It would be useful to be able to leave the datum and/or redeemer unspecified and let the resolver provide that. For example, perhaps the datum needed by the script is dependent on the user doing the redemption, etc.

Similarly, perhaps there are use cases where the UTXI should specify only the datum / credential they want to see witness from, and let the resolver specify something akin to a "collateral return".

I don't have super concrete examples right now, but understanding how you envisioned the datum and redeemer interacting with this would be helpful in clarifying my own thoughts.

@michaelpj
Copy link
Contributor Author

for example, when specifying an UTXI, do I specify the value, datum, and redeemer?

Yes, this should have been clearer, sorry! The idea is that a UTXI is the bit that is locked, and it is locked just like a normal output, so it has the value and datum on it. The resolving output is like a normal input and so specifies the redeemer.

This is a bit strange, but I think it's the right way around. This part makes more sense in the "negative outputs" view!

It would be useful to be able to leave the datum and/or redeemer unspecified and let the resolver provide that. For example, perhaps the datum needed by the script is dependent on the user doing the redemption, etc.

The resolver provides the redeemer.

Again, the idea is that the locking is just perfectly the same as how it works for outputs. This proposal does not try to incorporate any of the ideas about leaving datums etc. unspecified... I don't know how to do that at the moment!

@Quantumplation
Copy link
Contributor

Ok that makes some sense; It's a bit hard to think about, so I'll meditate on it for a bit.

CIP-????/README.md Outdated Show resolved Hide resolved
CIP-????/README.md Outdated Show resolved Hide resolved
CIP-????/README.md Outdated Show resolved Hide resolved
### Unresolved inputs and resolving outputs

We add a new kind of transaction input, an “unresolved input” (UTXI).
An unresolved input differs from a normal transaction input:
Copy link

@polinavino polinavino Mar 12, 2024

Choose a reason for hiding this comment

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

the key property of it is that it looks exactly like an output! It basically will be in the Agda model a specially-marked output (and it will be matched with a specially-marked input in a valid zone)

Copy link

@polinavino polinavino Mar 12, 2024

Choose a reason for hiding this comment

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

I still find the UTXI terminology pretty confusing (also the name sounds weird). It sounds like @Quantumplation was also confused by this? I am still in favour of something like "negative outputs", but done better, instead :

The UTxO stored in the ledger state will still be UTxO, but inside the validation zone, we will instead have UTxOZone , and backwards TxIns are matched with backwards TxOuts

  IsBackwards = Bool
  TxIn     = TxId × Ix
  TxInZone     = TxIn × IsBackwards
  TxOut    = Addr × Value × Maybe DataHash
  TxOutZone = TxOut × IsBackwards
  UTxO     = TxIn ⇀ TxOut
  UTxOZone     = TxInZone ⇀ TxOutZone```

Copy link
Contributor

@Quantumplation Quantumplation Mar 12, 2024

Choose a reason for hiding this comment

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

How about required input / satisfying output? Once I started using that terminology in my head it clicked for me.

(Some other ideas: requested inputs; unsatisfied inputs; missing input)

Copy link

@polinavino polinavino Mar 12, 2024

Choose a reason for hiding this comment

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

I talked to Andre at the formal ledger meeting today, and he said that it is always best to put any new features into entirely new transaction fields. So, the transaction would have two new fields, one for required Inputs (or other name?), and one for the satisfying outputs. I think the required inputs and satisfying outputs will have the same type as outputs and inputs, respectively.

Then we have UTxOZone = UTxO x BackwardsUTxO or something like that, and the second component needs to be empty (an empty UTxO map?) for a zone to be valid

Choose a reason for hiding this comment

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

"requested" and "required" both work i think

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, very open to other names. I liked "unresolved" because then we have UTXI which looks like UTXO 😁 A good name will go a long way towards making this easy to understand!

the key property of it is that it looks exactly like an output! It basically will be in the Agda model a specially-marked output

I discuss this in the doc a bit, but I think we are on the horns of a dilemma:

  1. Either we have "outputs" that are weird (negative value) and therefore behave a lot like inputs; or
  2. We have "inputs" that are weird (they have spending guards) and therefore behave a lot like outputs.

I think that it's less weird to think that there might be things other than outputs that need spending guards (although it's a new idea!). I also think the cost of the weirdness in case 1 is greater, because it forces all local reasoning about the transaction (e.g. scripts) to deal with negative quantities, which will be a pain for everyone. Case 2 is just a pain for the ledger 😂

Copy link

@polinavino polinavino Mar 13, 2024

Choose a reason for hiding this comment

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

I am open to calling either weird thing without using the input/output terminology, but i hope there is some agreement on the structure of the types, ie. two new fields in Tx, one has an address (possibly only a spending address), value, and datum, and the other has a TxId and an Ix.

CIP-????/README.md Outdated Show resolved Hide resolved
CIP-????/README.md Outdated Show resolved Hide resolved
CIP-????/README.md Outdated Show resolved Hide resolved
### Design

#### Linearizability and value flow

Copy link

@polinavino polinavino Mar 12, 2024

Choose a reason for hiding this comment

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

I know what you are saying here, but if i didnt, something like the following might sound more clear to me :
Linearizability means that all "borrowed" or "backwards-dependent" assets are backed by assets that already exist on chain, and are provided by one of the transactions in the zone.

However, this presents us with a problem: we cannot resolve both the input and the output in one transaction, because this would violate linearizability.
The same transaction cannot appear both earlier and later in the value flow!

We can solve this problem with atomic (indivisible) transaction groups: then we can use two transactions, one earlier and one later, but bind them together so that they cannot be split apart.

Choose a reason for hiding this comment

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

Point out here that usually such indivisible transaction sets would come from a single user, who can sign them all without the need for additional communication


In contrast, if the value flow can be linearized then we know that nothing fundamentally new is possible here and we do not need to worry.

#### Counterparty irrelevance

Choose a reason for hiding this comment

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

I think we should also emphasize in this section the fact that two-way communication is not required

CIP-????/README.md Outdated Show resolved Hide resolved
#### A better design

It may be that the best way to implement intents on Cardano is different from the approach we are taking (transactions which leave more details unspecified).
In that case such a design might entirely obsolete this one, making it an expensive and pointless burden to maintain in future.
Copy link

@polinavino polinavino Mar 12, 2024

Choose a reason for hiding this comment

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

For sure! But one thing we can consider to try to make the current design more compatible with more expressive intents in the future is replacing the IsBackwards tag of TxOutZone and TxInZone with some other more expressive metadata that specifies what sort of intent this is. For example, if we want an unspecified datum, MissingDatum could be the tag on an output. Not sure how another transaction can then fill it in, but just brainstorming here.

@Quantumplation
Copy link
Contributor

Thinking about CIP 112, would it make sense to also consider required_zone_observers and let there be a type of script that can validate the whole zone at once?

@polinavino
Copy link

Thinking about CIP 112, would it make sense to also consider required_zone_observers and let there be a type of script that can validate the whole zone at once?

That might be nice in the future, but is a bigger change than the ones outlined here. For example, we would need to give more thought to who pays for running this script, and how collateral works.

@fallen-icarus
Copy link

I've read this a few times to try to understand it. AFAIU satisfying unresolved inputs is an all or nothing action since they declare the exact value that the resolving output needs to satsify. There is no way to partially fulfill an unresolved input using a resolving output (ie, satisfying an unresolved input can be done with n resolving outputs). Is this understanding correct?

I am specifically thinking about how limit orders can be partially filled. If Alice creates a limit order that is offering 1000 ADA, Bob doesn't need to take the entire amount. He can take 100 ADA and leave the remaining 900 ADA for someone else. I don't think the atomic swap and dex aggregator use cases are that compelling without partial filling. Can you use scripts to allow partial filling by evolving the unresolved input into new (partially filled) unresolved input? If yes, why would this be better than just using the current approach of spending a normal input that returns required change (enforced by a script)? Right now, batchers accumulate orders before processing them all at once. Even in the limit order example, the batcher can accumulate 10 orders to satisfy the single limit order. If the batchers did this through a validation zone, wouldn't this required them to 1) spend all ten orders to create a single output, and then 2) match that output against Alice's unresolved limit order input? This seems like it just adds an unnecessary extra transaction. I don't personally use batchers in my design, but I don't see how these validation zones materially help. @Quantumplation If you are willing to share trade secrets 😄, do you have some ideas on how it could help?

If my understanding is correct, the only real use cases I see involve those where the "liabilities owed" match exactly those paid (eg, paying a bill). Having to match the value of the unresolved input exactly seems like a pretty big limitation.

@rphair rphair added the Category: Ledger Proposals belonging to the 'Ledger' category. label Mar 12, 2024
@rphair
Copy link
Collaborator

rphair commented Mar 12, 2024

@michaelpj I've added this to the CIP meeting agenda in 1 week (https://hackmd.io/@cip-editors/84) to which I think you've already been invited because of our Plutus theme. It would be good if you could be there to introduce this idea to the dev community as well, and hopefully @Quantumplation @fallen-icarus @polinavino you can also be there.

@Quantumplation
Copy link
Contributor

@fallen-icarus I may be giving up state secrets / alpha by sharing this, but you'd probably figure it out eventually, and this is likely a long way off so I don't think me withholding it would materially effect your ability to deliver before us or anything like that, so happy to share for the betterment of all :)

Think of it this way: you build a transaction that specifies "i just have an input with exactly this value and datum, but I don't care about the specific TxHash and output index". Then, if someone "slips in" before you and spends the UTXO you were "aiming for", in theory it wouldn't invalidate your signature, because the txhash would change but your requirement wouldn't.

Using this directly with the existing designs we have has a number of problems for exactly the reason you pointed out: you have to exactly match the input/output, and if the person who "slipped in" before you used up some of the value on the UTXO, or changed the datum, then the UTXO might as well have been spent.

But, you can solve this by also having the counter party slip in their transaction as an adapter.

Imagine you have a 5m ADA / 10M RBERRY UTXO that is used for liquidity, and people want to swap against it. (everything also applies if it's just one side of the pair at a specific listing price, like an order book, i'm just more familiar with pairs for analogies).

And imagine that 10 people want to swap against it, so they build transactions that take in that UTXO, with it's 5m ADA and 10m RBERRY, and each give and take according to the AMM, and return the surplus back to the pool.

This is doomed to fail, even with this CIP, because they're all specifying that they need all 5m ADA and 10m RBERRY, even though they are sending most of it back.

However, if they instead say "i am willing to give up 50 ADA, provided I get 100 RBERRY" (concretely: an unresolved input with 100 rberry, and an output of 50 ADA locked by some permissive script, such as one that lets it get folded back into the pool)

then all 10 people can build that transaction, and the batcher can build two transactions:

  • one that spends the major UTXO to "pull off" the appropriate chunks for all orders, i.e. with 10 outputs each directed towards one of the unresolved inputs
  • one that spends the result of each swap back "into" the pool
  • the script holding the major UTXO is only "content" to let pieces get torn off if it sees that it is going to an output locked by a script that it knows will ensure that the result of the swap makes its way back to the pool
    • (This is why I think extending CIP-112 to include observers for the whole validation zone would be good, because it becomes simpler to enforce this constraint; I can defer to a script that can look at the whole validation zone at once, perhaps with the collateral being paid by the person creating the validation zone itself, rather than any of the individual parties)

This is materially better than the current state of the art because:

  • The user knows the swap will be atomic; they don't need to let tokens leave their wallet into an escrow script to maybe be executed by a batcher
  • The circle of people who know about the users order (and can thus front-run it) is limited to the batchers they choose to share it with, rather than being broadcast for all ahead of time
  • A user is always free to sit there retrying and resigning if they don't want to trust a batcher
  • And it solves the contention over large/popular/cheap UTXOs that I believe current order book designs face

My big remaining concern about order book designs is that, in my opinion, they struggle with fairness. On a centralized exchange, if someone places a limit offer that is lower than many of the existing limit bids, I believe, legally, the order is required to match against the best prices available first, marching down the order book; This is also enforced nationally through the NBBO (national best bid offer). On an order book DEX, they get no guarantee that they'll get matched with the best price; there is then an incentive to censor the list of open orders, and then batch the users order at the most unfavorable price, pocketing the difference. I don't think that is happening on any of the existing order books, but it is an attack vector that I worry about, and in my mind, the AMM serves the role of an NBBO for fairness.

@Quantumplation
Copy link
Contributor

@michaelpj How does this CIP interface with reference inputs? collateral inputs? collateral outputs? (I assume "not at all" for the latter two at least, but I didn't see it explicitly mentioned in the CIP)

@colll78
Copy link
Contributor

colll78 commented Mar 12, 2024

This is extremely promising. It would enable a huge number of new contention-less design patterns.

@fallen-icarus
Copy link

fallen-icarus commented Mar 12, 2024

happy to share for the betterment of all :)

@Quantumplation I appreciate the quick and detailed reply, and I resonate with the sentiment for sharing! I think these public debates only help in the long run.

What follows is basically just me thinking out loud (as I'm sure you are since unresolved inputs are new). For starters, at a high-level, what you are describing just sounds like composing an order-book with an AMM which is already possible for cheaper than what is being described here.

However, if they instead say "i am willing to give up 50 ADA, provided I get 100 RBERRY" (concretely: an unresolved input with 100 rberry, and an output of 50 ADA locked by some permissive script, such as one that lets it get folded back into the pool)

This is literally a limit order with an implied price of 1 ADA : 2 RBERRY. So what you are describing is to have end users create an order-book using unresolved inputs that can then be composed with an AMM liquidity pool. The AMM is, unsurprisingly, acting as a market maker for these limit orders. But I see some problems with your described approach.

  • The circle of people who know about the users order (and can thus front-run it) is limited to the batchers they choose to share it with, rather than being broadcast for all ahead of time

MEV impacts order-books and AMMs differently. The TLDR is that MEV benefits end-users but hurts batchers on order-books while it hurts end-users but benefits batchers on AMMs. Take two examples, one order-book and one AMM. If Alice creates a limit order for 50 ADA for 100 RBERRY, does she care who satisfies it? If Mike (a batcher) front-runs Bob (another batcher), in order to profit, why would Alice care? She gets her 100 RBERRY either way. In fact, she benefited from the MEV because Mike and Bob competing resulted in her limit order being processed faster. On the flip side, consider an AMM where Alice wants to swap 50 ADA for some RBERRY; Alice has no control over the price since it is set by the AMM. Mike (still a batcher) can front-run Alice by submitting his order before hers so that price gets pushed up, then processing hers which pushes the price up further, and then finally submitting another order himself to sell which allows him to claim the spread he artificially created. If Alice whitelists batchers (like only allowing Bob) there is now less urgency for Alice's order to be fulfilled which means her order will statistically be processed slower than in the order-book example. This relationship should be factored in to the debate of whether order-books are more/less fair than AMMs. It should also be noted that end-users vastly outnumber batchers so shouldn't the system favor end-users? TBH I think this should also be factored into the debate for whether MEV is always bad.

As the examples above show, Alice has zero incentive to hide the limit order and, in fact, she is actually incentivized to broadcast it to everyone since it will statistically get satisfied faster. Limit orders have zero slippage so there is zero risk for Alice to do this. Alice will want batchers to compete for her limit order.

  • And it solves the contention over large/popular/cheap UTXOs that I believe current order book designs face

Contention problem for whom? Like the order book example above, Alice is not competing for the UTxO. She is incentivizing the batchers to compete on her behalf. I explained it in detail in my DEX's README (section here). My DEX even supports an intrinsic fee market, even without Cardano's tiered pricing, to further incentive batchers to compete to fill her order more quickly. Because of the fee market, end users never have to compete for limit orders, but they still can if they want to.

  • The user knows the swap will be atomic; they don't need to let tokens leave their wallet into an escrow script to maybe be executed by a batcher

If end-users actually do want to broadcast their limit orders to all batchers, how can you do this if the unresolved input is located at a pubkey credential? I came up with beacon tokens for this use case but it still required the input to be locked at a script credential so that the beacons can never be found in the wrong locations. Though, users never give up custody or delegation control so my approach isn't the same as using an escrow script. If you don't use beacon tokens, you now need another trust-less method to broadcast the orders.

there is then an incentive to censor the list of open orders,

This is not possible. Beacon tokens cannot be censored. If you have a copy of the current UTxO set, you have the entire order-book just a query away (just filter UTxOs by those with the beacon token). Again, if you don't use beacon tokens because the end-users order are just protected by a pubkey, you now need another way to broadcast the orders that has the same security and availability as beacon tokens.

To close, I want to stress that what you describe is all already possible by just composing an order-book DEX, like my cardano-swaps, with an AMM DEX, like sundaeswap. Except, since there are no extra transactions dedicated to just creating and satisfying unresolved inputs, there is less overhead with the current approach. And I want to double stress that, when it comes to limit orders, end-users are actually incentivized to broadcast them to everyone, not hide them.

My big remaining concern about order book designs is that, in my opinion, they struggle with fairness...

My philosophical belief is that users should have both. In fact, my idealized DeFi future is exactly the AMMs composing with an order-book DEX. The order book can be used by people who prioritize risk-management while AMMs can be used by people that prioritize "best price". A true market has both. Personally, I think most liquidity will gravitate towards order-books because I believe most people are risk-averse.

EDIT: I originally wrote this from the perspective that unresolved inputs exist on-chain similar to normal inputs but after reading the CIP again, unresolved inputs seem to only exists in transactions. When the validation zone is fully processed, there can be no unresolved inputs. I actually think this strengthens my argument since trust-less discoverability of these transactions require off-chain processing. Beacon tokens add very little extra over-head for just doing it on-chain with normal inputs.

@Quantumplation
Copy link
Contributor

I disagree with a lot of your characterizations / conclusions, but I don't really have time to write up a response, so we'll just have to agree to disagree 😅

@fallen-icarus
Copy link

Considering this CIP uses DeFi use cases as motivation for this major change, I think discussion of the disagreement is actually relevant to this CIP. I'd rather wait a while for your response than just leave it at "agree to disagree". If other people do not feel this debate is relevant, then please say so and I will happily disagree with you 😄.

@michaelpj
Copy link
Contributor Author

Thanks for the active and interesting debate, this sort of thing is very useful.

There is no way to partially fulfill an unresolved input using a resolving output

Yes, this CIP lets you easily implement some but not all of the usecases from the CPS. Exact swaps yes, limit/market orders no (or not directly).

It lets us be agnostic about the counterparty, but that's it.

Again, if you don't use beacon tokens because the end-users order are just protected by a pubkey, you now need another way to broadcast the orders that has the same security and availability as beacon tokens.

As the text says, this CIP only (partially) addresses intent settlement, and not intent processing. So yes, you need a broadcast system! This is pretty common for intent-based systems (see e.g. this survey article). Notably newer systems like UniswapX are moving in this direction.

As discussed in the CPS, I think the choice of on-chain vs off-chain intent-processing is not obvious. We can do intent-processing on-chain today via script-locked outputs. But off-chain approaches can be a lot cheaper, faster, and more flexible. Consider e.g. Stellar's built-in DEX, which eventually foundered under the transaction costs and wasn't able to keep up with increased price volatility. Of course, they have weaknesses too, but I think what we're talking about here can be useful in both settings (although we'd need some changes to Cardano in order to get cheap distribution without compromising the network).

(e.g. Cancelling or adjusting a limit order placed on-chain means making another transaction, paying the fees for that, and also for the script controlling the output. Not necessarily feasible at scale.)

If yes, why would this be better than just using the current approach of spending a normal input that returns required change (enforced by a script)?

I think @Quantumplation 's list is good, but I would add that as discussed above, not doing this on-chain can be desirable. You can see our work as making that approach simpler and easier to decentralize.

@fallen-icarus
Copy link

fallen-icarus commented Mar 14, 2024

I agree that being able to process more off-chain would be a good use case, but I do not think this CIP nor the CPS properly acknowledge that this use case currently results in sacrificing liveness. This downside needs to be taken seriously, especially with respect to DeFi.

Off-chain solutions are quite developed. Many existing applications have developed their own secondary networks for processing intents that are relevant to their application, and there are efforts to build more generic intent-processing networks (e.g. Anoma).
-- quote from CPS

I think this statement goes too far; the entire "Why Anoma" section of the article you linked talks about all of the downsides for the current intent-processing systems. The very first one mentioned in that article is the loss of liveness (ie, censorship resistance). Some try to solve this by trending towards decentralization, but (according to the article) none have achieved this yet and it is still an open question whether they will achieve it (even L1 blockchains are still struggling to achieve decentralization). So to say "Off-chain solutions are quite developed" is not accurate IMO. I would say this entire niche is still in R&D.

When it comes to the heart of DeFi, liveness cannot be sacrificed. Censorship resistance itself is an extremely valuable economic property. I recognize this comes with a cost though, and I do not believe all economic activity requires it. I would say the distinction lies in the entity's time horizon. Day traders, who constantly update their limit prices in volatile markets, are thinking minute-to-minute/day-to-day, and therefore, probably don't care as much about whether they will be censored months or years into the future. The same is not true for larger entities that have much longer time horizons, such as nation states and large corporations. Look no further than the fallout of the US and NATO freezing Russian assets; in addition to confiscating assets, Russian international payments are now being censored on SWIFT. Nations around the world are now concerned about potentially having their own economic activity stifled by third parties in the future, and are now trying to find alternative systems. This is directly due to the liveness assumptions of the current economic system being violated.

If blockchain is eventually going to be a check on government abuse, I strongly believe liveness is more important than throughput. If critical economic activity can be censored, it opens up attack vectors. Goldfinger attacks apply to DeFi vs TradFi just as much as PoW chains. Economic activity happening in DeFi means less economic activity and control for nation state based economies. Therefore, nation states are incentivized to destroy the DeFi economy. If throughput was enough, the world would be satisfied with TradFi.

That said, I believe there is room for both, these off-chain intents can extend on-chain DeFi by providing an outlet for people that require high-frequency actions; this would leave room on-chain for activity that actually requires liveness. I think this extension alone would be enough to prevent Cardano's on-chain DEXs from suffering the same fate as Stellar's DEX. So I am still fine with this change despite me being less optimistic about it than others. Perhaps in the future, it will be possible to have off-chain intents that do not sacrifice liveness.

I would appreciate it if the CIP and CPS were updated to accurately reflect that contemporary intent-processing systems tend to sacrifice liveness.

@rphair
Copy link
Collaborator

rphair commented Mar 14, 2024

At the next CIP meeting (#780 (comment)) we might only have time to introduce this CIP's idea: I am struggling to keep up with it but I'd still recommend at the meeting that the community be aware of its relevance to DEX design patterns... especially how it separately affects off-chain batchers vs. on-chain swaps... and would look forward to hearing more what the dev community thinks about this relationship.

As that discussion goes forward I would feel much better if both sides of the bipolarity beginning here (#780 (comment)) remain fully represented in the review process... rather than any point of view being the "last word" or sacrificing another point of view because of the time it takes to document it.

@michaelpj
Copy link
Contributor Author

michaelpj commented Mar 15, 2024

I would appreciate it if the CIP and CPS were updated to accurately reflect that contemporary intent-processing systems tend to sacrifice liveness.

Yep, this is a very good point which I was aware of but apparently I forgot to make explicitly 🤦 Censorship-resistance is one of the nice properties we get from the Cardano network, but a pretty important one indeed. I will add some prose about this.

That said, I believe there is room for both, these off-chain intents can extend on-chain DeFi by providing an outlet for people that require high-frequency actions; this would leave room on-chain for activity that actually requires liveness.

Yes, this also seems plausible to me.

I certainly think that there is space for an on-chain mechanism, I just am currently not convinced that the design we have available (the spot market in the Babel Fees paper) is a good one. I don't think it will be good enough to cover heavy real-life usage (see Stellar), and it's a lot of work to implement. I would be very excited to see some research into a more powerful and principled approach to on-chain intent processing in Cardano... but I do think it's a research topic at this stage.

As that discussion goes forward I would feel much better if both sides of the bipolarity beginning here (#780 (comment)) remain fully represented in the review process

I do try to capture alternatives in my CIPs, and in particular I'm going to try and update the CPS so it covers as much of the relevant considerations as possible.

Comment on lines 66 to 67
The `requiredTxs` field is special in that it is _not_ included when hashing the transaction body to create the transaction ID.
It is however signed when the transaction body is signed.

Choose a reason for hiding this comment

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

Are intent transactions signed before submitting them to an intent-processing system? I had assumed yes so that Alice doesn't need to be involved when her intent transaction is officially added to a validation zone by a batcher.

It is however signed when the transaction body is signed.

This makes me think otherwise, though. It reads like Alice must also sign the requiredTxs field even though she can't; she isn't present when the batcher aggregates the transactions into a validation zone.

Choose a reason for hiding this comment

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

This field is largely intended for the purpose of binding several transactions, all of which constructed by only Bob, for fulfilling Alice's intent transactions. For example, in the babel fees usecase, Bob cannot construct a single transaction in a way that both pays for the fees of Alice's transaction, and accepts Alice's offer of token X, without a loop in dependencies. So, he has to separate these actions into two transactions, that he must then make inseparable (by any block producer) by using the requiredTxs field

Choose a reason for hiding this comment

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

So, it might be awkward in other usecases

Choose a reason for hiding this comment

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

So Alice must individually sign her intent transaction. Then Bob must create a resolving transaction to match Alice's intent tx and include Alice's intent tx in the requiredTxs field of his transaction. Bob must sign his resolving transaction. Alice's intent transaction does not contain anything in its requiredTxs field. Is this correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You don't need requiredTxs to get included in the zone. You only need them if you want to bind stuff together atomically, which you don't do with Alice's transaction.

@fallen-icarus
Copy link

A practical concern I have with using intents off-chain like this is how would one rescind an intent transaction? I recognize this deals more with the intent-processing piece, but it seems like a pretty critical concern that impacts the potential use cases for validation zones.

Imagine if Alice creates an intent transaction for a limit order at a price of 1:2. She submits this transaction off-chain to be paired up with other intents. But what if the market price has moved and Alice instead wants to update her limit price to be 2:1? She would create a new one and submit it off-chain. So now there are two intent transactions for Alice floating off-chain. How is Alice protected from a batcher maliciously using the first transaction instead since it allows them to take Alice's assets at a better price? This seems like a pretty big incentives problem that could disqualify most DeFi use cases. This concern also impacts Babel Fees - what if Alice wants to change how much she is willing to pay for a transaction (the fee denominated in ADA would not change but the relative rate to Alice's asset would)?

I understand the desire of keeping CIPs as small as possible, and therefore, dedicating this one solely to intent-settlement. However, this concern makes me think you cannot separate intent-settlement from intent-processing. IMO it would be really bad if we implemented this major change now, but it turned out to be a dead-end due to the restrictions of the intent-processing part. I am not aware of how most other intent systems work so if they have solutions for this, at the very least, can you add prose about this "rescinding concern" and references to how others handle it?

@michaelpj
Copy link
Contributor Author

A practical concern I have with using intents off-chain like this is how would one rescind an intent transaction?

You have choices!

  • In many decentralized systems with uni-directional communication, you just can't rescind things. Consider e.g. Cardano itself: you can't rescind a transaction once you submit it (although you can race to try and make it invalid by spending an output that it also spends)
    • I think this is a somewhat general observation. We can get everyone to agree that something has been cancelled if we record it on-chain... since the whole point of the chain is to get a decentralized group to come to consensus.
  • You can send around unsigned intents. This loses you the benefits of uni-directional communication since things now do have to come back to you to sign, but allows you to cancel things.
  • You can use a trusted intermediary, who advertises your offer but without the information that is needed to complete it (e.g. they strip the signatures and then advertise the unsigned version). (c.f. bitcoin-dex). This lets you go offline but retain most of the benefits of the second approach.
  • You can set short TTLs on your intent so if they aren't settled quickly they become invalid and "auto-cancelled".

I'm not sure there's a one-size-fits-all approach here, since what is useful and desirable partly depends on the use case. If you have an intent where you want it to settle ASAP but you don't care about the details, that is very different from an intent which you want to settle sometime when the conditions are met. You're much more likely to care about cancellation for the latter. Perhaps this means we are still lacking requirements analysis, and the category of "intent" is too big still.

This concern also impacts Babel Fees - what if Alice wants to change how much she is willing to pay for a transaction (the fee denominated in ADA would not change but the relative rate to Alice's asset would)?

I think Babel fees are in the first category. Users are going to want those to settle fast, and if they hang around for long enough that meaningful price changes can happen then I think the system would just not be working well!

I understand the desire of keeping CIPs as small as possible, and therefore, dedicating this one solely to intent-settlement. However, this concern makes me think you cannot separate intent-settlement from intent-processing.

I'm not sure I agree with that, I think this approach is consistent with most of the ways I can see going about cancellation?

@Quantumplation
Copy link
Contributor

Another option for cancellation is to have a nullifier on-chain: each user has a UTXO in their wallet that has some nonce; and one of the reference inputs on the tx they built refers to this UTXO. If they want to cancel the intent (or, all outstanding intents), they spend the UTXO, effectively invalidating anything that hasn't settled yet.

@fallen-icarus
Copy link

Another option for cancellation is to have a nullifier on-chain: each user has a UTXO in their wallet that has some nonce; and one of the reference inputs on the tx they built refers to this UTXO. If they want to cancel the intent (or, all outstanding intents), they spend the UTXO, effectively invalidating anything that hasn't settled yet.

I like this choice the most. It seems to require less trust than the bitcoin-dex. I would suggest one change: you use a normal input instead of a reference input. In fact, I think you should use the ultimate input that gets spent. Concretely, if Alice wants to swap 50 ADA for 100 RBERRY, Alice can create an intent transaction that says:

You can take any UTxO from my address provided it has 50 ADA and datum X. 
Then you must deposit 100 RBERRY at my address.

If Alice wants to cancel any intent transactions, she would consume any UTxO at her address with those required datums. Updating her intent transactions still requires trusting the off-chain part a little, but Alice can make each datum specific to each intent transaction if she really wants to be more cautious. You could potentially require an NFT to be included in the input instead of a required datum if needed.

I think using normal inputs is preferable for a few reasons:

  • When reference inputs are used, the only way to actually have it respected is if the ultimate input spent is actually locked at a script address. But if the normal input itself is used, the intent transaction can potentially be self-verifying - it would fail if the input chosen does not have the required datum. This opens up the possibility of using normal pubkey addresses if desired. If more nuanced logic is needed, the input can be required to come from a script address. This brings me to my next point.
  • It is cheaper for scripts to only have to validate the normal inputs in question. Cross-referencing reference inputs adds a lot of extra cost. This extra cost can create some undesired incentives, namely to prefer transactions with the fewest required reference inputs. This can translate to satisfying the fewest number of users per transaction which is not ideal.

@Quantumplation What are your thoughts on this?

@Quantumplation
Copy link
Contributor

I'm not sure I agree; In my proposal, there is no script validation needed at all: you just literally include the input as a reference input. If that input has been spent, then the transaction is invalid in phase 1, regardless of what transactions run. Thus it's free, and doesn't rely on a script checking the reference inputs. In fact, you don't even need a datum attached, though the counter could be useful for other intent based features.

Even if the transaction you signed includes no scripts, but includes the reference input explicitly, and that reference input has been spent, then the transaction itself will still be invalid. Note that I'm not referring to an "unresolved reference input" or something of the sort, where some other input could be satisfied by some other input.

The reason to use a reference input over a normal input is that you can reuse the same reference input for many intents, and cancel them all at once; it dramatically reduces the complexity of tracking which inputs you've chained through which intents.

It does have the downside of cancelling every intent, though perhaps you have a small bag of UTXOs to parallelize your intents so you have some granularity, without having to do full thread based tracking, etc.

@fallen-icarus
Copy link

I misinterpreted your comment; for some reason, I thought you were using a datum attached to the reference input. Thank you for clarifying.

The reason to use a reference input over a normal input is that you can reuse the same reference input for many intents, and cancel them all at once; it dramatically reduces the complexity of tracking which inputs you've chained through which intents.

There do seem to be trade-offs for both. Something else to consider, when normal inputs are used and Alice's intent is satisfied, all outstanding intent transactions are automatically terminated. There is basically a "self-terminating" feature to normal inputs. This is not true for reference inputs since they still exist even after Alice's intent is satisfied; Alice must manually close it to stop any other (now undesired) intent transactions. This can be a problem, especially for forgetful users.

@michaelpj
Copy link
Contributor Author

These are some nice ideas for cancellation, I will include a discussion of them.

@rphair rphair changed the title CIP-???? | Validation zones CIP-0118? | Validation zones Mar 19, 2024
Copy link
Collaborator

@rphair rphair left a comment

Choose a reason for hiding this comment

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

thanks @michaelpj for introducing at meeting today: happily confirmed early as candidate through anticipating a long discussion.

Please update the directory name and the link to the rendered proposal in the OP 🚀

CIP-????/README.md Outdated Show resolved Hide resolved
@michaelpj
Copy link
Contributor Author

Pushed some updates:

  • Rework the discussion of transaction ordering to make it clearer how transactions have to be ordered in the zone
  • Add discussion of cancellation
  • Explicitly point out that we don't enable limit or market orders
  • Address a few other comments

@michaelpj
Copy link
Contributor Author

Also I should note that I'm very open to name bikeshedding - it's tricky to come up with good names for things, and I don't currently love most of my choices.

@fallen-icarus
Copy link

FYI the top PR comment is currently linked to the wrong CIP. It is linked to CIP-18 instead of CIP-118.

@michaelpj
Copy link
Contributor Author

Thanks, fixed.

@rphair rphair added the State: Likely Deprecated Close if confirmed deprecated (or long waiting). label Jul 23, 2024
@rphair
Copy link
Collaborator

rphair commented Jul 23, 2024

@polinavino we've agreed to discontinue this proposal in favour of your #862 but if any extraordinary circumstances require running them in parallel please feel free to reopen. The editors agreed with me that it's more important to keep your unique commit history than to link directly to the comments above... and this PR's reviewers have already been invited to comment on the new PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Category: Ledger Proposals belonging to the 'Ledger' category. State: Likely Deprecated Close if confirmed deprecated (or long waiting).
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants