-
Notifications
You must be signed in to change notification settings - Fork 355
CIP-0118? | Nested Transactions #862
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
base: master
Are you sure you want to change the base?
Conversation
thanks @polinavino ... really happy to see the continuation of this work. I'm marking the title with the obligatory cc (for continuing review from the old proposal) @Quantumplation @fallen-icarus - p.s. cc (re: Rationale ["towards better design"]) @AndrewWestberg |
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.
I believe it is proper for this to be a separate PR from the first one, though that should be confirmed by other CIP editors today (https://hackmd.io/@cip-editors/93 - cc @Ryun1 @Crypto2099). Given the significance of the revision, the commit history in this case I think is more important than the discussion history & hopefully any prior discussion points will be summarised by previous reviewers here (@fallen-icarus @Quantumplation).
|
||
## Path to Active | ||
|
||
### Software Readiness Level |
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.
For consistency with other CIPs (mainly for review in parallel with 100+ others) this section needs to be broken into Acceptance and Implementation ... I guess since it refers to testing functionality then it would be on the Implementation path.
When done sifting material around in this section it will also help for these items to be GitHub formatted tickboxes (- [ ]
) but I am not going to be pedantic about it especially at this stage.
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.
Sounds good, will do that later today!
I think it's important to not restrict thinking to the Babel Fees application. @Quantumplation explained it quite nicely, but I'll say it a bit differently: the key feature here is that we want to turn interactive protocols (which require back & forth communication, which in practice would be with a centralized service) into non-interactive ones. In fact, we should be able to prove formally that for any transaction that contains subtransactions you can make a transaction without subtransactions that does the same thing (except that it has a different txid & fees). For many applications, there might be ways to get non-interactive protocols in a different manner that doesn't require this feature. What nested transactions give you is a nice & easy way to get it in general. A more apt comparison with past features might be this: Plutus is actually completely unnecessary if you want to implement an order-book DEX. You can just write a piece of software that allows you to announce swaps and intent to fulfull them e.g. by publishing metadata that contains partially signed transactions. It's completely decentralized and trustless and could have been done all the way back in Shelley even (though there weren't any interesting swaps you could do). I'm sure many other things that typically use Plutus could have similarly been implemented before Alonzo by finding some clever solutions. All of that isn't to say that I think nested transactions is required or even a good feature. I haven't personally seen any use case that benefits from nested transactions sufficiently to convince me it's worth the effort (though I'd like to find out). As you've observed correctly, if you just want to do swaps where the participants don't pay the fees in ada you can have that today. I have one decent use case that might be relevant if we implement a particular Leios flavour, but it's not a terribly big thing and there are probably better ways to get that if that's the only use case. |
@WhatisRT the non-interactive part is not to attribute to nested transactions; The non-interactive part can be attributed to CIP-0137 or, more in general, to a data availability solution. Once something like CIP-137 is available, anything that nested transactions aims to do, can be done with a simple signed redeemer as in the babel fee example, without unnecessarily modifying the ledger, and with more control by the user. |
@michele-nuzzi So, back to my example of: "How can I today create a transaction without owning any ADA?" You say that a smart contract approach allows one to implement a solution for this. My question for you, how do I construct a transaction without owning any ADA? Even if your Babel Fee smart contract unlocks an input with ADA in it to pay for the fees, someone has to specify the collateral, which can't be locked by any script.
So, no matter on what sort of clever smart contract solution one will come up with, it will be impossible for the end user to submit a signed transaction without that user owning any ADA. It would have to be the provider who'd be creating the final transaction if such use case is to be possible. |
@lehins we have to be realistic. What is the problem we are trying to solve? There is no user with "no ada" due to minUtxo. The problem we are trying to solve is not "allow someone without ada to transact" because such a user doesn't exist, the problem we are trying to solve is "pay a fee with any token". Additionally, this problem only exists for simple transfers, where min collateral is less than minUtxo with no tokens for such a simple contract. With do you want to tell me the user does not have at least 2 utxos to do a transaction? do we want to introduce also transactions for the "users that don't have utxos"? |
There's a specific design question about whether simple scripts should be allowed in transactions containing subtransactions. Since following this PR is getting quite complicated I thought I'd try something new to spin out the conversation, which is to make a separate issue on the ledger specification repo. If you have any feedback or opinions on this topic, please leave a comment there! |
Regarding the ledger implementation version vs the smart contract version, I have some questions:
|
Which definition? could you explain it to me why adding a simple input does not work with contracts?
How hard it is to query one more utxo? |
By this argument, plutus should not exist, everything we want to do should be a modification of the ledger, because "we get everything for free" Wouldn't dApp developers need to do a lot more (error-prone) work to manage all the possibly unbalanced sub-transactions? With the smart contract version, the app only minds their logic; the babel fee logic is kept separate from the application logic |
@fallen-icarus mind you I'm not proposing a smart wallet for users, but only for providers, this solution works for everyone |
If the user's funds are locked at a pubkey address, signing a redeemer does nothing because the funds are not protected by logic. The user would need to sign the full transaction which is exactly the coordination problem nested transactions is trying to solve. The smart contract approach only works for funds protected by the smart contract.
That doesn't make sense to me. If the user's funds are not at a smart wallet, how can their funds be spent just by signing a redeemer?
I was referring to the on-chain code for the dApp. With the smart contract version, wouldn't the dApp need to analyze the redeemers at runtime just to figure out its own contexts? I'm actually curious if the smart contract approach introduces a new double-satisfaction attack vector that all dApps would need to consider. The ledger would enforce some safeguards for free which takes away some of the security burden for dApp developers.
That is not what I'm saying. Consider the Linux Kernel, ubiquitously useful features (e.g., new filesystems) are eventually integrated directly into the kernel while the rest of the features are not. I think the Cardano Ledger should be treated the same way. I don't actually know if Nested Transactions satisfies this high bar; that's why I'm asking these questions. |
Because we are not spending user funds, we are spending the provider funds Have you even had a look at the proposed smart contract solution before assuming it doesn't work? |
Do you realize how aggressive you are?
The Nested Transactions CIP works for both spending user funds and spending provider funds. So it sounds like the smart contract approach indeed does not cover the same use cases. It only covers a subset of use cases. |
What would you consider an appropriate response to someone who just dismisses your solution without reviewing it? |
It sounds like you havent reviewed the proposed smart contract solution. Also this is designed to solve specifically the babel-fee problem With very few adjustments, the same solution could be applied to your version of p2p swaps with professional market makers |
I actually did review your solution which seems very similar to MicroProofs' bullet. The entity signs I even directly quoted you 👇:
You placed this extra constraint! Nested Transactions is also trying to enable spending user funds, not just provider funds. But perhaps I am misunderstanding something so please answer this: How does your solution support spending funds in a Cardano address that is using only pubkey credentials? This address does not use simple scripts (no multisig) or plutus scripts. It is just a pure pubkey address. |
@fallen-icarus The contract only checks for the provider's utxo; that means the pubkey (or script) user is perfectly capable of spending their funds, because the script doesn't care about them. IT DOES NOT ADD ANY MORE CONSTRAINTS ON THE ORIGINAL TRANSACTION I hope this answers your question |
Sorry, I wasn't clear. I'm not talking about transaction constraints. I'm talking about use cases. You are saying nested transactions and the smart contract approach cover the same use cases, but only after narrowing the scope to spending provider funds.
With nested transactions, users don't need to migrate their funds to smart contract addresses to use sub-transactions. Pubkey-only addresses can spend funds by only signing sub-transactions, too. |
Users don't need to migrate any funds. I don't know how else to explain it |
If I have 100 ADA at an address like this: Address (PubkeyCredential spendingKeyHash) (Just $ PubKeyCredential stakingKeyHash) Please explain how I can spend the 100 ADA by only signing a piece of a redeemer. AFAIU, the ledger does not allow this. I need to sign the entire transaction. @lehins |
because you don't sign the redeemer, you only use the redeemer of the provider, and you just sign your transaction |
This is getting ridiculous. If you really want, I can explain it in a 2-minute call |
Oh, I think I see the confusion. That's a different use case than what I'm saying. You are imagining the provider creates and signs parts of redeemers and sends them to the relevant end-users. The end-user than submits the final transaction. So the flow of the sub-transaction is: provider --> user. But what about the end-user signing a sub-transaction and sending the sub-transaction to a provider? This is a different use case that is also supported by Nested Transactions, but not the smart contract approach. An example real world use case is an off-chain market maker: users send sub-transactions representing market orders to the market maker and the market maker then adds their liquidity to fulfill all these market orders in one transaction. Having the market maker sign the sub-transaction and send it to each end-user would be way less efficient and prone to unnecessary UTxO contention. So with Nested transactions, the flow of the sub-transactions can go in either direction: provider <--> user. |
Nested transactions would be prone to utxo contention too, that would be mitigated by the data aviablity solution that is implemented in parallel, which would also perfectly work to distribute redeemers. Additionally, the redeemer can specify an optional expiration time so that the provider can guarantee no contention up to that time (optional just in case of rare edge cases where other contracts may require different timing for their purposes). provider-> user and user->provider are equivalent. As I said this same solution could be applied to your design with very few changes. The smart contract approach has the added benefit of preserving the user privacy from the provider, which can therefore not censor based on the user transaction. Provider and user don't have to comunicate at all, the provider just has to make aviable the redeemers by any means, the user just takes them. In your case the market maker just places his liquidity and the user uses it to fulfil their order (which is how traditional OB MM work) |
This is false. With the smart contract approach, end-users cannot spend funds by only signing sub-transactions unless their funds are locked at a smart contract address.
Please don't twist my words. I didn't say there would be no UTxO contention. Provider --> user sub-transactions experience different UTxO contention than user --> provider. The type of contention matters for different use cases. Most of my use cases (like this video game store) require the ability for end-users to create sub-transactions and send them to providers. As I keep explaining, the smart contract approach only supports this if the end-user has their funds locked at the plutus script address. With nested transactions, the user's funds can remain at a pubkey address. We can talk more at the upcoming ledger working group, but the assertion that the smart contract approach covers the same use cases is false. As I said, it doesn't work for my use cases. |
I don't know how you keep interpreting every message of mine as an attack. Maybe not by this approach, but there is nothing preventing you from exploring some more contract designs, since there is no fundamental capability that nested transactions add to the expression of a transaction. If you can send a partial tx to the provider certainly you could send some arbitrary JSON/CBOR to the same provider |
I am being realistic. Babel fees is precisely that: ability to pay fees in something other than ADA. If a user is forced to specify 150% in ADA anyways to pay for the fees for phase2 invalida transaction, then it is not Babel Fees.
Having few lovelace due to minutxo restriction does not constitute having enough ADA to pay for fees and collateral
In my opinion forcing user to specify collateral is precisely the opposite of ability to pay fee in any token.
Babel Fee smart contract does not sound that simple that to me that it will cost 0.2 ADA, but I could definitely be wrong here since I do not write smart contracts and I am oblivious to their costs
Not necessarily that has enough ADA in it to submit a transaction.
That will unlikely to ever happen 😉 Cardano is a UTxO base blockchain. Even though there is a chance that accounts are on the horizon, a user will always have to spend at least one utxo for a replay protection. |
I'm interested in this proposal for, which may be, a new use case:
Reasons for that my be that this will yield an overall lower inclusion latency. While the overall size will be governed by the maximum transaction size, the cost of validating the batch may be even be lower? My main point of interest, however, would be the fact that it provides atomicity to multiple transactions and that I can refer to them by a single ID. Is this the case with the current proposal? (From a first look, I'd say yes) Further context: At least one of the Leios protocol designs, that aim for increased throughput on Cardano, would benefit from being able to refer to groups of transactions (instead of all txs individually). |
a batch is required to cover the minimum fees of all transactions. The fees specified in all transactions are always collected. | ||
Individual transactions in a batch do not need to meet the min-fee requirement. | ||
|
||
8. The total size of the top-level transaction (including all its sub-transactions) must be less than the `maxTxSize`. |
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.
This seems ambiguous - does it mean the total size of the top-level transaction including (naturally) the sub-transaction hashes, or recursively the total size including all the sub-transaction sizes too?
If the latter, that would seem a shame (and would prevent a particular use case in Leios which this margin is too small to contain), and it's not clear why this constraint is required.
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.
I think this would not impact the Leios use case we have been thinking about? In that situation, the max tx size could be bigger (which has all kinds of good properties like reducing potential for conflicts).
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.
OK, that's good - but I'd still like to understand why it has to be limited at all - assuming I have understood correctly that batching is by reference rather than inclusion?
Implied by:
L111: 2. subTxs : ℙ TxId
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.
Batching is by inclusion, instead of by reference, hence the size limit
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.
Ah OK. thanks. Did I misunderstand the meaning of "TxId" in the definition of subTxs? I had assumed that was a hash.
@ch1bo Nested Transactions in a nutshell means a regular transacttion that includes a list of sub-transactions. |
We propose a set of changes that revolve around validation zones, a construct for allowing certain kinds of underspecified transactions. In particular, for the Babel-fees usecase we discuss here, we allow transactions that specify part of a swap request. A validation zone is a list of transactions such that earlier transactions in the list may be underspecified, while later transactions must complete all partial specifications. In the Babel-fees usecase, the completion of a specification is the fulfillment of a swap request. We discuss how validation zones for the Babel fees usecase can be generalized to a template for addressing a number of use cases from CPS-15.
📄 Rendered Proposal