aiken-lang / aiken

A modern smart contract platform for Cardano
https://aiken-lang.org
Apache License 2.0
454 stars 84 forks source link

Codegen whoops #863

Closed Quantumplation closed 6 months ago

Quantumplation commented 6 months ago

What Git revision are you using?

Commit ebd6c3a56eb598432169f543a63b4c423af62a73

What operating system are you using, and which version?

Describe what the problem is?

Got the following error while playing around with the new fuzzing code:

   aiken::fatal::error
   Whoops! You found a bug in the Aiken compiler.

   Please report this error at https://github.com/aiken-lang/aiken/issues/new.
   In your bug report please provide the information below and if possible the code
   that produced it.

   Operating System: linux
   Architecture:     x86_64
   Version:          v1.0.24-alpha+e944f10

   crates/aiken-lang/src/gen_uplc.rs:4204:25

       internal error: entered unreachable code: Shouldn't call anything other than var

Here's the code that caused it, but i'm not sure what the specific reproduce is:

use aiken/cbor
use aiken/list as native_list
use aiken/fuzz.{list, int_between, map, map2, constant, and_then}
use aiken/bytearray
use aiken/hash.{blake2b_256}
use aiken/time.{PosixTime}
use sundae/multisig.{MultisigScript, Signature, AllOf, AnyOf, AtLeast, Before, After}

pub fn byte() -> Fuzzer<ByteArray> {
    int_between(0, 255) |> map2(constant(#""), _, bytearray.push)
}

pub fn public_key() -> Fuzzer<ByteArray> {
    byte() |> map(blake2b_256) |> map(fn(x) { bytearray.take(x, 28) })
}

pub fn posix_time() -> Fuzzer<PosixTime> {
    int_between(1600000000, 2000000000) |> map(fn(x) { x })
}

pub fn signature_multisig() -> Fuzzer<MultisigScript> {
    public_key() |> map(fn(pk) { Signature(pk) })
}
pub fn all_multisig() -> Fuzzer<MultisigScript> {
    list(multisig()) |> map(fn(x) { AllOf(x) })
}
pub fn any_multisig() -> Fuzzer<MultisigScript> {
    list(multisig()) |> map(fn(x) { AnyOf(x) })
}
pub fn at_least_multisig() -> Fuzzer<MultisigScript> {
    list(multisig()) |>
    and_then(fn(scripts) {
        int_between(1, native_list.length(scripts) - 1) |>
        map(fn(count) { AtLeast(count, scripts) })
    })
}
pub fn before_multisig() -> Fuzzer<MultisigScript> {
    posix_time() |> map(fn(t) { Before(t) })
}
pub fn after_multisig() -> Fuzzer<MultisigScript> {
    posix_time() |> map(fn(t) { Before(t) })
}
pub fn multisig() -> Fuzzer<MultisigScript> {
    int_between(0, 6) |> and_then(fn(variant) {
        when variant is {
            0 -> signature_multisig()
            1 -> all_multisig()
            2 -> signature_multisig()
            3 -> signature_multisig()
            4 -> before_multisig()
            5 -> after_multisig()
            6 -> after_multisig()
            _ -> fail
        }
    })
}

test pk_test(sig via multisig()) {
    trace bytearray.to_hex(cbor.serialise(sig))
    True
}

(Note: the code doesn't really make sense yet; i only caught this because i had watch on and was in the middle of writing something and my editor saved part way through and crashed it, so I ctrl-z'd until i found the point that gave the error)

What should be the expected behavior?

Not crash

Quantumplation commented 6 months ago

Here's where it's crashing:

https://github.com/aiken-lang/aiken/blob/77faee672e88b2efffcea6b89fdb3a4c06890a14/crates/aiken-lang/src/gen_uplc.rs#L4204

Quantumplation commented 6 months ago

(also, I was on a branch of aiken from my recent PR, but i've confirmed the issue also occurs on main)

Quantumplation commented 6 months ago

(can confirm @MicroProofs fixed this on main for me)

MicroProofs commented 6 months ago

Closed by bffa6781780763a6eb9acef204166eee184cfaad