-
Notifications
You must be signed in to change notification settings - Fork 321
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? | Nested Transactions #862
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!
This new design makes it possible to define a script which (via conditioning on transactions fixed by Such conditioning can be done in two ways
|
After some discussion with @willjgould and @lehins , we have come up with a way for sub-transactions to constrain the batches they are in - batch observers, see the updated README-nested.md. This is very similar to script observers and both can/will? be implemented together , however
It is essentially impossible to run (calculate exUnits, etc.) batch observer scripts unless you are building the top-level tx, so it probably makes sense for off-chain code to give special instructions to the top-level tx builder in some high-level language about how to build it in a way that will satisfy the script (simpler than Plutus). |
CIP-0118/README-nested.md
Outdated
5. a new intent we call "spend-by-output", wherein a sub-transactions may specify _outputs_ it | ||
intends to spend, and the top-level transaction specifies the inputs that point | ||
to those outputs in the UTxO set. This is included as a way to showcase that this | ||
change to the ledger rules establishes the infrastructure to add additional | ||
kids of supported intents (see CPS-15). |
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 don't understand what this means. The use of the terms "inputs" and "outputs" is confusing to me. In my vocabulary, "inputs" are UTxOs that a transaction intends to spend while "outputs" are UTxOs that would be created by the transaction. So I don't understand what it means to "specify outputs it intends to spend" or "[specify] the inputs that point to those outputs in the UTxO set". Can you explain what you mean by this?
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.
My interpretation is that "output" is the contents (address/datum/value), while "input" is the out_ref pointing to a specific output.
- a new intent we call "spend-by-output", wherein a sub-transaction may specify the contents of the outputs it intends to spend, and the top-level transaction specifies the transaction references to those output in the UTxO set
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.
suppose tx
has inputs txin1, txin2
and output o1
also, in the UTxO we have
txin1 |-> o
txin2 |-> o'
\
then, we can build tx'
that has spendOuts
containing o, o'
and output o1
. A top-level transaction builder can then complete the batch with txTop
, with (possibly some inputs), and
corInputs
containing txin1, txin2
Then, in some sense, tx
and tx'; txTop
do a similar thing - remove entries corresponding to txin1, txin2
from the UTxO, and add o, o'
to the UTxO. tx'
would likely include a payment to whoever builds txTop
for their tx-building services.
The reason we are proposing this is that if a light client (LC) is not following the chain, they would be unaware of the txin
s they would want to spend. If an LC requests a service provider to build a transaction for them that satisfies some specification (e.g. "pay key k
the amount x
of ada from key k'
), the SP should be able to respond in a way that the LC does not use the data in this response to construct a new valid transaction that excludes payment to the SP. Obscuring inputs that SP can supply later makes it so that the transaction is not valid unless it comes with a top-level tx that provides the missing inputs.
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 design answers the question of "how can a user approve payment from their wallet without knowing anything about the chain except what the transaction spending their money is doing with their money"?
CIP-0118/README-nested.md
Outdated
### Open (atomic) swaps | ||
|
||
A user wants to swap 10 Ada for 5 tokens `myT`. He creates an unbalanced transaction `tx` that | ||
has extra 10 Ada, but is short 5 `myT`. | ||
Any counterparty that sees this transaction can create a top-level | ||
transaction `tx'` that includes `tx` as a sub-transaction. The transaction | ||
`tx'` would have extra 5 `myT`, and be short 10 Ada. |
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.
Can you possibly be a bit more explicit with this example? This CIP talks about underspecified transactions, but doesn't really give a user-friendly example of one. I believe this new version has adopted the approach from my Transaction Pieces, right? So it would be accurate to say:
tx
has inputs with 10 Ada and an output with 5myT
, and is left unbalanced like this.tx'
has inputs with 5myT
and an output with 10 Ada.- They are submitted together as a balanced batch with
tx'
as the top-level transaction.
I think I am biased by the original Validation Zones CIP that had unresolved holes, so I would personally find this example helpful to show there are no unresolved holes in this version.
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.
yes, this is exactly right.
Hey everyone. I didn't have a clear idea on this CIP for a while but recently I'm thinking that it doesn't bring a lot of value especially considering the cost of implementation (impact on the ledger etc...) Most of what validations zone could achieve could instead be achieved leveraging utxo contention. We can have multiple transactions spending different utxos of a contract, but the same utxos of a given user. If someone is worried about contention on the contract, the more utxos the contract can spend (and the user can use in mutually exclusive transactions), the less chance of contention by the contract. This is effectively moving the load from the ledger to the consensus, that in theory should already be able to handle, without hardfork. |
BTW, I see and understand how validation zones could turn useful, and I not entirely opposed to it. Just wanted to let you know of potential alternative possibilities |
@michele-nuzzi Signing multiple transactions is a UX nightmare. Also... how much are you willing to waste in min-utxo fractionalizing liquidity across enough utxos to avoid contention. The fact of the matter is that pooling liquidity will give a better UX. Take for example a musician minting their 100m stream tokens on NEWM. They want to list these tokens for sale. They can put them into a pooled AMM with ~1.3 ada, or they can take your approach and fractionalize it into 1000 chunks of 100k tokens. This costs 1,300 ada to list it. As you fractionalize further, you don't necessarily avoid utxo contention. It actually increases as you'd have to pull more utxos into a given transaction to perform the swap and even 1 of them conflicting is a failure of the whole transaction. If you've guessed wrongly and either over-fractionalized or under-fractionalized based on end user demand for the amount of tokens they want to acquire, contention becomes more likely. As the fractions run out as people buy, you can either continue to fractionalize, which leads to contention when people are trying to grab amounts larger than the fraction size and need to take a high number of the fractions to do their swap... contention. Or, you don't continue to fractionalize and users are left fighting over the remaining fractions... contention. I do look forward to what your catalyst proposal produces and how you plan to have users signing 2..3...20 duplicate transactions on their ledger device to "solve" the utxo contention issue. As you can tell from my response, I do not believe embracing utxo contention and fractionalizing liquidity is a viable approach. |
@AndrewWestberg I think we are basing our perspectives on different assumptions. There would ideally be a sweet spot to fractionalize liquidity. I don't think it is realistic to assume 1000 orders can be executed in the same block, so over ~30 orders there would be no benefit. A well designed contract would also make sure that some given utxos can only be spent together to further reduce contention (if we must spend two utxos together is like spending only one). I would also point out that CIP 103 is currently active, allowing users to sign multiple transactions without impacting UX. |
Additionally relying on consensus rather than the ledger allows us more control over the transactions. We can build many transactions that we directly control and look good enough for us rather than praying and hoping the nodes will pick favourable utxos for the transaction. |
If around 30 orders go into a block, but there are 1000s of users trying to swap, they will need to sign transactions against future state that is un-knowable. You're never going to get away from utxo contention being an extremely poor UX if there's any type of large demand. If I'm not in the first group of 30, there's no way for me to sign a tx(s) and come back and have my swap actually work. The utxos I signed against are long gone in any type of load scenario. This CIP elegantly solves the problem. |
Once again we are basing our statements on different assumptions. Assuming the 30 orders will change the part of the state that future transactions depend on is the side-effect of the single-threaded mentality that prevents us to fully leverage what the utxo model can offer. In my opinion, this CIP incentivizes this single-threaded approach that in the long term is counterproductive for the utxo model. |
There will likely be cases for both single- and multi- threaded approaches, however, i can imagine many cases in which multi-threading would help also being situations where threads that are created by a single (or very few) entities. So, these same situations would benefit from that single entity instead setting up a Babel service which relieves the UTxO contention, removing the need for multi-threading. |
CIP-0118/README-nested.md
Outdated
|
||
We add the following new fields to `TxBody` : | ||
|
||
1. `isTopLevel : Bool`\ |
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 is redundant. NonEmpty subTxs
already sets this flag to True, while empty means False
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 was an old comment that I forgot to submit weeks ago 😄
CIP-0118/README-nested.md
Outdated
- fixes all attached sub-transactions | ||
|
||
3. `requiredTxs : ℙ TxId`\ | ||
- fixes what transactions will be shown to plutus scripts being run by this transaction |
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.
How do you include the top level transaction? You can't because that would be recursive. Which means sub transactions should either never see the top level tx or always see it.
Moreover, making ability for scripts to see other txs as an option is a bad idea IMHO. It should be all or nothing!
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.
Also old comment. Somehow I couldn't figure out on github to delete comments on the code that has disappeared
CIP-0118/README-nested.md
Outdated
- fixes what transactions will be shown to plutus scripts being run by this transaction | ||
|
||
4. `spendOuts : List TxOut`\ | ||
- outputs being spent for which inputs are provided by top-level tx |
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 will lead to a lot of duplication!!! Think of outputs with reference scripts or inline datums.
CIP-0118/README-nested.md
Outdated
- inputs corresponding to `spentOuts` | ||
|
||
6. `knowsOwnUnits : Bool`\ | ||
- toggles whether the sub-tx provides its own `ExUnits` or the top-level tx provides them |
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 goes back to making sub-txs in script context optional. This is totally unnecessary
CIP-0118/README-nested.md
Outdated
|
||
to | ||
|
||
`LEDGERS -> LEDGER -> SWAPS -> SWAP -> UTXOW -> UTXO -> UTXOS` |
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 will be better than the latter below, since sub transactions are morally part of a transaction and LEDGER
historically was a rule that validated a single transaction.
CIP-0118/README-nested.md
Outdated
4. `subTxIds : ℙ TxId` | ||
- IDs of sub-transactions in the batch |
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.
Why not include subTxs
in the TxBody
, instead of putting them into Tx
and having hashes here?
One less indirection that we would need to check
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.
The short answer is that Agda made recursive types difficult in certain cases (including ones where there is a set of Tx's inside of Tx). In the Haskell prototype, it is done as you suggest I believe.
CIP-0118/README-nested.md
Outdated
4. `subTxIds : ℙ TxId` | ||
- IDs of sub-transactions in the batch | ||
|
||
**Decision required** It could be better to include the sub-transactions in the body directly, or possibly in the script integrity hash |
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.
People hate script integrity hash, so we should go in the opposite direction and just include sub transaction in the body
CIP-0118/README-nested.md
Outdated
|
||
- `RdmrPtr ⇀ Redeemer` structure inside the body | ||
- datums inside the body | ||
- `requiredObservers` scripts that are checked by a transaction but are not for the purpose of validating a specific action |
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.
You can instead link to this CIP: #749
Co-authored-by: Alexey Kuleshevich <[email protected]>
@polinavino Can you update the Rendered Proposal link in the top comment? It is still linked to the first README. Some people are reading that one instead of the latest README-nested, and this is causing confusion among people trying to learn about this CIP. |
@polinavino I'd would suggest getting rid of all other versions of README in this PR and only keep the single |
@polinavino I have to agree completely with @lehins's suggestion as the proper way to clean up the problem @fallen-icarus pointed out. Applying updates to a file other than If needing to keep references to the other implementations, I would recommend perhaps a short-term solution of stripping the non-working files down to differences with the main working file... and then ultimately including these in the Rationale along with any other alternatives not taken. |
i left just the README.md which is the nested transactions one, and renamed the CIP to match |
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