-
Notifications
You must be signed in to change notification settings - Fork 323
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
CPS-0004? | Spending Script Redundant Execution #418
CPS-0004? | Spending Script Redundant Execution #418
Conversation
@fallen-icarus we need to reduce the amount of non-essential words in the title while still covering exactly what this is about. Would it be accurate & complete to title this Spending Script Redundant Execution? If not, then something else with a small number of meaningful words? |
@rphair Spending Script Redundant Execution works for me. I'll change the title. |
I'm not sure this is an actual problem? If you have this problem, your script should rather than doing the computation, check that you withdraw 0 ADA as rewards from a helper script that checks the computation. |
@L-as I'm not sure what you mean. This has nothing to do with rewards. Can you please elaborate on what you mean? |
It's a trick to solve exactly the issue you describe. You can always withdraw 0 ADA. |
My understanding of this trick is the following:
If this is correct then this trick does not solve the issue. Script B will still redundantly check if Script A was executed. This does not stop redundant script executions; it only minimizes the cost of those redundant executions. Also this trick only works well with centralized smart contracts. I have created a DEX proof-of-concept (that I will open source soon) where users maintain full delegation control of their assets at all times. As a design requirement for this feature, all users have their own swap contracts. Users can then lookup all available swap contracts to remotely interact with other users' swaps. I have already extensively tested the DEX and it works as expected. It also has other nice properties such as being naturally concurrent (there are at least as many utxos as there are users) and therefore doesn't require batchers. The only issue is having to tolerate the redundant executions. If I were to use this trick with the DEX, it would literally double the number of smart contracts required. Not only would this dramatically over-complicate the DEX design, but it would also create bottlenecks in the lookup process of finding all the necessary information for users to interact with the DEX. It is also worth pointing out that each user needs to store their reference scripts in each of their swap contract address. Right now this is like a deposit of 24 ADA in order to open a swap position. Using this trick would increase the necessary deposit each user needs to make per swap position. The above drawbacks aren't an issue for centralized smart contracts. But these centralized smart contracts also have the drawbacks of:
It is my strong opinion that, given the redundant executions incentivize this trick (in the pursuit of lower fees) and this trick strongly favors centralized smart contract designs, this actually further highlights why these redundant executions are a problem. |
@fallen-icarus I really hope you will include this last explanation in your CPS somehow. Cardano has a great potential (compared to other L1's) to support fully distributed architectures and the DEX example is an excellent way to bring this problem statement into active discussion & solution. |
I'm not sure I understand your issue, but you definitely shouldn't have a script per user. I'm not sure how you came to that conclusion. I'm 'aso not sure how this pertains to batchers, or delegating, or centralisation. In any case, I don't think the fee overhead from this trick is worth messing so heavily with how validators work. |
@L-as Imagine you have the following setup:
Now imagine that Alice and Bob both have 5 utxos locked by Script B (10 utxos in total). What would happen in the following contexts?
In the first context, there is no major problem:
In the second context, there is now a bottleneck problem: each of the 10 txs need to use one utxo from Script A to force its execution but there are only 5 utxos available. In this context, batchers are required to use the limited number of Script A utxos efficiently. You can increase the number of utxos at Script A but the concurrency will always be limited to the number of utxos at Script A. Given the world that blockchain hopes to achieve where everyone is using DeFi, would 1000 utxos be enough? What about 10000? If you guess wrong, bottlenecks will cause issues that only batchers can solve. The reason for this bottleneck is due to Script A not being a real reference script. It is basically a frankein-script: half-reference, half-real. By this I mean that a completely unrelated (to the transaction) utxo needs to be consumed in order to "reference" Script A. Now imagine this counter setup:
Imagine Alice has 5 utxos locked by Script Alice and Bob has 5 utxos locked by Script Bob. What would happen in the same two contexts before? In the first context, there are annoying redundant checks that cost about 0.3 ADA each but it works:
In the second context, there are no problems at all (there are no redundant checks since they are separate txs):
These 10 txs can go through at the same time because their is no concurrency bottleneck. Script Alice and Script Bob are always available since they are being used as true reference scripts. The second setup's maximum concurrency is directly tied to the the number of utxos each user wants to use. In other words, the more people want to use it, the more concurrency is naturally available. The first setup (which is the trick) has the concurrency "hardcoded" by the number of utxos at Script A. This concurrency does not naturally grow or shrink with the demand. In low demand contexts, there are likely to be too many utxos at Script A which results in inefficient use of the ADA locked at Script A. While in high demand contexts, there are likely to be too few utxos at Script A which means batchers will need to be used to compensate. The backlog that SundaeSwap suffered is a perfect example. Backlogs only exist when the concurrency is too low for the demand. This doesn't even deal who decides how many utxos are available from Script A which is another whole "can of worms". In short, this trick sacrifices concurrency in order to minimize the cost of redundant executions. To compensate for this drop in concurrency, centralizing solutions are used, such as batchers. That is how this pertains to concurrency and centralization. Edited to include fees for the first setup too. |
|
Anyway, I don't get how this pertains to the proposal, and would say that maybe what you want is to optimise the script for checking the 0 ADA withdrawal. AFAICT though this can be a script of around ~100 bytes if not smaller. #309 is also relevant. |
From my perspective, your view that redundant executions aren't a real issue stems from your set beliefs about how Dapps can and cannot be created. I thought if I showed you concrete proof of another (and in my option better) way, I could change your mind about this. I actually built the DEX so people can try it out. It has all the following desirable features:
Again in my opinion, these features make this proof-of-concept probably the best DEX that so far exists in DeFi. The only thing holding it back is the redundant executions. Without the redundant executions, it would also be much cheaper than any DEX using the "withdraw 0 ADA" trick. As for your points: Point 2 is addressed in its entirety in the README. Both the reference scripts and the available swaps are easily broadcasted by what I call Beacon Tokens. There is no need for any of the complicated techniques that were mentioned. It easily works on Cardano as is. As a bonus, these Beacon Tokens can be generalized to any Dapp. This means broadcasting any information to other users is trivial for any application. Also the need for a global state is not the only reason to use a blockchain. The blockchain is also meant for any peer to peer application where users do not trust each other. This latter reason is why my DEX is on-chain. There is no need for state-channels; there is plenty of room on layer 1. With the current design of the DEX, there is basically a deposit required for opening swaps which comes from having the user store his/her reference script on-chain to then be found with the Beacon Tokens. This deposit also disincentivizes opening empty swap addresses. However, if the deposit is deemed to be too high (currently about 20 ADA), I also mention a potential adaptation of the design at the end of the README that does not have this high of a deposit requirement. I am mentioning this to point out that, combined with the Beacon Tokens, there are no drawbacks from giving users their own scripts/addresses. As for point 1, I have looked at every DEX I could find that uses liquidity pools and none of them meet the gold standard of users maintaining full delegation control. By this I mean that, while both Alice and Bob use the DEX:
This still sounds like it violates the third requirement of the standard. From a first principle perspective, I am very skeptical of the idea that liquidity pools can ever be designed in a way to match the level of decentralization obtained from full user delegation control. Unless you can directly point to an actual liquidity pool based DEX that meets the above standard (including the third requirement), we will just have to agree to disagree. In short, it seems to me that there are three consequences (that I know of so far) to having these redundant executions:
You keep suggesting to use the "withdraw 0 ADA" trick and I keep explaining why I do not believe this trick is a good solution: it leads to more centralized designs. I strongly disagree with the view "we should just use the trick instead of fixing the redundant executions". Also the problem is not that the execution costs are too high; the problem is that there are redundant executions being done so the fee compounds. 0.3 ADA is already extremely cheap to check a whole transaction. If I wanted to, converting my script to be used like the trick suggested is not an issue. Therefore, #309 would not be useful. However, I think my proposal would actually solve #309 issue. My proposed solution allows a plutus script to be able to handle both the case where a datum is missing and the case where a datum is present; no proxy-scripts are necessary. It does this without having to create an on-chain encoding for a missing datum. I know there are other proposals motivated by the no datum issue. I will try to aggregate them and add to my proposal how they are easily solved by my proposed solution. I do not mean to come across as shilling the DEX proof-of-concept. There is actually no way for me to personally profit from others using the DEX, aside from new people coming to Cardano to use it. (Cheers to being properly incentivized lol). It is for this reason that I think it is okay for me to discuss it. I personally believe it adds weight to the need for this proposal but if others feel the DEX does not help explain why the fix is needed, I can drop it from the discussion. |
In my opinion, the divergence of opinion is exactly why it needs to remain in the discussion and certainly in the CPS itself (I said that above, but would say so even more emphatically now). @fallen-icarus - others are going to want to follow your more "granular" (I don't know if that's the right word?) approach even if trade practice suggests otherwise. Even if it were only an academic consideration it would still have a place in this CPS: editorially I can say that our overall process is about academic concepts finding implementations: sometimes gradually. |
I have a lot of thoughts, but I will focus on the biggest issue:
|
@L-as You are not accounting for the utxo ID changing every time the "withdraw 0 ADA" script is executed. On Cardano, a script will NOT execute unless a utxo from that script's address is consumed. It doesn't matter if there was no value taken. The old utxo will be destroyed and a new utxo with a different utxo ID will be produced. This will happen even if 0 ADA is actually taken from that script's address. It is NOT possible to successfully execute a script WITHOUT changing the utxo ID of the utxo that was used to force its execution. In order to force its execution again, the new utxo ID is now needed. This is completely different to the way actual reference scripts work. Actual reference scripts assume all utxos actually being used are at the address that belongs to the reference script. To have two different scripts means you have two different addresses. In order to execute both scripts in each transaction, at least one utxo must be consumed from each address. This means the utxos IDs at the "withdraw 0 ADA" script will be constantly changing. Are you thinking of how it works on another blockchain and thinking it will also work on Cardano? |
@fallen-icarus OK, I think I understand: You mistakenly believe that you need a UTXO to use the withdraw 0 trick. This is not the case. There is no UTXO at all locked by the script (or using the script as staking address, but even if there were, it doesn't matter). |
@L-as What is the Edit: Thanks for pointing out my mistaken assumption. |
So I have been testing using the I don't believe I mentioned this before but the dex uses composable atomic swaps. Do you want to convert 10 ADA into 5 WMT and 5 DUST? No problem; you can do this in one tx. Do you want to convert 5 ADA and 5 WMT to 3 AGIX and 7 DUST? Again no problem. This can also be done in the same tx. Using composable atomic swaps means, in one tx, you can easily do: many assets -> many assets In order to maintain composability, there is a separate auxiliary script for each possible trading pair (easily created on the fly by users). Without the atomic swap contracts being able to verify that the required auxiliary script was executed, the security of the composition is completely broken. @L-as Am I missing something else that would allow me to do this? |
@L-as After thinking about it more, I'm starting to think the auxiliary script is not what you mean.
Do you mean:
Is this correct? |
That's what I've been saying from the start. I have not misspoken. |
I know. The misunderstanding was my fault. I didn't realize you could literally use a staking script as a spending script like this. So whenever you mentioned rewards or staking, I thought you just didn't understand my issue. Apologies for this misunderstanding. I will test this today and comment with what I find. |
Okay so I was able to get everything working using the trick. However, despite the dex technically still working, I believe this CPS should still be pursued for the following reasons:
@L-as Maybe reasons 1, 2, and 3 alone are not enough of a reason to change how validators work. But when you also consider the possibility of reason 4, I believe it is worth doing. Do you? |
Although this CIP is for a different use-case than CIP38 there is some overlap and I just added this to the CIP38 motivation section #309 |
Co-authored-by: Matthias Benkort <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@KtorZ @fallen-icarus @zhekson1 I'm trying to follow up on increased interest on the Cardano MBO on Matrix in Cardano Swaps and whatever it would take to implement them. I've tried to stay ahead of this idea and see it's fallen quiet for about a month along with some of the CIP documented components that would be required.
Can we summarise here, so the community can follow potential implementations and so we can keep moving this CPS forward:
1 - Is there a "best" place on the CIP repository for discussing Cardano Swaps? Or given that it's given a full heading in #466, would that be a better choice?
- On that note, if Cardano Swaps is a major use case for this CPS, shouldn't it have its own section rather than a single line in a bulleted list of Use Cases it has now?
2 - Should Cardano Swaps have its own CPS? ... e.g. if it's perceived that the reference implementation on GitHub might be done better with support in Plutus for an improved implementation? (cc @michaelpj)
3 - Whether we can designate such a place, or need to create a new one (like a GitHub Discussion, if that's not a step backward), can we then use that place to gather public discussions like the ones I started collecting in #466 (comment) when they relate to community interest & potential implementations.. both for the Cardano Swaps and related use cases?
4 - The SPO Digest today mentioned Cardano Working Groups: how to get involved which lists an IOG group "Developer experience" which would cover applications for DEX and this CPS's other use cases... but without any more specific (sub-?) groups for these areas.
- @KtorZ how would we go about suggesting that a working group be formed to address this similar set of use cases, starting with the arguably most urgent case of Cardano Swaps?
- If IOG hasn't formed or can't form a group or sub-group for it, is this something the CF could do?
Whether there are Plutus changes that need to happen first, or this CPS needs to be changed in scope, or an additional CPS needs to be created for Cardano Swaps or other DeFi components, etc... then such a Working Group might finally consolidate all this potential into better documentation of who needs to do what & in what order.
I do not use matrix so I cannot see the activity there. Here are my thoughts though:
|
sounds great: not marking |
After writing both cardano-swaps and cardano-loans in aiken, I am no longer concerned about the redundant executions. cardano-swaps can handle 8+ swaps in a single transaction, and cardano-loans can accept 6 loans or make payments on 8+ loans in a single transaction. I think these benchmarks are more than sufficient for right now. To be clear, redundant executions are still present but aiken is efficient enough to make them negligible. Therefore, I do not see a need to pursue this CPS. |
That's very good to hear @fallen-icarus and so closing this would be consistent with others' suggestions that more general methods would be applicable, and thanks for the update. Is there anything that would be helpful in standards, documentation, developer support, or visibility to Cardano official agencies that would help with If so, l'd be happy if you would open a CIPs issue to help get whatever support you might need for the Cardano Swaps, Loans, and other use cases you've documented here. |
@fallen-icarus I would disagree with this actually. I have been playing with Hydra and L2 and some more complex use cases we totally blew up Aiken and Plutus. This still makes sense and it all depends on complexity of what one is doing. |
@rphair I would like to finish the feature set of these protocols before personally revisiting CIPs. The ideascale proposal pretty much covers what I would like to do. I never thought these POCs would take so long... There are a few issues where CIPs could help but I think the arguments for them would be stronger once there are fully featured protocols to point to. The issues mostly revolve around maintenance of these protocols. Will the official location for the code be my repo, the CIPs repo, or an entirely new repo like a "Cardano Protocols" repo? Should an entity like the cardano foundation hold the license to them? What will be the process for making changes to the protocols? I think these questions relate to the ones you asked in the linked comment. Perhaps the community can start thinking about these questions while the protocols are finalized. |
@matiwinnetou Considering I have not personally dealt with the issues you mention, I do not think I am the right person to head this CPS if it should still be pursued. Should this one be re-opened or should a new PR be made where someone else is the author? |
So far we've determined that CIP related code (practical & reference implementations; examples are OK) should not be in the CIPs repo for a few reasons highlighted in other PRs:
I can think of no practical goal that could be achieved any more easily by making that assignment. Anything the community does to promote Cardano P2P markets can rely entirely upon open source licenses published by developers themselves... and anything the CF does to promote these would not depend upon its holding license over either the code or its documentation in any CIPs.
What do you say Mateusz? Upon your request we can open this up again and declare you the advocate of this CPS, with you eventfully adding yourself a CPS author whenever that might be appropriate. 🤔 |
@rphair - I am happy to take over this CIP as an author. I personally don't think having Aiken (which is very performant indeed) is an excuse not to purse this work in future versions of Plutus. |
@matiwinnetou coincidentally it's been exactly a year since you offered to take over authorship / advocacy for this CPS. Due to that time interval I'm marking this Failing that, we might close this PR if nothing further happens with it ("Abandoned" mainly refers to the CIP submission rather than the idea). @fallen-icarus @MicroProofs @colll78 you might also give us your perspective about whether or not the recent update (rolling out with Chang) update to CIP-0069 addresses this issue (based on @fallen-icarus #418 (comment)). |
No Chang does not, there is still no way to guard the spending of a UTxO without a spending script that is executed once per UTxO. However, https://github.com/cardano-foundation/CIPs/tree/master/CIP-0112 the observe CIP that was merged does address this. |
The observer script CIP only partially addresses this issue; the spending scripts are still redundantly checking if the observer script is executed. The Spend Many CIP is the only CIP I am aware of that would entirely eliminate the redundant executions. |
@fallen-icarus if you agree with this:
then it can (now that it's merged) be added under |
Not exactly, because the observer CIP extends native scripts such that they can check for the presence of an observer, and native scripts have no impact on Ex-Units. This means that no spending scripts are necessary, and no redundant executions occur. Essentially, in places that you currently use spending scripts to check for the presence of a Reward script execution or any other transaction level validation, you instead use a native script which checks for a given observer. |
OK @fallen-icarus from the above conversation last month (not progressed since then) we have to assume this submission has been abandoned & that you or another advocate will either reopen this or submit a different iteration of the same idea if & when there is progress to be made. |
(rendered proposal in branch)