MISSING REQ SIGNER Fraud proof#229
Conversation
|
|
||
| expect list.has(builtin.un_list_data(bad_spend_inputs), bad_input) | ||
|
|
||
| expect invalid_input: Input = bad_input |
There was a problem hiding this comment.
This doesn't work because the transaction's spend inputs is a list of output references [OutputReference].
We have to do the lookup for the utxo output manually for this output reference, which means that we should have two different fraud proof procedures:
- The output reference is for a utxo produced by another transaction (
t_2) in this block (MISSING-REQ-SIGNER-TX). - The output reference is for a utxo (i.e. member of
prev_utxos_root) that existed before this block (MISSING-REQ-SIGNER-UTXO).
I updated the spec to describe these fraud proofs. Please adapt the code accordingly.
I suggest that you implement both fraud proofs in this PR (they're quite similar).
|
@GeorgeFlerovsky updated the FP splitted in 2 |
GeorgeFlerovsky
left a comment
There was a problem hiding this comment.
Code doesn't compile. See comments explaining why and how to fix it
| bad_spend_inputs: Data, | ||
| bad_input: Data, | ||
| parent_outputs_data: Data, | ||
| parent_outputs: List<Output>, |
There was a problem hiding this comment.
You can't use the Output type inside a redeemer because Output contains a Value, which is an opaque type. This is the compilation error I got when trying to build this:
Instead, the parent_outputs field should be Data, from which you can select the correct output and then parse it as an Output. For example, this is how we did it in the non-existent-input fraud proof validator:
Continue {
...
bad_input, // : Data
bad_spend_inputs, // : Data
} -> {
// Membership of the bad_input among the tx1 spent inputs
verify_hash_32(bad_tx, bad_tx_hash)
verify_hash_32(bad_tx_body, bad_tx.body)
verify_hash_32(bad_spend_inputs, bad_tx_body.spend_inputs)
expect list.has(builtin.un_list_data(bad_spend_inputs), bad_input)
expect invalid_input: Input = bad_input
}
There was a problem hiding this comment.
I can't cast as we did because it does not allow me to cast from Data to Output since output contains Value, so it's opaque
expect bad_output: Output = real_output
· ─────┬─────
· ╰── reckless opaque cast
126 │ expect invalid_input.output_reference.transaction_id == parent_tx_hash
127 │ expect invalid_input.output == bad_output
╰────
help: This expression is trying to convert something unknown into an opaque type. An opaque type is a data-type which hides its internal details; usually
because it enforces some specific invariant on its internal structure. For example, you might define a Natural type that holds an Integer but ensures
that it never gets negative.
A direct consequence means that it isn't generally possible, nor safe, to turn *any* value into an opaque type. Instead, use the constructors and
methods provided for lifting values into that opaque type while ensuring that any structural invariant is checked for.
There was a problem hiding this comment.
@elRaulito for the withdrawal contract I've used unconstr_fields to extract Output fields. Here:
midgard/onchain/aiken/validators/user-events/withdrawal.ak
Lines 208 to 213 in 68c013d
For Value, we have ValuePairs, which we can cast Data values to unsafely (which should be fine in most cases in Midgard):
midgard/onchain/aiken/validators/user-events/withdrawal.ak
Lines 263 to 265 in 68c013d

No description provided.