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

Plutus-starter: EndpointNotAvailable #3526

Closed
LendaDeAfonselio opened this issue Jul 9, 2021 · 8 comments
Closed

Plutus-starter: EndpointNotAvailable #3526

LendaDeAfonselio opened this issue Jul 9, 2021 · 8 comments
Assignees
Labels

Comments

@LendaDeAfonselio
Copy link

LendaDeAfonselio commented Jul 9, 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
[x] Other Any other topic (Playgrounds, etc.)

Summary

Hello I am trying to use the plutus-starter project to test out some contracts of my own, I am able to follow every step without problems until I try to interrupt with the endpoints, where it always seems to fail.

Steps to reproduce

Steps to reproduce the behavior:

  1. Clone 'plutus-starter`
  2. Follow the steps on the README.md file for VSCode devcontainer development (Success)
  3. Follow The Plutus Application Backend (PAB) example (Success)
  4. Start both wallet instances (Success)
  5. Get the status (Success)
  6. Lock some value using (Fails):
curl -H "Content-Type: application/json" \
  --request POST \
  --data '{"amount":{"getValue":[[{"unCurrencySymbol":""},[[{"unTokenName":""},90]]]]},"secretWord":"eagle"}' \
  http://localhost:8080/api/new/contract/instance/$INSTANCE_ID/endpoint/lock

Returns error: EndpointCallError (EndpointNotAvailable (ContractInstanceId {unContractInstanceId = 5ff489d7-4b1c-4828-afd5-424635cf87a1}) (EndpointDescription {getEndpointDescription = "lock"}))

Btw, the discord server link has expired.

Expected behavior

The "lock" operation was expected to go through, more info about the results I got the from the commands below

Screenshots and attachments

curl -s http://localhost:8080/api/new/contract/definitions | jq

[
  {
    "csrSchemas": [
      {
        "argument": {
          "contents": [
            [
              "guessWord",
              {
                "tag": "FormSchemaString"
              }
            ]
          ],
          "tag": "FormSchemaObject"
        },
        "endpointDescription": {
          "getEndpointDescription": "guess"
        }
      },
      {
        "argument": {
          "contents": [
            [
              "secretWord",
              {
                "tag": "FormSchemaString"
              }
            ],
            [
              "amount",
              {
                "tag": "FormSchemaValue"
              }
            ]
          ],
          "tag": "FormSchemaObject"
        },
        "endpointDescription": {
          "getEndpointDescription": "lock"
        }
      }
    ],
    "csrDefinition": "GameContract"
  }
]

Wallet 1:

curl -s -H "Content-Type: application/json" \
>   --request POST \
>   --data '{"caID": "GameContract", "caWallet":{"getWallet": 1}}' \
>   http://localhost:8080/api/new/contract/activate | jq

Reply:

{
  "unContractInstanceId": "5ff489d7-4b1c-4828-afd5-424635cf87a1"
}

Command: export INSTANCE_ID=5ff489d7-4b1c-4828-afd5-424635cf87a1
curl -s http://localhost:8080/api/new/contract/instance/$INSTANCE_ID/status | jq

{
  "cicCurrentState": {
    "observableState": [],
    "logs": [
      {
        "_logMessageContent": "Waiting for lock endpoint...",
        "_logLevel": "Info"
      },
      {
        "_logMessageContent": "Waiting for script to have a UTxO of at least 1 lovelace",
        "_logLevel": "Info"
      }
    ],
    "hooks": [],
    "err": null,
    "lastLogs": []
  },
  "cicContract": {
    "unContractInstanceId": "5ff489d7-4b1c-4828-afd5-424635cf87a1"
  },
  "cicWallet": {
    "getWallet": 1
  },
  "cicDefintion": "GameContract"
}

Finally:

curl -H "Content-Type: application/json" \
  --request POST \
  --data '{"amount":{"getValue":[[{"unCurrencySymbol":""},[[{"unTokenName":""},90]]]]},"secretWord":"eagle"}' \
  http://localhost:8080/api/new/contract/instance/$INSTANCE_ID/endpoint/lock

Returns error: EndpointCallError (EndpointNotAvailable (ContractInstanceId {unContractInstanceId = 5ff489d7-4b1c-4828-afd5-424635cf87a1}) (EndpointDescription {getEndpointDescription = "lock"}))

The same happens when I try to do this for Wallet 2 and the Guess endpoint.

Additional context

Did not change the code whatsoever, what am I doing incorrectly when interacting with the endpoints? Am I missing something?

System info (please complete the following information):

  • OS: Ubuntu
  • Version 20.04]
  • Plutus version or commit hash
@luigy
Copy link
Contributor

luigy commented Jul 12, 2021

Thanks for the detailed report! I was able to reproduce it and put up a fix for it.

@sorki
Copy link
Contributor

sorki commented Jul 13, 2021

@luigy note this is about not being able to call lock endpoint.

I've tried this several times (prior and after Plutus bump PR) hoping I can fix it but didn't figure it out. One of the things I've tried was turning game = lock `select` guess into game = forever $ lock `select` guess but that didn't help either.

@luigy
Copy link
Contributor

luigy commented Jul 13, 2021

@sorki hmm that's strange. Even though "lock" endpoint is not showing up this is due to way the "guess" endpoint is currently written. I have put up a temp workaround, but there is still an underlying issue that I suspect came from #3342 that I'm currently investigating as even without my changes it is expected to work

here is a clip of me calling the "lock" endpoint with my changes

plutus-starter-example-2021-07-13_15.20.49.mp4

@luigy luigy self-assigned this Jul 13, 2021
@sorki
Copy link
Contributor

sorki commented Jul 16, 2021

Tested your PR and it indeed does fix this despite my intuition. If you don't mind, I would appreciate a short explanation of what is going on with select and endpoints in this case.

@luigy
Copy link
Contributor

luigy commented Jul 17, 2021

@sorki from my understanding select will choose whichever side makes progress first and discard the other.

endpoint "name" "waits" until it gets "called" externally, whereas fundsAtAddressGeq is "making progress" soon after given that it's a loop "receiving" responses every n slots about funds and looping again or proceeding based on the results.

game = lock `select` guess

the behavior I'm observing in the case of the game contract is that in the case of guess, which executes fundsAtAddressGeq before endpoint, "makes progress" first from the pov of the pab so it continues on that side and discards lock. This leaves the contract in a state in which is waiting for funds to increase some threshold via fundsAtAddressGeq, but the lock endpoint which is the way to "add" the funds has already been discarded.

I'm still wondering if this is the intended behavior of fundsAtAddressGeq with respect to select?

The changes in the PR made endpoint the first thing happening in lock and in guess which results
on both waiting without any progress until either one gets called

@sorki
Copy link
Contributor

sorki commented Jul 19, 2021

Thank you! Helps a lot to improve my understanding of PAB.

@szg251
Copy link

szg251 commented Jul 31, 2021

@luigy @sorki I am not 100% sure, but reading the Plutus source code, I found that fundsAtAddressGeq waits untils it finds enough assets in the utxo map:
https://github.com/input-output-hk/plutus/blob/master/plutus-contract/src/Plutus/Contract/Request.hs#L298

When implementing the value check logic after using the utxoAt worked for me, but doesn't really seem necessary at all:

  utxos <- utxoAt gameAddress

  let presentVal = Haskell.foldMap (Ledger.txOutValue . Ledger.txOutTxOut) utxos
  let hasEnoughLovelace = presentVal `Ledger.Value.geq` Ada.lovelaceValueOf 1
  logWarn @Haskell.String $
    if hasEnoughLovelace
      then "There is enough lovelace in the script address"
      else "There is not enough lovelace in the script address"

@luigy
Copy link
Contributor

luigy commented Aug 25, 2021

@gege251 fundsAtAddressGeq stills behaves a bit funny as in it actually doesn't quite "block" as expected as it is polling on every slot for utxos, which I've improved on a bit on #3789 but still not the full solution.

With that said in input-output-hk/plutus-starter#26 the behavior of the contract was changed to not wait on having funds any longer so now both endpoint are always available and input-output-hk/plutus-starter#28 made it so the instance can take requests indefinitely instead of stopping after the first one is handled.

Closing this, but please reopen if you are still running into issue with the most recent version.

@luigy luigy closed this as completed Aug 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants