Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apply params to validator loaded from file fails #5414

Open
KristianBalaj opened this issue Jul 6, 2023 · 8 comments
Open

Apply params to validator loaded from file fails #5414

KristianBalaj opened this issue Jul 6, 2023 · 8 comments
Labels
Low priority Doesn't require immediate attention status: triaged

Comments

@KristianBalaj
Copy link

Summary

I'm trying to apply parameters to Aiken written validator that is loaded from file in Plutus.
When the validator is non-parametrized, it works fine, but the problem is when applying parameters to a validator.

The problem seems to be that the encoding of parameter application doesn't seem to match but I'm not sure what is the format Plutus is using to apply parameters and whether it could be customised.

Steps to reproduce the behavior

The Aiken's validator is a simple always pass validator that accesses the script parameters.

The following is the Aiken code for reference:

type FooScriptParams {
    a: Int,
}

validator(params: FooScriptParams) {
  fn spend(datum: Void, redeemer: Void, ctx: ScriptContext) -> Bool {
    let FooScriptParams { a } = params
    a == a
  }
}

Then using the following transformation to named deBruijn:

  1. aiken build --uplc
  2. aiken uplc encode --to named-debruijn artifacts/foo.spend.uplc > foo.namedDeBruijn

I'm using the following revision of Aiken aiken-lang/aiken@699467a

The following is the loading of the validator encoded in named deBruijn from foo.namedDeBruijn into Plutus:

data FooScriptParams = FooScriptParams
  { a :: Integer
  }

PlutusTx.makeLift ''FooScriptParams
PlutusTx.makeIsDataIndexed ''FooScriptParams [('FooScriptParams, 0)]

compiledFooUnapplied :: CompiledCode (FooScriptParams -> UntypedValidator)
compiledFooUnapplied = $$(PlutusTx.loadFromFile "some_path/foo.namedDeBruijn")

compiledFoo :: CompiledCode UntypedValidator
compiledFoo = compiledFooUnapplied `PlutusTx.applyCode` PlutusTx.liftCode FooScriptParams {a = 100}

Actual Result

Now when executing the compiledFoo from the steps to reproduce, I get the following error:

Could not unlift a builtin:
Not a constant
Caused by: (delay (\i_i0 -> i_i1 100))) []

Where the (delay (\i_i0 -> i_i1 100))) [] seems to be the encoded FooScriptParams.
So I'm expecting the problem is in the application of parameters.

Expected Result

Expected is that the parameters get properly applied to the validator and the validator validates.

Describe the approach you would take to fix this

No response

System info

Plutus revision: f003b09

@github-actions github-actions bot added the status: needs triage GH issues that requires triage label Jul 6, 2023
@effectfully
Copy link
Contributor

effectfully commented Jul 6, 2023

aiken uplc encode --to named-debruijn artifacts/foo.spend.uplc > foo.namedDeBruijn

Please attach the result of this command (as a file or under a spoiler).

(delay (\i_i0 -> i_i1 100))) []

What evaluator do you use? This doesn't seem like the syntax that we use in those errors, although I might be wrong about that.

Anyway, the error message says that a function is applied to the Scott-encoded FooScriptParams (and it's encoded correctly) while expecting some constant. What function? I can't tell without seeing the whole program.

... but actually, thinking about it, wasn't Aiken encoding all data types using Data instead of replicating our old (we now have SOPs) Scott-encoding? If so, then that's your error: the function implemented in Aiken wants you to provide a Data-encoded value of FooScriptParams and you provide it a Scott-encoded one.

I'm going to remove the bug label for now and I'll return it later if it turns out that the bug is indeed on the Plutus side.

@KristianBalaj
Copy link
Author

aiken uplc encode --to named-debruijn artifacts/foo.spend.uplc > foo.namedDeBruijn

Please attach the result of this command (as a file or under a spoiler).

Here's the Aiken's named debruijn of the always pass code listed above via hexdump:

Hexdump
00000000  01 00 00 32 01 03 69 5f  30 00 00 32 01 03 69 5f  |...2..i_0..2..i_|
00000010  31 00 00 32 01 03 69 5f  32 00 00 32 01 03 69 5f  |1..2..i_2..2..i_|
00000020  33 00 00 32 01 03 69 5f  34 00 00 32 01 03 69 5f  |3..2..i_4..2..i_|
00000030  35 00 00 32 01 03 69 5f  36 00 00 32 01 03 69 5f  |5..2..i_6..2..i_|
00000040  37 00 00 21 03 69 5f 38  00 00 21 03 69 5f 39 00  |7..!.i_8..!.i_9.|
00000050  00 21 04 69 5f 31 30 00  00 21 04 69 5f 31 31 00  |.!.i_10..!.i_11.|
00000060  00 32 01 04 69 5f 31 32  00 00 32 01 04 69 5f 31  |.2..i_12..2..i_1|
00000070  33 00 00 53 33 01 03 69  5f 34 00 0a 32 01 04 69  |3..S3..i_4..2..i|
00000080  5f 31 34 00 00 32 01 04  69 5f 31 35 00 00 33 70  |_14..2..i_15..3p|
00000090  e1 04 69 5f 31 35 00 01  01 04 69 5f 31 35 00 01  |..i_15....i_15..|
000000a0  37 5a 61 03 69 5f 31 00  0e 01 04 69 5f 31 34 00  |7Za.i_1....i_14.|
000000b0  01 30 01 03 69 5f 32 00  0c 37 54 01 03 69 5f 38  |.0..i_2..7T..i_8|
000000c0  00 06 14 98 59 4c cc 01  03 69 5f 34 00 09 33 70  |....YL...i_4..3p|
000000d0  e9 00 01 81 03 69 5f 33  00 0a 37 54 01 03 69 5f  |.....i_3..7T..i_|
000000e0  39 00 04 14 98 59 4c cc  01 03 69 5f 34 00 08 33  |9....YL...i_4..3|
000000f0  70 e9 00 01 81 03 69 5f  33 00 09 37 54 01 04 69  |p.....i_3..7T..i|
00000100  5f 31 30 00 02 14 98 58  cc 01 03 69 5f 36 00 01  |_10....X...i_6..|
00000110  01 03 69 5f 36 00 01 48  00 09 04 69 5f 31 36 00  |..i_6..H...i_16.|
00000120  00 21 04 69 5f 31 37 00  00 21 04 69 5f 31 38 00  |.!.i_17..!.i_18.|
00000130  00 21 04 69 5f 31 39 00  00 33 33 01 03 69 5f 34  |.!.i_19..33..i_4|
00000140  00 06 33 70 e1 04 69 5f  31 39 00 01 01 04 69 5f  |..3p..i_19....i_|
00000150  31 37 00 03 01 03 69 5f  31 00 09 21 04 69 5f 32  |17....i_1..!.i_2|
00000160  30 00 00 33 33 01 04 69  5f 31 36 00 05 01 04 69  |0..33..i_16....i|
00000170  5f 31 36 00 05 33 70 01  04 69 5f 31 37 00 04 48  |_16..3p..i_17..H|
00000180  00 8c 01 03 69 5f 30 00  0b 01 04 69 5f 32 30 00  |....i_0....i_20.|
00000190  01 01 04 69 5f 31 39 00  02 01 04 69 5f 31 38 00  |...i_19....i_18.|
000001a0  02 21 04 69 5f 32 31 00  00 30 01 03 69 5f 33 00  |.!.i_21..0..i_3.|
000001b0  03 37 54 01 04 69 5f 32  31 00 01 57 34 aa e7 55  |.7T..i_21..W4..U|
000001c0  5c f2 ba 15 74 41                                 |\...tA|
000001c6

Here's the same but from the stdout in terminal:

Terminal stdout
2i_02i_12i_22i_32i_42i_52i_62i_7!i_8!i_9!i_10!i_112i_122i_13S3i_4
2i_142i_153p�i_15i_157Zai_1i_140i_2
                                   7Ti_8�YL�i_4 3p��i_3
7Ti_9�YL�i_3p��i_3      7Ti_10�X�i_6i_6H        i_16!i_17!i_18!i_1933i_43p�i_19i_17i_1  !i_2033i_16i_163pi_17H�i_0
                                                                                                                  i_20i_19i_18!i_210i_37Ti_21W4��U\�tA% 

And here's the binary file (the upload expires in 6 days) - https://filebin.net/uv538dwurqn2pp0j

What evaluator do you use? This doesn't seem like the syntax that we use in those errors, although I might be wrong about that.

I'm using the following tool to run the validator https://github.com/mlabs-haskell/plutus-simple-model
I'm not sure what evaluator does it use, but my guess would be the Cardano ledger one.

If so, then that's your error: the function implemented in Aiken wants you to provide a Data-encoded value of FooScriptParams and you provide it a Scott-encoded one.

That sounds like the possible problem.
Is there a way how to modify the parameter application to be data-encoded instead of the scott encoded one?

compiledFoo :: CompiledCode UntypedValidator
compiledFoo = compiledFooUnapplied `PlutusTx.applyCode` PlutusTx.liftCode FooScriptParams {a = 100}

@effectfully
Copy link
Contributor

Is there a way how to modify the parameter application to be data-encoded instead of the scott encoded one?

No, we do not support Data-encoded data in any way, it's Aiken's thing. I know @michaelpj has strong opinions about it. Basically, it's just super extra inefficient to encode data using Data.

If you really need such a thing, your best bet is probably to compile to SOPs using our most recent release and then convert SOPs to Data, shouldn't be too hard. But I don't know how Aiken encodes data, so perhaps it makes sense for you to request such functionality from Aiken people.

I'll take a look at the provided file shortly, thanks for sharing.

@effectfully
Copy link
Contributor

effectfully commented Jul 7, 2023

So this is the decoded program:

program
(program
   1.0.0
   ((\i_0 ->
       (\i_1 ->
          (\i_2 ->
             (\i_3 ->
                (\i_4 ->
                   (\i_5 ->
                      (\i_6 ->
                         (\i_7 i_8 i_9 i_10 i_11 ->
                            (\i_12 ->
                               (\i_13 ->
                                  force
                                    (i_4
                                       ((\i_14 ->
                                           (\i_15 -> equalsInteger i_15 i_15)
                                             (unIData (i_1 i_14)))
                                          (i_2 (unConstrData i_8)))
                                       (delay ())
                                       (delay error)))
                                 (force
                                    (i_4
                                       (equalsInteger
                                          0
                                          (i_3 (unConstrData i_9)))
                                       (delay ())
                                       (delay error))))
                              (force
                                 (i_4
                                    (equalsInteger 0 (i_3 (unConstrData i_10)))
                                    (delay ())
                                    (delay error))))
                           (i_6 i_6 0))
                        (\i_16 i_17 i_18 i_19 ->
                           i_4
                             (equalsInteger i_19 i_17)
                             i_1
                             (\i_20 ->
                                i_16 i_16 (addInteger i_17 1) (i_0 i_20) i_19)
                             i_18))
                     (\i_21 -> i_3 (unConstrData i_21)))
                  (force ifThenElse))
               (force (force fstPair)))
            (force (force sndPair)))
         (force headList))
      (force tailList)))

The lambda that you apply is the one binding i_8. i_8 is expected to be a Data object with an Integer in its single constructor, i.e. this all confirms my hypothesis.

I do not see what the Plutus team can do here, I don't think we're going to support converting SOPs to Data in any observable future (we might decide to do that if we end up implementing a fancy ScriptContext encoding or something). @michaelpj please verify this when you're back.

Hence I'm closing the issue, do feel free to reopen if you disagree.

@KristianBalaj
Copy link
Author

Thank you very much for your insights again 🙌
I really appreciate it.

@effectfully
Copy link
Contributor

Happy to help!

@michaelpj
Copy link
Contributor

No, we do not support Data-encoded data in any way, it's Aiken's thing. I know @michaelpj has strong opinions about it. Basically, it's just super extra inefficient to encode data using Data.

I mean, it's stupid and very slow, but I think we could support this as a datatype compilation mode now. Although I would mostly use it to show how bad it is 😂

@effectfully
Copy link
Contributor

I mean, it's stupid and very slow, but I think we could support this as a datatype compilation mode now. Although I would mostly use it to show how bad it is joy

OK, if there's a serious consideration for us to do it, then I'm reopening this issue.

@effectfully effectfully reopened this Jul 10, 2023
@effectfully effectfully added Low priority Doesn't require immediate attention status: triaged labels Jul 10, 2023
@github-actions github-actions bot added the status: needs triage GH issues that requires triage label Jul 10, 2023
@effectfully effectfully removed the status: needs triage GH issues that requires triage label Jul 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Low priority Doesn't require immediate attention status: triaged
Projects
None yet
Development

No branches or pull requests

3 participants