IntersectMBO / cardano-node

The core component that is used to participate in a Cardano decentralised blockchain.
https://cardano.org
Apache License 2.0
3.08k stars 722 forks source link

[FR] - Modify transaction submit command to expose detailed plutus error information #3737

Open Jimbo4350 opened 2 years ago

Jimbo4350 commented 2 years ago

Add the a command line option taking a filename.

The transaction submit will output to the file additional detail plutus script error information in JSON format.

The starting point is this piece of code:

 case res of
      Net.Tx.SubmitSuccess -> liftIO $ putTextLn "Transaction successfully submitted."
      Net.Tx.SubmitFail reason ->
        case reason of
          TxValidationErrorInMode err _eraInMode -> left . ShelleyTxCmdTxSubmitError . Text.pack $ show err
          TxValidationEraMismatch mismatchErr -> left $ ShelleyTxCmdTxSubmitErrorEraMismatch mismatchErr

We can pattern match on TxValidationError era to ApplyTxErr all the way to the underlying ledger type ApplyTxError.

From there we can use plutusDebug on BS.ByteString to get this data:

data PlutusDebug
  = PlutusDebugV1
      CostModel
      ExUnits
      SBS.ShortByteString
      [PV1.Data]
      ProtVer
  | PlutusDebugV2
      CostModel
      ExUnits
      SBS.ShortByteString
      [PV2.Data]
      ProtVer

Output this to the as JSON to the file.

newhoggy commented 2 years ago

LogObject TagMismatchDescription FailureDescription reconstruction PlutusDebug PlutusFailure debugPlutus PlutusDebugInfo

newhoggy commented 2 years ago

I commented out ToObject (Alonzo.UtxosPredicateFailure (AlonzoEra StandardCrypto)) and LogFormatting (Alonzo.UtxoPredicateFailure (Alonzo.AlonzoEra StandardCrypto)) instances and chased compile errors to the point where I removed these constraints from type TraceConstraints blk and found that cardano-node still compiles.

I believe this means that consensus does not yet use these constraints to push logging of these messages.

newhoggy commented 2 years ago

Repurposing this ticket. For the record, this was how the ticket was described previously:

cardano-ledger has a nice little tool that allows us to deserialise the log output of TagMismatchDescription which occurs in the node logs when a plutus scripts fails when it was expected to succeed (and vice versa). We can access a lot more information (in a more easily digestible format) via debugPlutus.

This ticket will be considered done when:

  • A new cli command cardano-cli transaction debug-script --node-log-file [--tx-file | --tx-body | --script-file | --script-hash ] [--out-file] has been created
  • This command will render debugging information for all scripts that exist in the tx or is specified via script-file/script-hash provided the relevant failure logs exist in the node log file.

Requirements

  • We need to parse the node's JSON logs to make this easier. So we should first implement a Text -> LogObject function. I suspect this should potentially be a prior separate PR.
  • We will identify the script we are interested in via it's hash. In order to do this we must first decode all TagMismatchDescription objects and deserialise the reconstruction field via FromCBOR FailureDescription. We can calculate the script hash from PlutusDebug (from the PlutusFailure constructor's ByteString via FromCBOR PlutusDebug) and compare it to the hash we are interested in. In instances where a script has been repeatedly submitted and failed to validate (or succeeded to validate when it was expected to fail) we should potentially add a timestamp in the JSON object or plain text in the stdout.
  • We are interested in both cases of the TagMismatchDescription log object (PassedUnexpectedly, FailedUnexpectedly). We are interested in the PlutusFailure Text ByteString and we should also render OnePhaseFailure as well (hence we accept any script-file and/or script-hash)
  • The PlutusFailure's ByteString can be decoded with debugPlutus and will give us PlutusDebugInfo. I've asked Jared to return more information in the failure case so we can give more debugging information.
  • We should render the debugging information as JSON or print to stdout