Fix validator's fallback handler generation

Fixes #1015.
This commit is contained in:
KtorZ 2024-09-10 10:47:41 +02:00
parent 5879dcfd4c
commit 7741be64f8
No known key found for this signature in database
GPG Key ID: 33173CB6F77F4277
5 changed files with 155 additions and 15 deletions

View File

@ -8,6 +8,7 @@
### Changed
- **aiken-lang**: Fix validator's else handler generation. See [#1015](https://github.com/aiken-lang/aiken/issues/1015) @KtorZ
- **aiken-lang**: Fix underflow in error message reported by the validator arity. See [#1013](https://github.com/aiken-lang/aiken/issues/1013) @KtorZ
- **aiken-lang**: Fix list-pattern needlessly formatting over multiple lines. @KtorZ
- **aiken-lang**: Fix formatter on long alternative patterns spanning over multiple lines. @KtorZ

View File

@ -714,25 +714,30 @@ impl TypedValidator {
.chain(std::iter::once(&self.fallback).map(|fallback| {
let arg = fallback.arguments.first().unwrap();
let then = &[
TypedExpr::let_(
TypedExpr::local_var(var_context, arg.tipo.clone(), arg.location),
arg.get_variable_name().map(TypedPattern::var).unwrap_or(
TypedPattern::Discard {
name: var_context.to_string(),
location: arg.location,
},
let then = match arg.get_variable_name() {
Some(arg_name) => TypedExpr::sequence(&[
TypedExpr::let_(
TypedExpr::local_var(
var_context,
arg.tipo.clone(),
arg.location,
),
TypedPattern::var(arg_name),
arg.tipo.clone(),
arg.location,
),
arg.tipo.clone(),
arg.location,
),
fallback.body.clone(),
];
fallback.body.clone(),
]),
None => fallback.body.clone(),
};
TypedClause {
location: Span::empty(),
pattern: TypedPattern::var(var_context),
then: TypedExpr::sequence(then),
pattern: TypedPattern::Discard {
name: "_".to_string(),
location: arg.location,
},
then,
}
}))
.collect(),

View File

@ -0,0 +1,6 @@
[
{ 0: h'70{{ simple_else.simple_else.else.hash }}'
, 1: 1000000000
, 2: [1, 24(h'd87980')]
}
]

View File

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

View File

@ -0,0 +1,95 @@
use aiken/collection/dict
use cardano/address.{Address, Script}
use cardano/assets
use cardano/script_context.{ScriptContext, Spending}
use cardano/transaction.{
InlineDatum, Input, Output, OutputReference, ScriptPurpose, Spend, Transaction,
}
validator simple_else {
else(ctx: ScriptContext) {
expect Spending(output_ref, _) = ctx.info
let transaction = ctx.transaction
assert_transaction_id(transaction.id)
assert_script_info(output_ref)
assert_inputs(transaction.inputs)
expect [] = transaction.outputs
expect [] = transaction.reference_inputs
expect [] = transaction.extra_signatories
expect 42 == transaction.fee
assert_redeemers(transaction.redeemers)
expect [] == dict.to_pairs(transaction.datums)
True
}
}
fn assert_transaction_id(id: ByteArray) {
expect
#"c6fbd346681a8f8337f6b3e51e6ec973f1509367eabc3a44c849af58a1d8471b" == id
Void
}
fn assert_script_info(info: OutputReference) {
expect
OutputReference {
transaction_id: #"0000000000000000000000000000000000000000000000000000000000000000",
output_index: 0,
} == info
Void
}
fn assert_inputs(inputs: List<Input>) {
expect [
Input {
output_reference: OutputReference { transaction_id, output_index: 0 },
output: Output {
address,
value: resolved_input_value,
datum: InlineDatum(_),
reference_script: None,
},
},
] = inputs
expect
transaction_id == #"0000000000000000000000000000000000000000000000000000000000000000"
expect resolved_input_value == assets.from_lovelace(1000000000)
expect Address { payment_credential: Script(_), stake_credential: None } =
address
Void
}
fn assert_redeemers(redeemers: Pairs<ScriptPurpose, Data>) {
expect
[
Pair(
Spend(
OutputReference {
transaction_id: #"0000000000000000000000000000000000000000000000000000000000000000",
output_index: 0,
},
),
void(),
),
] == redeemers
Void
}
fn void() -> Data {
let void: Data = Void
void
}