Write down first e2e script context test for v3.

This commit is contained in:
KtorZ 2024-08-09 19:04:25 +02:00
parent 821f7bd8c7
commit 62b1b932f9
No known key found for this signature in database
GPG Key ID: 33173CB6F77F4277
11 changed files with 423 additions and 2 deletions

View File

@ -4,7 +4,7 @@ use super::{
Error, Error,
}; };
use crate::{ use crate::{
ast::{FakeNamedDeBruijn, NamedDeBruijn, Program}, ast::{Data, FakeNamedDeBruijn, NamedDeBruijn, Program},
machine::cost_model::ExBudget, machine::cost_model::ExBudget,
tx::script_context::{DataLookupTable, ScriptVersion, TxInfoV1, TxInfoV2, TxInfoV3}, tx::script_context::{DataLookupTable, ScriptVersion, TxInfoV1, TxInfoV2, TxInfoV3},
PlutusData, PlutusData,
@ -44,7 +44,14 @@ pub fn eval_redeemer(
} }
.apply_data(redeemer.data.clone()) .apply_data(redeemer.data.clone())
.apply_data(script_context.to_plutus_data()), .apply_data(script_context.to_plutus_data()),
ScriptContext::V3 { .. } => program.apply_data(script_context.to_plutus_data()), ScriptContext::V3 { .. } => {
program
// FIXME: Temporary, but needed until https://github.com/aiken-lang/aiken/pull/977
// is implemented.
.apply_data(Data::constr(0, vec![]))
.apply_data(Data::constr(0, vec![]))
.apply_data(script_context.to_plutus_data())
}
}; };
let mut eval_result = if let Some(costs) = cost_mdl_opt { let mut eval_result = if let Some(costs) = cost_mdl_opt {

View File

@ -0,0 +1,8 @@
# Aiken compilation artifacts
artifacts/
# Aiken's project working directory
build/
# Aiken's default documentation export
docs/
*.cbor
*.log

View File

@ -0,0 +1,191 @@
# V3 Script Context Tests
This project contains a few handcrafted Plutus V3 validators and transactions
whose sole purpose is to test the interpretation of the `ScriptContext` from
within an Aiken's validators.
So validators are meant to work hand-in-hand with an associated context.
Because we can't have fully static context (since they contain the validator
and its hash), we define _templates_.
Everything is a bit clunky, but steps have been captured in a `test.sh` script
for convenience.
## How to use
```
./test.sh [VALIDATOR_TITLE]
```
## Test Coverage
- Purpose
- [x] spend
- [ ] mint
- [ ] withdraw
- [ ] publish
- [ ] voting
- [ ] proposing
- Transaction body
- [x] inputs
- reference inputs
- [x] none
- [ ] some
- outputs
- [ ] none
- [ ] some
- [x] fee
- [ ] mint
- certificates
- [ ] none
- some
- Register credential
- [ ] no deposit
- [ ] with deposit
- Unregister credential
- [ ] no deposit
- [ ] with deposit
- [ ] Delegate
- [ ] Register & delegate credential
- [ ] Register drep
- [ ] Unregister drep
- [ ] Update drep
- [ ] Register pool
- [ ] Retire pool
- [ ] Delegate CC
- [ ] Retire CC
- withdrawals
- [ ] none
- [ ] some
- [ ] validity range
- extra signatories
- [x] none
- [ ] some
- [ ] redeemers
- [ ] datums
- votes
- [ ] none
- [ ] some
- proposal procedures
- [ ] none
- [ ] some
- current treasury
- [ ] with
- [ ] without
- treasury donation
- [ ] with
- [ ] without
- Address
- [ ] type-0 (key | key)
- [ ] type-1 (script | key)
- [ ] type-2 (key | script)
- [ ] type-3 (script | script)
- [ ] type-4 (key | ptr)
- [ ] type-5 (script | ptr)
- [ ] type-6 (key | ø)
- [x] type-7 (key | ø)
- Value
- [x] only ada
- [ ] multi-assets
- Output datum
- [ ] none
- [ ] hash
- [x] inline
- Output script
- [x] none
- [ ] inline
- Governance Action
- parameter change
- [ ] with action id
- [ ] without action id
- hardfork initiation
- [ ] with action id
- [ ] without action id
- treasuryWithdrawals
- [ ] with constitution
- [ ] without constitution
- no confidence
- [ ] with action id
- [ ] without action id
- update committee
- [ ] with action id
- [ ] without action id
- new constitution
- [ ] with action id
- [ ] without action id
- [ ] info action
- Vote
- [ ] No
- [ ] Yes
- [ ] Abstain
- Voter
- [ ] CC
- [ ] DRep
- [ ] SPO
- ChangedParameters
- [ ] 0: coin
- [ ] 1 : coin
- [ ] 2 : uint .size 4
- [ ] 3 : uint .size 4
- [ ] 4 : uint .size 2
- [ ] 5 : coin
- [ ] 6 : coin
- [ ] 7 : epoch_interval
- [ ] 8 : uint .size 2
- [ ] 9 : nonnegative_interval
- [ ] 10 : unit_interval
- [ ] 11 : unit_interval
- [ ] 16 : coin
- [ ] 17 : coin
- [ ] 18 : costmdls
- [ ] 19 : ex_unit_prices
- [ ] 20 : ex_units
- [ ] 21 : ex_units
- [ ] 22 : uint .size 4
- [ ] 23 : uint .size 2
- [ ] 24 : uint .size 2
- [ ] 25 : pool_voting_thresholds
- [ ] 26 : drep_voting_thresholds
- [ ] 27 : uint .size 2
- [ ] 28 : epoch_interval
- [ ] 29 : epoch_interval
- [ ] 30 : coin
- [ ] 31 : coin
- [ ] 32 : epoch_interval
- [ ] 33 : nonnegative_interval}
- Constitution
- [ ] with guardrail script
- [ ] without guardrail script
- Value
- [x] pure ada
- [ ] native assets
- Credential
- [ ] key
- [x] script
- Delegatee
- [ ] pool
- [ ] drep
- [ ] pool + drep
- DRep
- [ ] key
- [ ] script
- [ ] abstain
- [ ] no confidence
- Boundary
- [ ] closed
- [ ] open

View File

@ -0,0 +1,7 @@
# This file was generated by Aiken
# You typically do not need to edit this file
requirements = []
packages = []
[etags]

View File

@ -0,0 +1,5 @@
name = "script_context/v3"
version = "0.0.0"
plutus = "v3"
license = "Apache-2.0"
description = "Aiken contracts for project 'script_context/v3'"

View File

@ -0,0 +1 @@
81a300581d70{{ VALIDATOR_HASH }}011a3b9aca00028201d818{{ DATUM }}

View File

@ -0,0 +1,34 @@
[
{ 0:
[ [h'0000000000000000000000000000000000000000000000000000000000000000', 0]
]
, 1:
[ [h'6011111111111111111111111111111111111111111111111111111111', 1000000000]
]
, 2: 42
, 11: h'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'
, 13:
[ [h'0000000000000000000000000000000000000000000000000000000000000000', 0]
]
, 16:
[ h'6000000000000000000000000000000000000000000000000000000000', 1000000000
]
, 17: 1
},
{ 5: [[0, 0, 121([]), [1000000, 100000000]]]
, 7: [h'{{ VALIDATOR }}']
},
true,
null
]

View File

@ -0,0 +1 @@
../../../../../../stdlib/lib/aiken

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,53 @@
#!/usr/bin/env bash
TITLE=$1
if [ -z $TITLE ]; then
echo -e "\033[31mMissing argument: \033[1mVALIDATOR_TITLE\033[0m"
echo ""
echo -e "\033[1mUsage: \033[0m"
echo " test.sh {ACCEPTANCE_TEST}"
echo ""
echo -e "\033[1mExample: \033[0m"
echo " test.sh basic"
exit 1
fi
AIKEN=${2:-"cargo run -r --quiet --"}
if ! command -v jq &> /dev/null
then
echo "\033[1mjq\033[0m missing from system but required."
exit 1
fi
if ! command -v cbor-diag &> /dev/null
then
echo "\033[1mcbor-diag\033[0m missing from system but required."
exit 1
fi
$AIKEN build --filter-traces all -t verbose
if [ $? -ne 0 ]; then
exit $?
fi
BLUEPRINT=$(jq ".validators[] | select(.title|contains(\"$TITLE\"))" plutus.json)
VALIDATOR_HASH=$(echo $BLUEPRINT | jq -r .hash)
VALIDATOR=$(echo $BLUEPRINT | jq -r .compiledCode)
DATUM=$(cbor-diag --to hex --from diag <<< "h'$(cat ctx/$TITLE/datum.cbor)'")
sed "s/{{ VALIDATOR_HASH }}/$VALIDATOR_HASH/" ctx/$TITLE/resolved_inputs.template \
| sed "s/{{ DATUM }}/$DATUM/" \
> ctx/$TITLE/resolved_inputs.cbor
sed "s/{{ VALIDATOR }}/$VALIDATOR/" ctx/$TITLE/tx.template \
| sed "s/{{ VALIDATOR_HASH }}/$VALIDATOR_HASH/" \
| cbor-diag --to hex --from diag \
> ctx/$TITLE/tx.cbor
$AIKEN tx simulate \
ctx/$TITLE/tx.cbor \
ctx/inputs.cbor \
ctx/$TITLE/resolved_inputs.cbor

View File

@ -0,0 +1,69 @@
use aiken/dict
use aiken/transaction.{
InlineDatum, Input, Output, OutputReference, ScriptContext, Spend, Spending,
}
use aiken/transaction/credential.{Address, ScriptCredential}
use aiken/transaction/value
validator {
fn spend(_tmp1: Void, _tmp2: Void, ctx: ScriptContext) {
let void: Data = Void
expect
#"78ec148ea647cf9969446891af31939c5d57b275a2455706782c6183ef0b62f1" == ctx.transaction.id
expect
Spending(
OutputReference {
transaction_id: #"0000000000000000000000000000000000000000000000000000000000000000",
output_index: 0,
},
Some(void),
) == ctx.info
trace @"inputs": ctx.transaction.inputs
expect [
Input {
output_reference: OutputReference { transaction_id, output_index: 0 },
output: Output {
address,
value: resolved_input_value,
datum: InlineDatum(_),
reference_script: None,
},
},
] = ctx.transaction.inputs
expect
transaction_id == #"0000000000000000000000000000000000000000000000000000000000000000"
expect resolved_input_value == value.from_lovelace(1000000000)
expect Address {
payment_credential: ScriptCredential(_),
stake_credential: None,
} = address
expect [] = ctx.transaction.reference_inputs
expect [] = ctx.transaction.extra_signatories
expect 42 == ctx.transaction.fee
expect
[
Pair(Spend(
OutputReference {
transaction_id: #"0000000000000000000000000000000000000000000000000000000000000000",
output_index: 0,
},
),
void),
] == ctx.transaction.redeemers
expect [] == dict.to_pairs(ctx.transaction.datums)
True
}
}