diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index c470867e2dd7968b5c61a06b6293f5e33ce816fc..e246db86a4fd878c70ea338282fe0b20878d3c5d 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -2530,9 +2530,36 @@ module Sc_rollup : sig val input_request_equal : input_request -> input_request -> bool + module Outbox : sig + (** See {!Sc_rollup_outbox_message_repr}. *) + module Message : sig + type transaction = { + unparsed_parameters : Script.expr; + destination : Contract_hash.t; + entrypoint : Entrypoint.t; + } + + type t = Atomic_transaction_batch of {transactions : transaction list} + + val of_bytes : string -> t tzresult + + module Internal_for_tests : sig + val to_bytes : t -> string tzresult + end + end + + val record_applied_message : + context -> + t -> + Raw_level.t -> + message_index:int -> + (Z.t * context) tzresult Lwt.t + end + type output = { - message_counter : Z.t; - payload : Sc_rollup_outbox_message_repr.t; + outbox_level : Raw_level.t; + message_index : Z.t; + message : Outbox.Message.t; } module PVM : sig @@ -2580,6 +2607,8 @@ module Sc_rollup : sig type output_proof + val output_proof_encoding : output_proof Data_encoding.t + val output_of_output_proof : output_proof -> output val state_of_output_proof : output_proof -> State_hash.t @@ -2870,32 +2899,6 @@ module Sc_rollup : sig end end - module Outbox : sig - (** See {!Sc_rollup_outbox_message_repr}. *) - module Message : sig - type transaction = { - unparsed_parameters : Script.expr; - destination : Contract_hash.t; - entrypoint : Entrypoint.t; - } - - type t = Atomic_transaction_batch of {transactions : transaction list} - - val of_bytes : string -> t tzresult - - module Internal_for_tests : sig - val to_bytes : t -> string tzresult - end - end - - val record_applied_message : - context -> - t -> - Raw_level.t -> - message_index:int -> - (Z.t * context) tzresult Lwt.t - end - module Errors : sig type error += Sc_rollup_does_not_exist of t end diff --git a/src/proto_alpha/lib_protocol/sc_rollup_PVM_sem.ml b/src/proto_alpha/lib_protocol/sc_rollup_PVM_sem.ml index bacfc69148a53d974c2f9d73aa0d33342488dc4f..5d688ddb87e609b562cd0c69d546bf8cf0f8d00b 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_PVM_sem.ml +++ b/src/proto_alpha/lib_protocol/sc_rollup_PVM_sem.ml @@ -135,25 +135,34 @@ let input_request_equal a b = Raw_level_repr.equal l m && Z.equal n o | First_after _, _ -> false -type output = {message_counter : Z.t; payload : Sc_rollup_outbox_message_repr.t} +type output = { + outbox_level : Raw_level_repr.t; + message_index : Z.t; + message : Sc_rollup_outbox_message_repr.t; +} let output_encoding = let open Data_encoding in conv - (fun {message_counter; payload} -> (message_counter, payload)) - (fun (message_counter, payload) -> {message_counter; payload}) - (obj2 - (req "message_counter" n) - (req "payload" Sc_rollup_outbox_message_repr.encoding)) + (fun {outbox_level; message_index; message} -> + (outbox_level, message_index, message)) + (fun (outbox_level, message_index, message) -> + {outbox_level; message_index; message}) + (obj3 + (req "outbox_level" Raw_level_repr.encoding) + (req "message_index" n) + (req "message" Sc_rollup_outbox_message_repr.encoding)) -let pp_output fmt {message_counter; payload} = +let pp_output fmt {outbox_level; message_index; message} = Format.fprintf fmt - "@[%a@;%a@;@]" + "@[%a@;%a@;%a@;@]" + Raw_level_repr.pp + outbox_level Z.pp_print - message_counter + message_index Sc_rollup_outbox_message_repr.pp - payload + message module type S = sig (** @@ -294,6 +303,9 @@ module type S = sig is part of the outbox of a given [state]. *) type output_proof + (** [output_proof_encoding] encoding value for [output_proof]s. *) + val output_proof_encoding : output_proof Data_encoding.t + (** [output_of_output_proof proof] returns the [output] that is referred to in [proof]'s statement. *) val output_of_output_proof : output_proof -> output diff --git a/src/proto_alpha/lib_protocol/sc_rollup_arith.ml b/src/proto_alpha/lib_protocol/sc_rollup_arith.ml index cfd9f2389f9c3292f83c3d7bebde0ac8a7b348fe..2fceb16ac63bf231729a1098e23194dd6bd236f5 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_arith.ml +++ b/src/proto_alpha/lib_protocol/sc_rollup_arith.ml @@ -962,8 +962,11 @@ module Make (Context : P) : let destination = Contract_hash.zero in let entrypoint = Entrypoint_repr.default in let transaction = {unparsed_parameters; destination; entrypoint} in - let payload = Atomic_transaction_batch {transactions = [transaction]} in - let output = Sc_rollup_PVM_sem.{message_counter = counter; payload} in + let message = Atomic_transaction_batch {transactions = [transaction]} in + let* outbox_level = CurrentLevel.get in + let output = + Sc_rollup_PVM_sem.{outbox_level; message_index = counter; message} + in Output.set (Z.to_string counter) output let evaluate = @@ -1065,11 +1068,23 @@ module Make (Context : P) : output_proof_output : PS.output; } + let output_proof_encoding = + let open Data_encoding in + conv + (fun {output_proof; output_proof_state; output_proof_output} -> + (output_proof, output_proof_state, output_proof_output)) + (fun (output_proof, output_proof_state, output_proof_output) -> + {output_proof; output_proof_state; output_proof_output}) + (obj3 + (req "output_proof" Context.proof_encoding) + (req "output_proof_state" State_hash.encoding) + (req "output_proof_output" PS.output_encoding)) + let output_of_output_proof s = s.output_proof_output let state_of_output_proof s = s.output_proof_state - let output_key (output : PS.output) = Z.to_string output.message_counter + let output_key (output : PS.output) = Z.to_string output.message_index let has_output output tree = let open Lwt_syntax in diff --git a/src/proto_alpha/lib_protocol/sc_rollup_wasm.ml b/src/proto_alpha/lib_protocol/sc_rollup_wasm.ml index 21fa930d03b94a9f88b53c9d6eeb8f882e87fd65..8243b7403fc735cf4c55e8c4e02d0b9cf7131b13 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_wasm.ml +++ b/src/proto_alpha/lib_protocol/sc_rollup_wasm.ml @@ -438,6 +438,17 @@ module V2_0_0 = struct output_proof_output : PS.output; } + let output_proof_encoding = + let open Data_encoding in + conv + (fun {output_proof_state; output_proof_output} -> + (output_proof_state, output_proof_output)) + (fun (output_proof_state, output_proof_output) -> + {output_proof_state; output_proof_output}) + (obj2 + (req "output_proof" State_hash.encoding) + (req "output_proof_state" PS.output_encoding)) + (* FIXME: #3176 The WASM PVM must provide an implementation for these proofs. These are likely to be similar to the proofs about the diff --git a/src/proto_alpha/lib_protocol/test/pbt/test_refutation_game.ml b/src/proto_alpha/lib_protocol/test/pbt/test_refutation_game.ml index a4354a0d3839a88b02a5b91de56d2922a82a3084..82b21eb0353636bed2e26844520d76475d904531 100644 --- a/src/proto_alpha/lib_protocol/test/pbt/test_refutation_game.ml +++ b/src/proto_alpha/lib_protocol/test/pbt/test_refutation_game.ml @@ -261,6 +261,8 @@ end) : TestPVM with type state = int = struct type output_proof = unit + let output_proof_encoding = Data_encoding.unit + let state_of_output_proof _ = Stdlib.failwith "Dummy PVM can't handle output proof" @@ -344,6 +346,8 @@ end) : TestPVM with type state = string * int list = struct type output_proof = unit + let output_proof_encoding = Data_encoding.unit + let state_of_output_proof _ = Stdlib.failwith "Dummy PVM can't handle output proof" diff --git a/src/proto_alpha/lib_protocol/test/unit/test_sc_rollup_arith.ml b/src/proto_alpha/lib_protocol/test/unit/test_sc_rollup_arith.ml index 93e740354e74892ec1118db7af0d5199ba8e2230..d11a08ce0a9eb436a64f6df739cc1365409b6c84 100644 --- a/src/proto_alpha/lib_protocol/test/unit/test_sc_rollup_arith.ml +++ b/src/proto_alpha/lib_protocol/test/unit/test_sc_rollup_arith.ml @@ -302,13 +302,13 @@ let test_evaluation_messages () = >>=? fun () -> List.iter_es (test_evaluation_message ~valid:false) invalid_messages -let test_output_messages_proofs ~valid (source, expected_outputs) = +let test_output_messages_proofs ~valid ~inbox_level (source, expected_outputs) = let open Lwt_result_syntax in let open Sc_rollup_PVM_sem in boot "" @@ fun ctxt state -> let input = { - inbox_level = Raw_level_repr.root; + inbox_level = Raw_level_repr.of_int32_exn (Int32.of_int inbox_level); message_counter = Z.zero; payload = source; } @@ -335,7 +335,7 @@ let test_output_messages_proofs ~valid (source, expected_outputs) = in List.iter_es check_output expected_outputs -let make_output ~counter n = +let make_output ~outbox_level ~message_index n = let open Sc_rollup_outbox_message_repr in let unparsed_parameters = Micheline.(Int (dummy_location, Z.of_int n) |> strip_locations) @@ -344,38 +344,72 @@ let make_output ~counter n = let entrypoint = Entrypoint_repr.default in let transaction = {unparsed_parameters; destination; entrypoint} in let transactions = [transaction] in - let message_counter = Z.of_int counter - and payload = Atomic_transaction_batch {transactions} in - Sc_rollup_PVM_sem.{message_counter; payload} + let message_index = Z.of_int message_index in + let outbox_level = Raw_level_repr.of_int32_exn (Int32.of_int outbox_level) in + let message = Atomic_transaction_batch {transactions} in + Sc_rollup_PVM_sem.{outbox_level; message_index; message} let test_valid_output_messages () = + let test inbox_level = + let outbox_level = inbox_level in + [ + ("1", []); + ("1 out", [make_output ~outbox_level ~message_index:0 1]); + ( "1 out 2 out", + [ + make_output ~outbox_level ~message_index:0 1; + make_output ~outbox_level ~message_index:1 2; + ] ); + ( "1 out 1 1 + out", + [ + make_output ~outbox_level ~message_index:0 1; + make_output ~outbox_level ~message_index:1 2; + ] ); + ( "1 out 1 1 + out out", + [ + make_output ~outbox_level ~message_index:0 1; + make_output ~outbox_level ~message_index:1 2; + make_output ~outbox_level ~message_index:2 2; + ] ); + ] + |> List.iter_es (test_output_messages_proofs ~valid:true ~inbox_level) + in + (* Test for different inbox/outbox levels. *) + List.iter_es test [0; 1; 2345] + +let test_invalid_output_messages () = + let inbox_level = 0 in + let outbox_level = inbox_level in [ - ("1", []); - ("1 out", [make_output ~counter:0 1]); - ("1 out 2 out", [make_output ~counter:0 1; make_output ~counter:1 2]); - ("1 out 1 1 + out", [make_output ~counter:0 1; make_output ~counter:1 2]); + ("1", [make_output ~outbox_level ~message_index:0 1]); + ("1 out", [make_output ~outbox_level ~message_index:1 1]); + ( "1 out 1 1 + out", + [ + make_output ~outbox_level ~message_index:0 1; + make_output ~outbox_level ~message_index:3 2; + ] ); ( "1 out 1 1 + out out", [ - make_output ~counter:0 1; - make_output ~counter:1 2; - make_output ~counter:2 2; + make_output ~outbox_level ~message_index:0 1; + make_output ~outbox_level ~message_index:1 2; + make_output ~outbox_level ~message_index:2 3; ] ); ] - |> List.iter_es (test_output_messages_proofs ~valid:true) + |> List.iter_es (test_output_messages_proofs ~valid:false ~inbox_level) -let test_invalid_output_messages () = +let test_invalid_outbox_level () = + let inbox_level = 42 in + let outbox_level = inbox_level - 1 in [ - ("1", [make_output ~counter:0 1]); - ("1 out", [make_output ~counter:1 1]); - ("1 out 1 1 + out", [make_output ~counter:0 1; make_output ~counter:3 2]); - ( "1 out 1 1 + out out", + ("1", []); + ("1 out", [make_output ~outbox_level ~message_index:0 1]); + ( "1 out 2 out", [ - make_output ~counter:0 1; - make_output ~counter:1 2; - make_output ~counter:2 3; + make_output ~outbox_level ~message_index:0 1; + make_output ~outbox_level ~message_index:1 2; ] ); ] - |> List.iter_es (test_output_messages_proofs ~valid:false) + |> List.iter_es (test_output_messages_proofs ~valid:false ~inbox_level) let tests = [ @@ -386,4 +420,5 @@ let tests = Tztest.tztest "Evaluating message" `Quick test_evaluation_messages; Tztest.tztest "Valid output messages" `Quick test_valid_output_messages; Tztest.tztest "Invalid output messages" `Quick test_invalid_output_messages; + Tztest.tztest "Invalid outbox level" `Quick test_invalid_outbox_level; ]