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

runStep does result in InsufficientFunds when using a threadToken #3546

Closed
ch1bo opened this issue Jul 14, 2021 · 2 comments · Fixed by #3625
Closed

runStep does result in InsufficientFunds when using a threadToken #3546

ch1bo opened this issue Jul 14, 2021 · 2 comments · Fixed by #3625
Labels

Comments

@ch1bo
Copy link

ch1bo commented Jul 14, 2021

Area

[] Plutus Foundation Related to the GHC plugin, Haskell-to-Plutus compiler, on-chain code
[x] Plutus Application Framework Related to the Plutus application backend (PAB), emulator, Plutus libraries
[] Marlowe Related to Marlowe
[] Other Any other topic (Playgrounds, etc.)

Summary

When using a thread token with Plutus.Contract.StateMachine, runInitialise correctly pays it to the script, but a following runStep fails with InsufficientFunds.

The issue was observed in our integrated code as well as a in minimal reproducer example:

λ cabal exec sm-repro
Slot 00000: TxnValidate af5e6d25b5ecb26185289a03d50786b7ac4425b21849143ed7e18bcd70dc4db8
Slot 00000: SlotAdd Slot 1
Slot 00001: 00000000-0000-4000-8000-000000000000 {Contract instance for wallet 1}:
  Contract instance started
Slot 00001: *** CONTRACT LOG: "Forged thread token: ThreadToken {ttOutRef = TxOutRef {txOutRefId = af5e6d25b5ecb26185289a03d50786b7ac4425b21849143ed7e18bcd70dc4db8, txOutRefIdx = 6}, ttCurrencySymbol = 6611d7baf973a1d9e64c60c546cafbe94a3ab7ce4928dd97d768c913066bc4d6}"
Slot 00001: W1: TxSubmit: 3f1ebb918adf02ccdcdd8ff82f354e2bc346f180b734cdf41c8a4529cf9c9b54
Slot 00001: TxnValidate 3f1ebb918adf02ccdcdd8ff82f354e2bc346f180b734cdf41c8a4529cf9c9b54
Slot 00001: SlotAdd Slot 2
Slot 00002: *** CONTRACT LOG: "Initialized state machine"
Slot 00002: *** CONTRACT STOPPED WITH ERROR: "\"SMCContractError (WalletError (InsufficientFunds \\\"Total: Value (Map [(,Map [(\\\\\\\"\\\\\\\",99992792)])]) expected: Value (Map [(6611d7baf973a1d9e64c60c546cafbe94a3ab7ce4928dd97d768c913066bc4d6,Map [(0x715d66b53561035ba0b0881776b7d2054c73d3b0eb1fb6aabb0229d36345b33a,1)])])\\\"))\""

Steps to reproduce

Steps to reproduce the behavior:

  1. Checkout https://github.com/input-output-hk/hydra-poc/tree/plutus-sm-repro
  2. cabal build hydra-plutus:exe:sm-repro
  3. cabal exec sm-repro
  4. See error

Expected behavior

When using the Plutus.Contract.Statemachine interface, we expect that thread tokens are handled for us and that no additional constraints / lookups would be necessary for handling the state machine's thread token.

System info (please complete the following information):

Additional context

I did look into the Auction use case (which we took as an example originally) and while the tests do seem to pass:

> defaultMain tests
auction
  run an auction:                    OK (1.16s)
  run an auction with multiple bids: OK (1.53s)
  QuickCheck property:               OK
    +++ OK, passed 1 test (100% FIXME).
All 3 tests passed (2.70s)
*** Exception: ExitSuccess

running the auctionTrace1 with runEmulatorTraceIO is blocking (?) and simply activating the auctionSeller contract (which is quite similar to the reproducer contract) gives me also the InsufficientFunds error !?

> runEmulatorTraceIO $ void $ Trace.activateContractWallet w1 seller
Slot 00000: TxnValidate af5e6d25b5ecb26185289a03d50786b7ac4425b21849143ed7e18bcd70dc4db8
Slot 00000: SlotAdd Slot 1
Slot 00001: 00000000-0000-4000-8000-000000000000 {Contract instance for wallet 1}:
  Contract instance started
Slot 00001: 00000000-0000-4000-8000-000000000000 {Contract instance for wallet 1}:
  Contract log: Object (fromList [("contents",Object (fromList [("contents",Object (fromList [("contents",Object (fromList [("contents",String "Total: Value (Map []) expected: Value (Map [(ffff,Map [(\"token\",1)])])"),("tag",String "InsufficientFunds")])),("tag",String "WalletError")])),("tag",String "SMCContractError")])),("tag",String "AuctionFailed")])
Slot 00001: *** CONTRACT STOPPED WITH ERROR: "StateMachineContractError (SMCContractError (WalletError (InsufficientFunds \"Total: Value (Map []) expected: Value (Map [(ffff,Map [(\\\"token\\\",1)])])\")))"
Slot 00001: SlotAdd Slot 2
@ch1bo ch1bo added the bug label Jul 14, 2021
@ch1bo
Copy link
Author

ch1bo commented Jul 14, 2021

Working hypothesis: The wallet thinks it needs to provide the thread token value although it does not need to, as we can spend that using the redeemer (input). The tx constraints should be in place and the wallet just "gives up too early".

@sjoerdvisscher
Copy link
Contributor

The reason running the auctionSeller fails is because it needs to be run with auctionEmulatorCfg which will create the "ffff" token.

The bug was that in our tests, the transition always ignores the old value, while in your case the old value is passed on as the new value. This caused the transaction to try to output 2 thread tokens. A workaround could be to set the value to mempty. But the fix should be merged soon.

I have added your minimal repro as a test case, thanks for that!

sjoerdvisscher added a commit that referenced this issue Jul 28, 2021
…step (#3625)

* Add test that reproduces the ThreadToken bug

* Remove thread token from previous value of a state machine step

Fixes #3546

* Add some comments

* updateMaterialized
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants