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

Replace Set TxIn with [TxIn] to fix StateMachine.getInput #594

Merged
5 commits merged into from
Jul 15, 2022

Conversation

ghost
Copy link

@ghost ghost commented Jul 14, 2022

This PR tries to fix the problem with StateMachine.getInput by properly querying the redeemer of the input by its index.


Pre-submit checklist:

  • Branch
    • Tests are provided (if possible)
    • Commit sequence broadly makes sense
    • Key commits have useful messages
    • Formatting, PNG optimization, etc. are updated
  • PR
    • Self-reviewed the diff
    • Useful pull request description
    • Reference the ADR in the PR and reference the PR in the ADR (if revelant)
    • Reviewer requested

Comment on lines -81 to +82
, _citxInputs = txInputs
, _citxInputs = Set.toList txInputs
Copy link
Author

Choose a reason for hiding this comment

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

This is incorrect but to fix it we need to fix the Tx from plutus-core. Or create our own Tx with [TxIn] instead of Set TxIn.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add a TODO and a story for this? I guess it will need to be done once next-node is merged in main.

Copy link
Contributor

Choose a reason for hiding this comment

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

No need imho, this is good enough.

Comment on lines -40 to +43
inputs =
-- We need to sort the inputs as the order is important
-- to find the corresponding redeemers
inputs = sort $
Copy link
Author

Choose a reason for hiding this comment

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

Here is the correct order of inputs as we sort cardano-api's TxIn with an indented Ord instance.

Copy link
Contributor

Choose a reason for hiding this comment

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

Good catch, I would have thought they would already be in the right order!

listToMaybe $ mapMaybe Tx.inScripts $ filter (\Tx.TxIn{Tx.txInRef} -> outRef == txInRef) $ Set.toList $ _citxInputs tx
-- We retrieve the correspondent redeemer according to the index of txIn in the list
let findRedeemer (ix, _) = Map.lookup (Tx.RedeemerPtr Tx.Spend ix) (_citxRedeemers tx)
Ledger.Redeemer r <- listToMaybe $ mapMaybe findRedeemer $ filter (\(_, Tx.TxIn{Tx.txInRef}) -> outRef == txInRef) $ zip [0..] $ _citxInputs tx
Copy link
Author

Choose a reason for hiding this comment

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

Here is where we use the knowledge of inputs order to get the redeemer. I hope I got the idea correctly that index of TxIn is binded to the redeemer pointer.

Source: IntersectMBO/cardano-node#3389 (comment)

Maybe instead of relying on their order it's better to include the index. Set TxIn ~> Set (TxInIndx, TxIn), that would make it more explicit.

Copy link
Contributor

Choose a reason for hiding this comment

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

The fact that we now have a list instead of a set makes it clear enough that the order is significant in my opinion.

plutus-ledger/src/Ledger/Tx/CardanoAPI.hs Show resolved Hide resolved
@ghost ghost mentioned this pull request Jul 14, 2022
8 tasks
where
withHash (ConsumeScriptAddress val red dat) =
-- TODO: the index of the txin is probably incorrect as we take it from the set.
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this going to have bad consequences?

Copy link
Author

Choose a reason for hiding this comment

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

My understanding is that this PR makes a move from a completely broken state to a semi-broken state. Instead of not getting redeemers at all, we will start choosing them but with a big chance of selecting the incorrect ones.

Copy link
Author

@ghost ghost Jul 14, 2022

Choose a reason for hiding this comment

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

Speaking of fromOnChainTx in particular, I think withHash function was useless already since we use the Tx here, and the inputs have an empty TxInType here as I understand. And we might skip the ConsumeScriptAddress case at all always return mempty.

Copy link
Contributor

Choose a reason for hiding this comment

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

As long as the redeemer pointer points to the right input, I think this is totally fine.

To show that there is a relation between the list and the indexes, I think it's better to do the Set.toList once and pass the list to validators.

Copy link
Author

Choose a reason for hiding this comment

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

As long as the redeemer pointer points to the right input, I think this is totally fine.

There is a problem here that we take a set that could break the order. I looked at usages of the fromOnChainTx and there is no anything that directly relies on that order. But would be nice to fix Tx type.

where
withHash (ConsumeScriptAddress val red dat) =
-- TODO: the index of the txin is probably incorrect as we take it from the set.
Copy link
Contributor

Choose a reason for hiding this comment

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

As long as the redeemer pointer points to the right input, I think this is totally fine.

To show that there is a relation between the list and the indexes, I think it's better to do the Set.toList once and pass the list to validators.

Comment on lines -40 to +43
inputs =
-- We need to sort the inputs as the order is important
-- to find the corresponding redeemers
inputs = sort $
Copy link
Contributor

Choose a reason for hiding this comment

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

Good catch, I would have thought they would already be in the right order!

listToMaybe $ mapMaybe Tx.inScripts $ filter (\Tx.TxIn{Tx.txInRef} -> outRef == txInRef) $ Set.toList $ _citxInputs tx
-- We retrieve the correspondent redeemer according to the index of txIn in the list
let findRedeemer (ix, _) = Map.lookup (Tx.RedeemerPtr Tx.Spend ix) (_citxRedeemers tx)
Ledger.Redeemer r <- listToMaybe $ mapMaybe findRedeemer $ filter (\(_, Tx.TxIn{Tx.txInRef}) -> outRef == txInRef) $ zip [0..] $ _citxInputs tx
Copy link
Contributor

Choose a reason for hiding this comment

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

The fact that we now have a list instead of a set makes it clear enough that the order is significant in my opinion.

@ghost ghost merged commit b7c773c into main Jul 15, 2022
@ghost ghost deleted the fix-statemachine-getinput branch July 15, 2022 13:29
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants