Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/input-output-hk/plutus in…
Browse files Browse the repository at this point in the history
…to effectfully/error-handling/polish-evaluation-errors
  • Loading branch information
effectfully committed May 23, 2024
2 parents 0aaf06f + 5771700 commit b61398d
Show file tree
Hide file tree
Showing 45 changed files with 3,693 additions and 96 deletions.
49 changes: 42 additions & 7 deletions .github/workflows/add-triage-label.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
# Whenever a new issue is opened, this workflow adds the "status: needs triage"
# label, unless the issue already has one of the "Internal" labels.

name: Add Triage Label
on:
issues:
types:
- reopened
- opened

jobs:
add-triage-label:
runs-on: ubuntu-latest
Expand All @@ -13,10 +17,41 @@ jobs:
- name: Run
uses: actions/github-script@v7
with:
script: |
github.rest.issues.addLabels({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
labels: ["status: needs triage"]
})
script: |
const INTERNAL_LABELS = ["Internal", "status: triaged"];
async function getIssueLabels() {
const { data: labels } = await github.rest.issues.listLabelsOnIssue({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number
});
return labels.map(label => label.name);
}
async function issueHasInternalLabels() {
const labels = await getIssueLabels();
return INTERNAL_LABELS.some(item => labels.includes(item));
}
async function addNeedsTriageLabelToIssue() {
await github.rest.issues.addLabels({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
labels: ["status: needs triage"]
});
}
try {
if (!await issueHasInternalLabels()) {
await addNeedsTriageLabelToIssue();
}
} catch (error) {
core.setFailed(`Error: ${error}`);
}
2 changes: 1 addition & 1 deletion .github/workflows/longitudinal-benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
run: git config core.hooksPath no-hooks

- name: Store benchmark result
uses: benchmark-action/github-action-benchmark@v1.19.3
uses: benchmark-action/github-action-benchmark@v1.20.3
with:
name: Plutus Benchmarks
tool: 'customSmallerIsBetter'
Expand Down
25 changes: 17 additions & 8 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,41 @@ name: Nightly Test Suite
on:
schedule:
- cron: 0 0 * * * # daily at midnight

workflow_dispatch: # or manually dispatch the job
inputs:
hedgehog-tests:
description: Numer of tests to run (--hedgehog-tests XXXXX)
required: false
default: "50000"

env:
HEDGEHOG_TESTS: ${{ github.event.inputs.hedgehog-tests || 50000 }}

jobs:
nightly-test-suite:
timeout-minutes: 14400
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Quick Install Nix
uses: cachix/install-nix-action@V27
with:
extra_nix_config: |
experimental-features = nix-command flakes
accept-flake-config = true
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@main

- name: Use Magic Nix Cache
uses: DeterminateSystems/magic-nix-cache-action@main

