diff --git a/src/lib_riscv/pvm/backend.ml b/src/lib_riscv/pvm/backend.ml index 414f5b7aeffcef028c26b7089e49fcf833dd2cb0..260fd2a85f2ef572c7817bfba176fbeb74da23d3 100644 --- a/src/lib_riscv/pvm/backend.ml +++ b/src/lib_riscv/pvm/backend.ml @@ -12,8 +12,6 @@ type reveals = unit type write_debug = string -> unit Lwt.t -type input_info - type state = Storage.State.t type status = Api.status @@ -22,6 +20,10 @@ type reveal_data = Api.reveal_data type input = Api.input +type input_request = Octez_riscv_api.input_request + +type proof = Octez_riscv_api.proof + (* The kernel debug logging function (`string -> unit Lwt.t`) passed by the node * to [compute_step] and [compute_step_many] cannot be passed directly * to the Rust backend, which expects a `u8 -> ()` function and cannot run Lwt @@ -73,3 +75,11 @@ let get_current_level state = Lwt.return (Api.octez_riscv_get_level state) let state_hash state = Api.octez_riscv_state_hash state let set_input state input = Lwt.return (Api.octez_riscv_set_input state input) + +let proof_start_state proof = Api.octez_riscv_proof_start_state proof + +let proof_stop_state proof = Api.octez_riscv_proof_stop_state proof + +let verify_proof input proof = Api.octez_riscv_verify_proof input proof + +let produce_proof input state = Api.octez_riscv_produce_proof input state diff --git a/src/lib_riscv/pvm/backend.mli b/src/lib_riscv/pvm/backend.mli index 491aa758a785e53e330f72a0a79ad3a4008e2ac2..35512a29d62999996836f7ccc48d30c9d03b6030 100644 --- a/src/lib_riscv/pvm/backend.mli +++ b/src/lib_riscv/pvm/backend.mli @@ -10,8 +10,6 @@ type reveals type write_debug = string -> unit Lwt.t -type input_info - type state = Storage.State.t type status = Octez_riscv_api.status @@ -20,6 +18,10 @@ type reveal_data = Octez_riscv_api.reveal_data type input = Octez_riscv_api.input +type input_request = Octez_riscv_api.input_request + +type proof = Octez_riscv_api.proof + val compute_step_many : ?reveal_builtins:reveals -> ?write_debug:write_debug -> @@ -47,3 +49,11 @@ val get_current_level : state -> int32 option Lwt.t val state_hash : state -> bytes val set_input : state -> input -> state Lwt.t + +val proof_start_state : proof -> bytes + +val proof_stop_state : proof -> bytes + +val verify_proof : input option -> proof -> input_request option + +val produce_proof : input option -> state -> proof option diff --git a/src/proto_alpha/lib_sc_rollup_node/riscv_pvm.ml b/src/proto_alpha/lib_sc_rollup_node/riscv_pvm.ml index aced8941e59840ce0c0f93e8a8d92d2d318b454f..5c8d71f4b43a2016fa3b5aad7879a689806df786 100644 --- a/src/proto_alpha/lib_sc_rollup_node/riscv_pvm.ml +++ b/src/proto_alpha/lib_sc_rollup_node/riscv_pvm.ml @@ -6,6 +6,34 @@ (* *) (*****************************************************************************) +type Environment.Error_monad.error += Riscv_proof_verification_failed + +type Environment.Error_monad.error += Riscv_proof_production_failed + +let () = + let open Environment.Error_monad in + let open Data_encoding in + let msg = "Proof verification failed" in + register_error_kind + `Permanent + ~id:"smart_rollup_riscv_proof_verification_failed" + ~title:msg + ~pp:(fun fmt () -> Format.fprintf fmt "%s" msg) + ~description:msg + unit + (function Riscv_proof_verification_failed -> Some () | _ -> None) + (fun () -> Riscv_proof_verification_failed) ; + let msg = "Proof production failed" in + register_error_kind + `Permanent + ~id:"smart_rollup_riscv_proof_production_failed" + ~title:msg + ~pp:(fun fmt () -> Format.fprintf fmt "%s" msg) + ~description:msg + unit + (function Riscv_proof_production_failed -> Some () | _ -> None) + (fun () -> Riscv_proof_production_failed) + open Protocol open Alpha_context module Context = Riscv_context @@ -44,13 +72,20 @@ module PVM : type hash = Sc_rollup.State_hash.t - type proof = void + type proof = Backend.proof - let proof_encoding = void + let proof_encoding = + Data_encoding.( + conv_with_guard + (function (_ : proof) -> ()) + (fun _ -> Error "proofs not implemented") + unit) - let proof_start_state = function (_ : proof) -> . + let proof_start_state proof = + Sc_rollup.State_hash.of_bytes_exn (Backend.proof_start_state proof) - let proof_stop_state = function (_ : proof) -> . + let proof_stop_state proof = + Sc_rollup.State_hash.of_bytes_exn (Backend.proof_stop_state proof) let state_hash state = Lwt.return (Sc_rollup.State_hash.of_bytes_exn (Backend.state_hash state)) @@ -91,23 +126,35 @@ module PVM : | Sc_rollup.(Reveal (Raw_data data)) -> Reveal (RawData data) | _ -> assert false + let of_pvm_input_request (_input_request : Backend.input_request) : + Sc_rollup.input_request = + raise (Invalid_argument "input_request not implemented") + let set_input input state = Backend.set_input state (to_pvm_input input) let eval state = Backend.compute_step state - let verify_proof ~is_reveal_enabled:_ _input = function (_ : proof) -> . + let verify_proof ~is_reveal_enabled:_ input_given proof = + let open Environment.Error_monad.Lwt_result_syntax in + match Backend.verify_proof (Option.map to_pvm_input input_given) proof with + | None -> tzfail Riscv_proof_verification_failed + | Some request -> return (of_pvm_input_request request) - let produce_proof _context ~is_reveal_enabled:_ _state _step = assert false + let produce_proof _context ~is_reveal_enabled:_ input_given state = + let open Environment.Error_monad.Lwt_result_syntax in + match Backend.produce_proof (Option.map to_pvm_input input_given) state with + | None -> tzfail Riscv_proof_production_failed + | Some proof -> return proof type output_proof = void let output_proof_encoding = void - let output_of_output_proof = function (_ : proof) -> . + let output_of_output_proof = function (_ : output_proof) -> . - let state_of_output_proof = function (_ : proof) -> . + let state_of_output_proof = function (_ : output_proof) -> . - let verify_output_proof = function (_ : proof) -> . + let verify_output_proof = function (_ : output_proof) -> . let produce_output_proof _context _state _output = assert false diff --git a/src/riscv/lib/octez_riscv_api.ml b/src/riscv/lib/octez_riscv_api.ml index 1a25ac9e5a61c2ebc4249cd75f96568336e094cd..7ad6660949bb6de0e92c4e7fbe3db6eac6e25a94 100644 --- a/src/riscv/lib/octez_riscv_api.ml +++ b/src/riscv/lib/octez_riscv_api.ml @@ -10,6 +10,8 @@ type id type status = Evaluating | WaitingForInput | WaitingForMetadata type reveal_data = RawData of string | Metadata of bytes * int32 type input = InboxMessage of int32 * int64 * string | Reveal of reveal_data +type input_request +type proof external octez_riscv_id_unsafe_of_raw_bytes: bytes -> id = "octez_riscv_id_unsafe_of_raw_bytes" external octez_riscv_storage_id_to_raw_bytes: id -> bytes = "octez_riscv_storage_id_to_raw_bytes" external octez_riscv_storage_id_equal: id -> id -> bool = "octez_riscv_storage_id_equal" @@ -32,3 +34,7 @@ external octez_riscv_state_hash: state -> bytes = "octez_riscv_state_hash" external octez_riscv_set_input: state -> input -> state = "octez_riscv_set_input" external octez_riscv_get_message_counter: state -> int64 = "octez_riscv_get_message_counter" external octez_riscv_storage_export_snapshot: repo -> id -> string -> (unit, [`Msg of string]) result = "octez_riscv_storage_export_snapshot" +external octez_riscv_proof_start_state: proof -> bytes = "octez_riscv_proof_start_state" +external octez_riscv_proof_stop_state: proof -> bytes = "octez_riscv_proof_stop_state" +external octez_riscv_verify_proof: input option -> proof -> input_request option = "octez_riscv_verify_proof" +external octez_riscv_produce_proof: input option -> state -> proof option = "octez_riscv_produce_proof" diff --git a/src/riscv/lib/octez_riscv_api.mli b/src/riscv/lib/octez_riscv_api.mli index 1a25ac9e5a61c2ebc4249cd75f96568336e094cd..7ad6660949bb6de0e92c4e7fbe3db6eac6e25a94 100644 --- a/src/riscv/lib/octez_riscv_api.mli +++ b/src/riscv/lib/octez_riscv_api.mli @@ -10,6 +10,8 @@ type id type status = Evaluating | WaitingForInput | WaitingForMetadata type reveal_data = RawData of string | Metadata of bytes * int32 type input = InboxMessage of int32 * int64 * string | Reveal of reveal_data +type input_request +type proof external octez_riscv_id_unsafe_of_raw_bytes: bytes -> id = "octez_riscv_id_unsafe_of_raw_bytes" external octez_riscv_storage_id_to_raw_bytes: id -> bytes = "octez_riscv_storage_id_to_raw_bytes" external octez_riscv_storage_id_equal: id -> id -> bool = "octez_riscv_storage_id_equal" @@ -32,3 +34,7 @@ external octez_riscv_state_hash: state -> bytes = "octez_riscv_state_hash" external octez_riscv_set_input: state -> input -> state = "octez_riscv_set_input" external octez_riscv_get_message_counter: state -> int64 = "octez_riscv_get_message_counter" external octez_riscv_storage_export_snapshot: repo -> id -> string -> (unit, [`Msg of string]) result = "octez_riscv_storage_export_snapshot" +external octez_riscv_proof_start_state: proof -> bytes = "octez_riscv_proof_start_state" +external octez_riscv_proof_stop_state: proof -> bytes = "octez_riscv_proof_stop_state" +external octez_riscv_verify_proof: input option -> proof -> input_request option = "octez_riscv_verify_proof" +external octez_riscv_produce_proof: input option -> state -> proof option = "octez_riscv_produce_proof" diff --git a/src/riscv/lib/src/ocaml_api.rs b/src/riscv/lib/src/ocaml_api.rs index 283a1f3855dbd147a1fe89fab9398a53f6813d1e..874c3f11a71e2bcb39c30bff90deeaa61fedde47 100644 --- a/src/riscv/lib/src/ocaml_api.rs +++ b/src/riscv/lib/src/ocaml_api.rs @@ -51,6 +51,13 @@ pub enum Input<'a> { Reveal(RevealData<'a>), } +/// A value of this type could only be returned as part of successfully verifying +/// a proof, which is not yet implemented. It is therefore only mocked for now. +#[ocaml::sig] +pub struct InputRequest; + +ocaml::custom!(InputRequest); + impl From for Status { fn from(item: PvmStatus) -> Self { Status::try_from(item as u8).expect("Invalid conversion") @@ -309,3 +316,39 @@ pub unsafe fn octez_riscv_storage_export_snapshot( ocaml::Value::hash_variant(gc, "Msg", Some(s.to_value(gc))) }) } + +/// Proofs +#[ocaml::sig] +pub struct Proof; + +ocaml::custom!(Proof); + +#[ocaml::func] +#[ocaml::sig("proof -> bytes")] +pub fn octez_riscv_proof_start_state(_proof: Pointer) -> [u8; 32] { + todo!() +} + +#[ocaml::func] +#[ocaml::sig("proof -> bytes")] +pub fn octez_riscv_proof_stop_state(_proof: Pointer) -> [u8; 32] { + todo!() +} + +#[ocaml::func] +#[ocaml::sig("input option -> proof -> input_request option")] +pub unsafe fn octez_riscv_verify_proof( + _proof: Pointer, + _input: Option, +) -> Option> { + None +} + +#[ocaml::func] +#[ocaml::sig("input option -> state -> proof option")] +pub unsafe fn octez_riscv_produce_proof( + _input: Option, + _state: Pointer, +) -> Option> { + None +}