- name: plutus-core-nightly
if: always()
run: |
pushd plutus-core
nix run --no-warn-dirty --accept-flake-config .#plutus-core-test -- --hedgehog-tests 10000
nix run --no-warn-dirty --accept-flake-config .#plutus-core-test -- --hedgehog-tests $HEDGEHOG_TESTS
popd
- name: plutus-ir-nightly
if: always()
run: |
pushd plutus-core
nix run --no-warn-dirty --accept-flake-config .#plutus-ir-test -- --hedgehog-tests 10000
nix run --no-warn-dirty --accept-flake-config .#plutus-ir-test -- --hedgehog-tests $HEDGEHOG_TESTS
popd
16 changes: 4 additions & 12 deletions RELEASE.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -75,19 +75,11 @@ This updates versions and version bounds, and assembles the changelogs.open a PR
- Choose as git tag `x.y.z.0`
- Choose as target the git commit hash which points to the release commit
- Click `Generate release notes` to automatically fill in the details of what's changed
- Create and attach pir&uplc executables to the release by running the following commands inside the repository where its HEAD is at the release commit:
-
+
[source,bash]
-------------
nix build .#hydraJobs.x86_64-linux.musl64.ghc96.pir
cp ./result/bin/pir ./pir-x86_64-linux-ghc96
nix build .#hydraJobs.x86_64-linux.musl64.ghc96.uplc
cp ./result/bin/uplc ./uplc-x86_64-linux-ghc96
-------------
- Create and attach pir&uplc executables to the release by running the following script inside the repository where its HEAD is at the release commit: `./scripts/prepare-bins.sh`. This will create `pir-x86_64-linux-ghc96` and `uplc-x86_64-linux-ghc96` executables, compress them and put in the project's root folder. Upload them to the release draft.
- Click `Publish release`.
7. Open a PR in the https://github.com/IntersectMBO/cardano-haskell-packages[CHaP repository] for publishing the new version. Run `./scripts/add-from-github.sh "https://github.com/IntersectMBO/plutus" COMMIT-SHA LIST-OF-UPDATED-PACKAGES` (see https://github.com/IntersectMBO/cardano-haskell-packages#-from-github[the README on CHaP]). Example: https://github.com/IntersectMBO/cardano-haskell-packages/pull/394.
7. Open a PR in the https://github.com/IntersectMBO/cardano-haskell-packages[CHaP repository] for publishing the new version. +
If you are making PR from your own fork then don't forget to sync your fork with the upstream first. +
Run `./scripts/add-from-github.sh "https://github.com/IntersectMBO/plutus" COMMIT-SHA LIST-OF-UPDATED-PACKAGES` (see https://github.com/IntersectMBO/cardano-haskell-packages#-from-github[the README on CHaP]). Example: https://github.com/IntersectMBO/cardano-haskell-packages/pull/764.
- If issues are found, create a release branch `release/x.y.z`, fix the issues on master, backport the fixes to `release/x.y.z`, tag `x.y.z.0-rc2`, and go to step 4.
- Why not just fix the issues on master and tag `x.y.z.0-rc2` from master?
It is desirable to minimize the amount of change between `rc1` and `rc2`, because it may reduce the tests and checks that need to be performed against `rc2`.
Expand Down
9 changes: 0 additions & 9 deletions doc/read-the-docs-site/plutus-doc.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,6 @@ source-repository head
type: git
location: https://github.com/IntersectMBO/plutus

flag defer-plugin-errors
description:
Defer errors from the plugin, useful for things like Haddock that can't handle it.

default: False
manual: True

common lang
default-language: Haskell2010
default-extensions:
Expand All @@ -47,8 +40,6 @@ common lang
-fobject-code -fno-ignore-interface-pragmas
-fno-omit-interface-pragmas

if flag(defer-plugin-errors)

common ghc-version-support
-- See the section on GHC versions in CONTRIBUTING
if (impl(ghc <9.6) || impl(ghc >=9.7))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

### Added

- Primitives `integerToByteString` and `byteStringToInteger` are added to PlutusV2,
enabled at protocol version 10.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
### Removed

- `UnknownBuiltin` and `UnknownBuiltinType` in #6064.
5 changes: 1 addition & 4 deletions plutus-core/plutus-core/src/PlutusCore/Error.hs
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ throwingEither r e = case e of

-- | An error encountered during parsing.
data ParserError
= UnknownBuiltinType !T.Text !SourcePos
| BuiltinTypeNotAStar !T.Text !SourcePos
= BuiltinTypeNotAStar !T.Text !SourcePos
| UnknownBuiltinFunction !T.Text !SourcePos ![T.Text]
| InvalidBuiltinConstant !T.Text !T.Text !SourcePos
deriving stock (Eq, Ord, Generic)
Expand Down Expand Up @@ -171,8 +170,6 @@ instance Pretty SourcePos where
pretty = pretty . sourcePosPretty

instance Pretty ParserError where
pretty (UnknownBuiltinType s loc) =
"Unknown built-in type" <+> squotes (pretty s) <+> "at" <+> pretty loc
pretty (BuiltinTypeNotAStar ty loc) =
"Expected a type of kind star (to later parse a constant), but got:" <+>
squotes (pretty ty) <+> "at" <+> pretty loc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@ data MachineError fun
| BuiltinTermArgumentExpectedMachineError
-- ^ A builtin expected a term argument, but something else was received.
| UnexpectedBuiltinTermArgumentMachineError
-- ^ A builtin received a term argument when something else was expected.
| UnknownBuiltin fun
-- ^ A builtin received a term argument when something else was expected
| NonConstrScrutinized
| MissingCaseBranch Word64
deriving stock (Show, Eq, Functor, Generic)
Expand Down Expand Up @@ -160,8 +159,6 @@ instance (HasPrettyDefaults config ~ 'True, Pretty fun) =>
"A builtin received a term argument when something else was expected"
prettyBy _ (UnliftingMachineError unliftingError) =
pretty unliftingError
prettyBy _ (UnknownBuiltin fun) =
"Encountered an unknown built-in function:" <+> pretty fun
prettyBy _ NonConstrScrutinized =
"A non-constructor value was scrutinized in a case expression"
prettyBy _ (MissingCaseBranch i) =
Expand Down
123 changes: 86 additions & 37 deletions plutus-ledger-api/exe/analyse-script-events/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import Data.Primitive.PrimArray qualified as P
import Data.SatInt (fromSatInt)
import System.Directory.Extra (listFiles)
import System.Environment (getArgs, getProgName)
import System.FilePath (isExtensionOf)
import System.FilePath (isExtensionOf, takeFileName)
import System.IO (stderr)
import Text.Printf (hPrintf, printf)

Expand Down Expand Up @@ -302,6 +302,70 @@ countBuiltins eventFiles = do
P.itraversePrimArray_ printEntry finalCounts
where printEntry i c = printf "%-35s %12d\n" (show (toEnum i :: DefaultFun)) c


data EvaluationResult = OK ExBudget | Failed | DeserialisationError

-- Convert to a string for use in an R frame
toRString :: EvaluationResult -> String
toRString = \case
OK _ -> "T"
Failed -> "F"
DeserialisationError -> "NA"

-- Print out the actual and claimed CPU and memory cost of every script.
analyseCosts :: EventAnalyser
analyseCosts ctx _ ev =
case ev of
PlutusV1Event ScriptEvaluationData{..} _ ->
let result =
case deserialiseScript PlutusV1 dataProtocolVersion dataScript of
Left _ -> DeserialisationError
Right script ->
case
V1.evaluateScriptRestricting
dataProtocolVersion
V1.Quiet
ctx
dataBudget
script
dataInputs
of
(_, Left _) -> Failed
(_, Right cost) -> OK cost
in printCost result dataBudget

PlutusV2Event ScriptEvaluationData{..} _ ->
let result =
case deserialiseScript PlutusV2 dataProtocolVersion dataScript of
Left _ -> DeserialisationError
Right script ->
case
V2.evaluateScriptRestricting
dataProtocolVersion
V2.Quiet
ctx
dataBudget
script
dataInputs
of
(_, Left _) -> Failed
(_, Right cost) -> OK cost
in printCost result dataBudget

where printCost :: EvaluationResult -> ExBudget -> IO ()
printCost result claimedCost =
let (claimedCPU, claimedMem) = costAsInts claimedCost
in case result of
OK cost ->
let (actualCPU, actualMem) = costAsInts cost
in printf "%15d %15d %15d %15d %2s\n" actualCPU claimedCPU actualMem claimedMem (toRString result)
-- Something went wrong; print the cost as "NA" ("Not Available" in R) so that R can
-- still process it.
_ ->
printf "%15s %15d %15s %15d %2s\n" "NA" claimedCPU "NA" claimedMem (toRString result)
costAsInts :: ExBudget -> (Int, Int)
costAsInts (ExBudget (V2.ExCPU cpu) (V2.ExMemory mem)) = (fromSatInt cpu, fromSatInt mem)

-- Extract the script from an evaluation event and apply some analysis function
analyseUnappliedScript
:: (Term NamedDeBruijn DefaultUni DefaultFun () -> IO ())
Expand All @@ -325,6 +389,10 @@ analyseOneFile
-> IO ()
analyseOneFile analyse eventFile = do
events <- loadEvents eventFile
printf "# %s\n" $ takeFileName eventFile
-- Print the file in the output so we can narrow down the location of
-- interesting/anomalous data. This may not be helpful for some of the
-- analyses.
case ( mkContext V1.mkEvaluationContext (eventsCostParamsV1 events)
, mkContext V2.mkEvaluationContext (eventsCostParamsV2 events)
) of
Expand Down Expand Up @@ -354,29 +422,6 @@ analyseOneFile analyse eventFile = do
Nothing -> putStrLn "*** ctxV2 missing ***"


max_tx_ex_steps :: Double
max_tx_ex_steps = 10_000_000_000

max_tx_ex_mem :: Double
max_tx_ex_mem = 14_000_000

-- Print out the CPU and memory budgets of each script event. These are the costs
-- paid for by the submitters, not the actual costs consumed during execution.
-- TODO: add a version that tells us the actual execution costs.
getBudgets :: EventAnalyser
getBudgets _ctx _params ev =
let printFractions d =
let ExBudget (V2.ExCPU cpu) (V2.ExMemory mem) = dataBudget d
in printf "%15d %10.8f %15d %10.8f\n"
(fromSatInt cpu :: Int)
((fromSatInt cpu) / max_tx_ex_steps)
(fromSatInt mem :: Int)
((fromSatInt mem) / max_tx_ex_mem)

in case ev of
PlutusV1Event evdata _expected -> printFractions evdata
PlutusV2Event evdata _expected -> printFractions evdata

main :: IO ()
main =
let analyses =
Expand All @@ -400,28 +445,32 @@ main =
, "count the total number of occurrences of each builtin in validator scripts"
, countBuiltins
)
, ( "budgets"
, "print (claimed) budgets of scripts"
, putStrLn " cpu cpuFraction mem memFraction"
`thenDoAnalysis` getBudgets
, ( "costs"
, "print actual and claimed costs of scripts"
, putStrLn " cpuActual cpuClaimed memActual memClaimed status"
`thenDoAnalysis` analyseCosts
)
]

doAnalysis analyser = mapM_ (analyseOneFile analyser)
(prelude `thenDoAnalysis` analyser) files = prelude >> doAnalysis analyser files

usage = do
getProgName >>= hPrintf stderr "Usage: %s <dir> <analysis>\n"
getProgName >>= hPrintf stderr "Usage: %s <analysis> [<dir>]\n"
hPrintf stderr "Analyse the .event files in <dir> (default = current directory)\n"
hPrintf stderr "Avaliable analyses:\n"
mapM_ printDescription analyses
where printDescription (n,h,_) = hPrintf stderr " %-16s: %s\n" n h

go name dir =
case find (\(n,_,_) -> n == name) analyses of
Nothing -> printf "Unknown analysis: %s\n" name >> usage
Just (_,_,analysis) ->
filter ("event" `isExtensionOf`) <$> listFiles dir >>= \case
[] -> printf "No .event files in %s\n" dir
eventFiles -> analysis eventFiles

in getArgs >>= \case
[dir, name] ->
case find (\(n,_,_) -> n == name) analyses of
Nothing -> printf "Unknown analysis: %s\n" name >> usage
Just (_,_,analysis) ->
filter ("event" `isExtensionOf`) <$> listFiles dir >>= \case
[] -> printf "No event files in %s\n" dir
eventFiles -> analysis eventFiles
_ -> usage
[name] -> go name "."
[name, dir] -> go name dir
_ -> usage
Loading

0 comments on commit b61398d

Please sign in to comment.