From 79c46758f5a974a3455a77118908881a9f9f996b Mon Sep 17 00:00:00 2001 From: Sventimir Date: Tue, 15 Mar 2022 16:13:48 +0100 Subject: [PATCH 001/100] Docs: add the concept of MR's owner. --- docs/developer/contributing.rst | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/docs/developer/contributing.rst b/docs/developer/contributing.rst index 811f1e9ff5..b99948d0a1 100644 --- a/docs/developer/contributing.rst +++ b/docs/developer/contributing.rst @@ -441,11 +441,30 @@ Merge Request "Draft" Mode A merge request that is not yet ready for review should be marked as `draft `_ by prefixing its title with ``Draft:``. -On ``tezos/tezos`` draft merge requests are ignored by reviewers. +On ``tezos/tezos`` draft merge requests that are assigned to their owners +are ignored by reviewers. Marking merge requests as draft hence helps lower the number of merge requests that require attention from the :doc:`Octez merge team`. +Merge Request's owner +~~~~~~~~~~~~~~~~~~~~~ + +Usually the person who has created a Merge Request is also responsible for +pushing it forward: finding reviewers, addressing their comments and so on. +Occasionally though it happens that the author has to move to more pressing +tasks and hands his MR over to another person to finish. This is a problem, +because an MR assigned to its author has sort of a special status – it +informs everyone that the branch is likely to change at any moment. When an +MR is handed over, we lose that important information. + +For this reason, when take-over happens, it's useful to make that explicit. +The person taking over should put a comment informing about this so that +everyone knows that the person attending to the MR changes. Also the +description should be updated to reflect that information. It is suggested to +prefix the description with a line specifying the MR's owner if that's +different to the author indicated by GitLab. + .. _adding_new_dependencies: Special case: MRs that introduce a new dependency From 9602d628e58ea29751fa2e7bef5c3c46d9798f38 Mon Sep 17 00:00:00 2001 From: Romain Bardou Date: Mon, 14 Mar 2022 13:00:31 +0100 Subject: [PATCH 002/100] Tezt: add --test-arg / -a --- tezt/lib/cli.ml | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ tezt/lib/cli.mli | 38 ++++++++++++++++++++++++++++++++++++++ tezt/lib/log.ml | 1 + 3 files changed, 87 insertions(+) diff --git a/tezt/lib/cli.ml b/tezt/lib/cli.ml index ca1e1e637a..7c0e81f2e9 100644 --- a/tezt/lib/cli.ml +++ b/tezt/lib/cli.ml @@ -63,6 +63,7 @@ type options = { mutable junit : string option; mutable skip : int; mutable only : int option; + mutable test_args : string String_map.t; } let options = @@ -97,6 +98,7 @@ let options = junit = None; skip = 0; only = None; + test_args = String_map.empty; } let () = at_exit @@ fun () -> Option.iter close_out options.log_file @@ -167,6 +169,20 @@ let init ?args () = if value <= 0 then raise (Arg.Bad "--only must be at least one") ; options.only <- Some value in + let add_test_arg value = + let len = String.length value in + let rec find_equal i = + if i >= len then None + else if value.[i] = '=' then Some i + else find_equal (i + 1) + in + let (parameter, value) = + match find_equal 0 with + | None -> (value, "true") + | Some i -> (String.sub value 0 i, String.sub value (i + 1) (len - i - 1)) + in + options.test_args <- String_map.add parameter value options.test_args + in let spec = Arg.align [ @@ -375,6 +391,14 @@ let init ?args () = Arg.Int set_only, " Only run the first COUNT tests. This filter is applied \ after --job and --skip." ); + ( "--test-arg", + Arg.String add_test_arg, + "= Pass a generic argument to tests. Tests can get \ + this argument with Cli.get. --test-arg is a short-hand \ + for: --test-arg =true" ); + ( "-a", + Arg.String add_test_arg, + "= Same as --test-arg." ); ] in let usage = @@ -428,3 +452,27 @@ let init ?args () = | Arg.Help msg -> Printf.printf "%s" msg ; exit 0 + +let get ?default parse parameter = + match String_map.find_opt parameter options.test_args with + | Some value -> ( + match parse value with + | None -> failwith (sf "invalid value for -a %s: %s" parameter value) + | Some value -> value) + | None -> ( + match default with + | None -> + failwith + (sf + "missing test argument %s, please specify it with: -a %s=" + parameter + parameter) + | Some default -> default) + +let get_bool ?default parameter = get ?default bool_of_string_opt parameter + +let get_int ?default parameter = get ?default int_of_string_opt parameter + +let get_float ?default parameter = get ?default float_of_string_opt parameter + +let get_string ?default parameter = get ?default (fun x -> Some x) parameter diff --git a/tezt/lib/cli.mli b/tezt/lib/cli.mli index c6e0e12e5d..385dafd2b4 100644 --- a/tezt/lib/cli.mli +++ b/tezt/lib/cli.mli @@ -26,6 +26,8 @@ (** Command-line interface. *) +open Base + (** Log levels for standard output. The list below is sorted from the most quiet level to the most verbose level. @@ -99,6 +101,7 @@ type options = { mutable junit : string option; mutable skip : int; mutable only : int option; + mutable test_args : string String_map.t; } (** Values for command-line options. *) @@ -119,3 +122,38 @@ val options : options So if you call [init] several times with the same [--log-file] argument, all logs between the calls to [init] are lost in this file. *) val init : ?args:string list -> unit -> unit + +(** Get the value for a parameter specified with [--test-arg]. + + Usage: [get parse parameter] + + If [--test-arg parameter=value] was specified on the command-line, + this calls [parse] on [value]. If [parse] returns [None], this fails. + If [parse] returns [Some x], this returns [x]. + + If no value for [parameter] was specified on the command-line, + this returns [default] if [default] was specified. Else, this fails. + + It is recommended to make it so that specifying parameters with [--test-arg] + is not mandatory for everyday use. This means it is recommended to always + give default values, and that those default values should be suitable + for typical test runs. For parameters that can take a small number of values, + it is usually better to register multiple tests, one for each possible value, + and to use tags to select from the command-line. + + @raise Failure if [parse] returns [None] or if [parameter] was not + specified on the command-line using [--test-arg] and no [default] + value was provided. *) +val get : ?default:'a -> (string -> 'a option) -> string -> 'a + +(** Same as [get bool_of_string_opt]. *) +val get_bool : ?default:bool -> string -> bool + +(** Same as [get int_of_string_opt]. *) +val get_int : ?default:int -> string -> int + +(** Same as [get float_of_string_opt]. *) +val get_float : ?default:float -> string -> float + +(** Same as [get (fun x -> Some x)]. *) +val get_string : ?default:string -> string -> string diff --git a/tezt/lib/log.ml b/tezt/lib/log.ml index c482013841..d72620306b 100644 --- a/tezt/lib/log.ml +++ b/tezt/lib/log.ml @@ -66,6 +66,7 @@ let channel = junit = _; skip = _; only = _; + test_args = _; } = Cli.options in From ee65c398de2e592ca7edbb32c2e2b894fbc8ecd2 Mon Sep 17 00:00:00 2001 From: Mark Karpov Date: Mon, 14 Mar 2022 17:10:09 +0100 Subject: [PATCH 003/100] Tezt: drop Cli.init, TPS: refactor the app As requested by Romain, here is the change that eliminates the problematic Cli.init function from the Tezt framework. Instead of using commands with cmdliner we now use Tezt tags to select the right "command". We pass options by using the newly conceived --test-arg or -a command line option. --- .gitignore | 1 + Makefile | 3 + manifest/main.ml | 1 - src/bin_tps_evaluation/README.md | 38 ++--- .../benchmark_tps_command.ml | 147 +++++------------- .../benchmark_tps_command.mli | 4 +- src/bin_tps_evaluation/dune | 1 - .../estimate_average_block_command.ml | 104 +++++-------- .../estimate_average_block_command.mli | 4 +- src/bin_tps_evaluation/gas_tps_command.ml | 92 +++-------- src/bin_tps_evaluation/gas_tps_command.mli | 4 +- src/bin_tps_evaluation/main_tps_evaluation.ml | 28 +--- src/bin_tps_evaluation/perform-analysis.sh | 2 +- .../tezos-tps-evaluation-benchmark-tps | 3 + ...ezos-tps-evaluation-estimate-average-block | 3 + .../tezos-tps-evaluation-gas-tps | 3 + .../tezos-tps-evaluation.opam | 1 - tezt/lib/cli.ml | 4 +- tezt/lib/cli.mli | 22 +-- tezt/long_tests/main.ml | 1 - tezt/manual_tests/main.ml | 1 - tezt/records/update.ml | 1 - tezt/self_tests/main.ml | 1 - tezt/snoop/main.ml | 1 - tezt/tests/main.ml | 1 - tezt/vesting_contract_test/main.ml | 1 - 26 files changed, 145 insertions(+), 327 deletions(-) create mode 100755 src/bin_tps_evaluation/tezos-tps-evaluation-benchmark-tps create mode 100755 src/bin_tps_evaluation/tezos-tps-evaluation-estimate-average-block create mode 100755 src/bin_tps_evaluation/tezos-tps-evaluation-gas-tps diff --git a/.gitignore b/.gitignore index 47f8166031..43ae7341c6 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,7 @@ __pycache__ /tezos-codec /tezos-snoop /tezos-tps-evaluation +/tezos-tps-evaluation-* /tezos-sc-rollup-node-* /tezos-sc-rollup-client-* diff --git a/Makefile b/Makefile index d33e20e9e3..8cee1b5c8e 100644 --- a/Makefile +++ b/Makefile @@ -309,6 +309,9 @@ build-tps-deps: build-tps: lift-protocol-limits-patch build build-tezt @dune build ./src/bin_tps_evaluation @cp -f ./_build/install/default/bin/tezos-tps-evaluation . + @cp -f ./src/bin_tps_evaluation/tezos-tps-evaluation-benchmark-tps . + @cp -f ./src/bin_tps_evaluation/tezos-tps-evaluation-estimate-average-block . + @cp -f ./src/bin_tps_evaluation/tezos-tps-evaluation-gas-tps . .PHONY: docker-image-build docker-image-build: diff --git a/manifest/main.ml b/manifest/main.ml index 06b8580e15..b320b32f65 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -3318,7 +3318,6 @@ let _tezos_tps_evaluation = caqti; caqti_driver_postgresql; caqti_lwt; - cmdliner; data_encoding; lwt; ppx_blob; diff --git a/src/bin_tps_evaluation/README.md b/src/bin_tps_evaluation/README.md index 97b22f5a1b..b39059288b 100644 --- a/src/bin_tps_evaluation/README.md +++ b/src/bin_tps_evaluation/README.md @@ -74,7 +74,7 @@ It is possible to get an estimation of the maximal possible TPS by using the protocol parameters. ``` -./tezos-tps-evaluation gas-tps --average-block=src/bin_tps_evaluation/average-block.json +./tezos-tps-evaluation-gas-tps -a average-block=src/bin_tps_evaluation/average-block.json [14:26:25.243] Starting test: tezos_tps_gas [14:26:27.956] Reading description of the average block from src/bin_tps_evaluation/average-block.json [14:26:28.061] Originating smart contracts @@ -87,8 +87,9 @@ protocol parameters. This estimation is obtained by dividing the hard gas limit per block by the average transaction cost. -The `gas-tps` command will also register its result in a database if -`tezt_config.json` exists (see [these instructions][long-tezts-locally]). +The `tezos-tps-evaluation-gas-tps` command will also register its result in +a database if `tezt_config.json` exists (see [these +instructions][long-tezts-locally]). ## Running the TPS benchmark @@ -99,36 +100,23 @@ reached and after that it will run the stress test client command. The TPS parameter that is passed to the stress test command (we call this **target TPS of injection**) depends on the presence of the -`--lift-protocol-limits` flag: +`-a lift-protocol-limits` flag: -* If `--lift-protocol-limits` is passed, an arbitrary big value is passed, +* If `-a lift-protocol-limits` is passed, an arbitrary big value is passed, so that stress test will inject as fast as possible. -* If no `--lift-protocol-limits` is passed, TPS computed from gas (see the +* If no `-a lift-protocol-limits` is passed, TPS computed from gas (see the previous section for details) will be used as the target TPS of injection. By default 10 blocks will be produced, but this can be changed by supplying -the `--blocks-total` command line option. The total number of applied +the `-a blocks-total` command line option. The total number of applied operations will be divided by the total time spent producing the blocks and the resulting value will be presented as the **empirical TPS**. The benchmark is also capable of calculating **de facto TPS of injection** which is useful in judging the results. -It is possible to pass command line arguments to the underlying Tezt -framework. To accomplish that pass arguments after the double dash -delimiter. For example: - -```bash -./tezos-tps-evaluation benchmark-tps -- --help -``` - -will print command line options that the Tezt framework accepts. `-- -v` can -be helpful for obtaining a detailed log. - -Consult `./tezos-tps-evaluation benchmark-tps --help` to see all accepted -command line options. - -The `benchmark-tps` command will also register its result in a database if -`tezt_config.json` exists (see [these instructions][long-tezts-locally]). +The `tezos-tps-evaluation-benchmark-tps` command will also register its +result in a database if `tezt_config.json` exists (see [these +instructions][long-tezts-locally]). ### Making sense of the results @@ -138,7 +126,7 @@ to catch TPS regressions, but not to find where exactly the bottlenecks are. The empirical TPS is significantly affected by the hardware on which the benchmark is run and other factors, such as the amount of logging that is -performed. For example, passing `-- -v` is likely to result in much lower +performed. For example, passing `-v` is likely to result in much lower empirical TPS values. The empirical TPS should normally be very close to the de facto TPS of @@ -173,7 +161,7 @@ trustworthy: ### Example usage ``` -./tezos-tps-evaluation benchmark-tps --average-block=src/bin_tps_evaluation/average_block.json --lift-protocol-limits +./tezos-tps-evaluation-benchmark-tps -a average-block=src/bin_tps_evaluation/average_block.json -a lift-protocol-limits [12:20:57.387] Tezos TPS benchmark [12:20:57.387] Protocol: Alpha [12:20:57.387] Total number of accounts to use: 5 diff --git a/src/bin_tps_evaluation/benchmark_tps_command.ml b/src/bin_tps_evaluation/benchmark_tps_command.ml index 7e827add22..7744c2b844 100644 --- a/src/bin_tps_evaluation/benchmark_tps_command.ml +++ b/src/bin_tps_evaluation/benchmark_tps_command.ml @@ -243,108 +243,45 @@ let regression_handling defacto_tps_of_injection empirical_tps in save_and_check "empirical_tps" @@ fun () -> empirical_tps -module Term = struct - let accounts_total_arg = - let open Cmdliner in - let doc = "The number of bootstrap accounts to use in the benchmark" in - let docv = "ACCOUNTS_TOTAL" in - Arg.(value & opt int 5 & info ["accounts-total"] ~docv ~doc) - - let blocks_total_arg = - let open Cmdliner in - let doc = "The number of blocks to bake during the benchmark" in - let docv = "BLOCKS_TOTAL" in - Arg.(value & opt int 10 & info ["blocks-total"] ~docv ~doc) - - let average_block_path_arg = - let open Cmdliner in - let doc = "Path to the file with description of the average block" in - let docv = "AVERAGE_BLOCK_PATH" in - Arg.(value & opt (some string) None & info ["average-block"] ~docv ~doc) - - let lift_protocol_limits_arg = - let open Cmdliner in - let doc = - "Remove any protocol settings that may limit the maximum achievable TPS" - in - let docv = "LIFT_PROTOCOL_LIMITS" in - Arg.(value (flag & info ["lift-protocol-limits"] ~docv ~doc)) - - let tps_of_injection_arg = - let open Cmdliner in - let doc = "The injection TPS value that we should use" in - let docv = "TPS_OF_INJECTION" in - Arg.(value & opt (some int) None & info ["tps-of-injection"] ~docv ~doc) - - let tezt_args = - let open Cmdliner in - let doc = - "Extra arguments after -- to be passed directly to Tezt. Contains `-i` \ - by default to display info log level." - in - let docv = "TEZT_ARGS" in - Arg.(value & pos_all string [] & info [] ~docv ~doc) - - let previous_count_arg = - let open Cmdliner in - let doc = - "The number of previously recorded samples that must be compared to the \ - result of this benchmark" - in - let docv = "PREVIOUS_SAMPLE_COUNT" in - Arg.( - value & opt int 10 & info ["regression-previous-sample-count"] ~docv ~doc) - - let term = - let process accounts_total blocks_total average_block_path - lift_protocol_limits provided_tps_of_injection tezt_args previous_count - = - (try Cli.init ~args:("-i" :: tezt_args) () - with Arg.Help help_str -> - Format.eprintf "%s@." help_str ; - exit 0) ; - Long_test.init () ; - let executors = Long_test.[x86_executor1] in - Long_test.register - ~__FILE__ - ~title:"tezos_tps_benchmark" - ~tags:[] - ~timeout:(Long_test.Minutes 60) - ~executors - (fun () -> - let* (defacto_tps_of_injection, empirical_tps) = - run_benchmark - ~lift_protocol_limits - ~provided_tps_of_injection - ~accounts_total - ~blocks_total - ~average_block_path - () - in - regression_handling - defacto_tps_of_injection - empirical_tps - lift_protocol_limits - ~previous_count) ; - Test.run () ; - `Ok () - in - let open Cmdliner.Term in - ret - (const process $ accounts_total_arg $ blocks_total_arg - $ average_block_path_arg $ lift_protocol_limits_arg $ tps_of_injection_arg - $ tezt_args $ previous_count_arg) -end - -module Manpage = struct - let command_description = - "Run the benchmark and print out the results on stdout" - - let description = [`S "DESCRIPTION"; `P command_description] - - let man = description - - let info = Cmdliner.Term.info ~doc:command_description ~man "benchmark-tps" -end - -let cmd = (Term.term, Manpage.info) +let register () = + Long_test.register + ~__FILE__ + ~title:"tezos_tps_benchmark" + ~tags:["tezos_tps_benchmark"] + ~timeout:(Long_test.Minutes 60) + ~executors:Long_test.[x86_executor1] + (fun () -> + let lift_protocol_limits = + Cli.get_bool ~default:false "lift-protocol-limits" + in + let provided_tps_of_injection = + Cli.get + ~default:None + (fun s -> + match int_of_string_opt s with + | None -> None + | Some x -> Some (Some x)) + "provided_tps_of_injection" + in + let accounts_total = Cli.get_int ~default:5 "accounts-total" in + let blocks_total = Cli.get_int ~default:10 "blocks-total" in + let average_block_path = + Cli.get ~default:None (fun s -> Some (Some s)) "average-block" + in + let previous_count = + Cli.get_int ~default:10 "regression-previous-sample-count" + in + let* (defacto_tps_of_injection, empirical_tps) = + run_benchmark + ~lift_protocol_limits + ~provided_tps_of_injection + ~accounts_total + ~blocks_total + ~average_block_path + () + in + regression_handling + defacto_tps_of_injection + empirical_tps + lift_protocol_limits + ~previous_count) diff --git a/src/bin_tps_evaluation/benchmark_tps_command.mli b/src/bin_tps_evaluation/benchmark_tps_command.mli index 6a25822791..5769af92b6 100644 --- a/src/bin_tps_evaluation/benchmark_tps_command.mli +++ b/src/bin_tps_evaluation/benchmark_tps_command.mli @@ -23,5 +23,5 @@ (* *) (*****************************************************************************) -(** Cmdliner's command definition for the "benchmark TPS" command. *) -val cmd : unit Cmdliner.Term.t * Cmdliner.Term.info +(** Register the TPS benchmark as a Tezt long test. *) +val register : unit -> unit diff --git a/src/bin_tps_evaluation/dune b/src/bin_tps_evaluation/dune index 8593842659..f8d5e25bde 100644 --- a/src/bin_tps_evaluation/dune +++ b/src/bin_tps_evaluation/dune @@ -11,7 +11,6 @@ caqti caqti-driver-postgresql caqti-lwt - cmdliner data-encoding lwt ppx_blob diff --git a/src/bin_tps_evaluation/estimate_average_block_command.ml b/src/bin_tps_evaluation/estimate_average_block_command.ml index 3bac89c0e4..d84659dfb5 100644 --- a/src/bin_tps_evaluation/estimate_average_block_command.ml +++ b/src/bin_tps_evaluation/estimate_average_block_command.ml @@ -198,71 +198,39 @@ module Json = struct end (** Execute the query against the database and formats the result. *) -let query_db start_date end_date limit conn_str = - Lwt_main.run - ( Lwt.bind - (Db.get_operation_summary conn_str start_date end_date ()) - (function - | Ok rows -> Lwt.return rows - | Error e -> Stdlib.failwith (Caqti_error.show e)) - >>= fun summary -> - Lwt.bind - (Db.get_top_contracts conn_str start_date end_date limit ()) - (function - | Ok rows -> Lwt.return rows - | Error e -> Stdlib.failwith (Caqti_error.show e)) - >>= fun top_contracts -> - Lwt.return (Json.show_summary summary top_contracts) ) - -module Term = struct - let connection_string_arg = - let open Cmdliner in - let doc = "PostgreSQL connection string" in - let docv = "CONNECTION_STRING" in - Arg.( - value - & opt string "postgresql://postgres:postgres@localhost:5432/postgres" - & info ["c"; "connection-string"] ~docv ~doc) - - let start_date_arg = - let open Cmdliner in - let doc = "The start date to use in the query" in - let docv = "START_DATE" in - let info = Arg.info ["s"; "start-date"] ~docv ~doc in - Arg.required (Arg.opt (Arg.some Arg.string) None info) - - let end_date_arg = - let open Cmdliner in - let doc = "The end date to use in the the query" in - let docv = "END_DATE" in - let info = Arg.info ["e"; "end-date"] ~docv ~doc in - Arg.required (Arg.opt (Arg.some Arg.string) None info) - - let contract_min_percentage_arg = - let open Cmdliner in - let doc = - "The minimum percentage of operations for a contract to be included" - in - let docv = "CONTRACT_MIN_PERCENTAGE" in - Arg.( - value & opt float 0.1 & info ["p"; "contract-min-percentage"] ~docv ~doc) - - let estimate_average_block = - let open Cmdliner.Term in - const query_db $ start_date_arg $ end_date_arg $ contract_min_percentage_arg - $ connection_string_arg -end - -module Manpage = struct - let command_description = - "Use historical data to estimate contents of the average block" - - let description = [`S "DESCRIPTION"; `P command_description] - - let man = description - - let info = - Cmdliner.Term.info ~doc:command_description ~man "estimate-average-block" -end - -let cmd = (Term.estimate_average_block, Manpage.info) +let query_db start_date end_date contract_min_percentage conn_str = + Lwt.bind (Db.get_operation_summary conn_str start_date end_date ()) (function + | Ok rows -> Lwt.return rows + | Error e -> Stdlib.failwith (Caqti_error.show e)) + >>= fun summary -> + Lwt.bind + (Db.get_top_contracts + conn_str + start_date + end_date + contract_min_percentage + ()) + (function + | Ok rows -> Lwt.return rows + | Error e -> Stdlib.failwith (Caqti_error.show e)) + >>= fun top_contracts -> Lwt.return (Json.show_summary summary top_contracts) + +let register () = + Long_test.register + ~__FILE__ + ~title:"tezos_tps_estimate_average_block" + ~tags:["tezos_tps_estimate_average_block"] + ~timeout:(Long_test.Minutes 60) + ~executors:Long_test.[x86_executor1] + (fun () -> + let connection_string = + Cli.get_string + ~default:"postgresql://postgres:postgres@localhost:5432/postgres" + "connection-string" + in + let start_date = Cli.get_string "start-date" in + let end_date = Cli.get_string "end-date" in + let contract_min_percentage = + Cli.get_float ~default:0.1 "contract-min-percentage" + in + query_db start_date end_date contract_min_percentage connection_string) diff --git a/src/bin_tps_evaluation/estimate_average_block_command.mli b/src/bin_tps_evaluation/estimate_average_block_command.mli index 93712c4979..4d70741b54 100644 --- a/src/bin_tps_evaluation/estimate_average_block_command.mli +++ b/src/bin_tps_evaluation/estimate_average_block_command.mli @@ -23,5 +23,5 @@ (* *) (*****************************************************************************) -(** Cmdliner's command definition for "estimate average block" command. *) -val cmd : unit Cmdliner.Term.t * Cmdliner.Term.info +(** Register estimation of average block as a Tezt long test. *) +val register : unit -> unit diff --git a/src/bin_tps_evaluation/gas_tps_command.ml b/src/bin_tps_evaluation/gas_tps_command.ml index 1c6ca02cb7..1bf40db88f 100644 --- a/src/bin_tps_evaluation/gas_tps_command.ml +++ b/src/bin_tps_evaluation/gas_tps_command.ml @@ -60,74 +60,24 @@ let estimate_gas_tps ~average_block_path () = Node.terminate ~kill:true node >>= fun () -> Lwt.return @@ float_of_int gas_tps -module Term = struct - let average_block_path_arg = - let open Cmdliner in - let doc = "Path to the file with description of the average block" in - let docv = "AVERAGE_BLOCK_PATH" in - Arg.(value & opt (some string) None & info ["average-block"] ~docv ~doc) - - let tezt_args = - let open Cmdliner in - let doc = - "Extra arguments after -- to be passed directly to Tezt. Contains `-i` \ - by default to display info log level." - in - let docv = "TEZT_ARGS" in - Arg.(value & pos_all string [] & info [] ~docv ~doc) - - let previous_count_arg = - let open Cmdliner in - let doc = - "The number of previously recorded samples that must be compared to the \ - result of this benchmark" - in - let docv = "PREVIOUS_SAMPLE_COUNT" in - Arg.( - value & opt int 10 & info ["regression-previous-sample-count"] ~docv ~doc) - - let term = - let process average_block_path tezt_args previous_count = - (* We are going to need to call the client stress test command here in - order to get an estimation of gas cost of various transactions that - stress test uses. This functionality is also protocol-dependent, so - we need to start a node, too. Hence we use the tezt network to spin - up the network. *) - (try Cli.init ~args:("-i" :: tezt_args) () - with Arg.Help help_str -> - Format.eprintf "%s@." help_str ; - exit 0) ; - Long_test.init () ; - let executors = Long_test.[x86_executor1] in - Long_test.register - ~__FILE__ - ~title:"tezos_tps_gas" - ~tags:[] - ~timeout:(Long_test.Minutes 1) - ~executors - (fun () -> - Long_test.measure_and_check_regression_lwt - ~previous_count - ~minimum_previous_count:previous_count - ~stddev:false - ~repeat:1 - "tps_evaluation" - @@ estimate_gas_tps ~average_block_path) ; - Test.run () ; - `Ok () - in - let open Cmdliner.Term in - ret (const process $ average_block_path_arg $ tezt_args $ previous_count_arg) -end - -module Manpage = struct - let command_description = "Estimate TPS based on gas" - - let description = [`S "DESCRIPTION"; `P command_description] - - let man = description - - let info = Cmdliner.Term.info ~doc:command_description ~man "gas-tps" -end - -let cmd = (Term.term, Manpage.info) +let register () = + Long_test.register + ~__FILE__ + ~title:"tezos_gas_tps" + ~tags:["tezos_gas_tps"] + ~timeout:(Long_test.Minutes 60) + ~executors:Long_test.[x86_executor1] + (fun () -> + let average_block_path = + Cli.get ~default:None (fun s -> Some (Some s)) "average-block" + in + let previous_count = + Cli.get_int ~default:10 "regression-previous-sample-count" + in + Long_test.measure_and_check_regression_lwt + ~previous_count + ~minimum_previous_count:previous_count + ~stddev:false + ~repeat:1 + "tps_evaluation" + @@ estimate_gas_tps ~average_block_path) diff --git a/src/bin_tps_evaluation/gas_tps_command.mli b/src/bin_tps_evaluation/gas_tps_command.mli index 99a75fba51..a50e6d45ea 100644 --- a/src/bin_tps_evaluation/gas_tps_command.mli +++ b/src/bin_tps_evaluation/gas_tps_command.mli @@ -23,5 +23,5 @@ (* *) (*****************************************************************************) -(** Cmdliner's command definition for the "gas TPS" command. *) -val cmd : unit Cmdliner.Term.t * Cmdliner.Term.info +(** Register gas estimation of TPS as a Tezt long test. *) +val register : unit -> unit diff --git a/src/bin_tps_evaluation/main_tps_evaluation.ml b/src/bin_tps_evaluation/main_tps_evaluation.ml index 75623ef0f4..698f892993 100644 --- a/src/bin_tps_evaluation/main_tps_evaluation.ml +++ b/src/bin_tps_evaluation/main_tps_evaluation.ml @@ -23,27 +23,9 @@ (* *) (*****************************************************************************) -let commands = - [ - Benchmark_tps_command.cmd; - Estimate_average_block_command.cmd; - Gas_tps_command.cmd; - ] - -let term = - let open Cmdliner.Term in - ret (const (`Help (`Pager, None))) - -let info = - let version = Tezos_version.Bin_version.version_string in - Cmdliner.Term.info - ~doc:"The Tezos TPS evaluation tool" - ~version - "tezos-tps-evaluation" - let () = - match Cmdliner.Term.eval_choice (term, info) commands with - | `Error _ -> exit 1 - | `Help -> exit 0 - | `Version -> exit 0 - | `Ok () -> exit 0 + Long_test.init () ; + Benchmark_tps_command.register () ; + Estimate_average_block_command.register () ; + Gas_tps_command.register () ; + Test.run () diff --git a/src/bin_tps_evaluation/perform-analysis.sh b/src/bin_tps_evaluation/perform-analysis.sh index 7c0892a3de..4ab9cdbc02 100755 --- a/src/bin_tps_evaluation/perform-analysis.sh +++ b/src/bin_tps_evaluation/perform-analysis.sh @@ -25,7 +25,7 @@ declare -r RESULT_FILE="$START_DATE-to-$END_DATE.json" docker run -d --name tezos_history_analysis -p 5432:5432 -e POSTGRES_HOST_AUTH_METHOD=trust -e POSTGRES_USER=tezos postgres:14-alpine bunzip2 -c "$DATABASE_DUMP_FILE" | docker exec -i tezos_history_analysis psql -U tezos -a tezos -../../tezos-tps-evaluation estimate-average-block -c postgresql://tezos:tezos@localhost:5432 --start "$START_DATE" --end "$END_DATE" > "$RESULT_FILE" +../../tezos-tps-evaluation-estimate-average-block -a connection-string=postgresql://tezos:tezos@localhost:5432 -a start-date="$START_DATE" -a end-date="$END_DATE" > "$RESULT_FILE" cp "$RESULT_FILE" "average-block.json" docker stop tezos_history_analysis docker rm tezos_history_analysis diff --git a/src/bin_tps_evaluation/tezos-tps-evaluation-benchmark-tps b/src/bin_tps_evaluation/tezos-tps-evaluation-benchmark-tps new file mode 100755 index 0000000000..bb68fd15e3 --- /dev/null +++ b/src/bin_tps_evaluation/tezos-tps-evaluation-benchmark-tps @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +./tezos-tps-evaluation -i tezos_tps_benchmark "$@" diff --git a/src/bin_tps_evaluation/tezos-tps-evaluation-estimate-average-block b/src/bin_tps_evaluation/tezos-tps-evaluation-estimate-average-block new file mode 100755 index 0000000000..2afa7a0071 --- /dev/null +++ b/src/bin_tps_evaluation/tezos-tps-evaluation-estimate-average-block @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +./tezos-tps-evaluation -i tezos_tps_estimate_average_block "$@" diff --git a/src/bin_tps_evaluation/tezos-tps-evaluation-gas-tps b/src/bin_tps_evaluation/tezos-tps-evaluation-gas-tps new file mode 100755 index 0000000000..9b3be6bd93 --- /dev/null +++ b/src/bin_tps_evaluation/tezos-tps-evaluation-gas-tps @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +./tezos-tps-evaluation -i tezos_gas_tps "$@" diff --git a/src/bin_tps_evaluation/tezos-tps-evaluation.opam b/src/bin_tps_evaluation/tezos-tps-evaluation.opam index 820f31b7bb..0112cd0fef 100644 --- a/src/bin_tps_evaluation/tezos-tps-evaluation.opam +++ b/src/bin_tps_evaluation/tezos-tps-evaluation.opam @@ -14,7 +14,6 @@ depends: [ "caqti" "caqti-driver-postgresql" "caqti-lwt" - "cmdliner" "data-encoding" { >= "0.5.1" & < "0.6" } "lwt" { >= "5.4.0" } "tezos-baking-alpha" diff --git a/tezt/lib/cli.ml b/tezt/lib/cli.ml index 7c0e81f2e9..1a58c07c74 100644 --- a/tezt/lib/cli.ml +++ b/tezt/lib/cli.ml @@ -453,6 +453,8 @@ let init ?args () = Printf.printf "%s" msg ; exit 0 +let () = init () + let get ?default parse parameter = match String_map.find_opt parameter options.test_args with | Some value -> ( @@ -475,4 +477,4 @@ let get_int ?default parameter = get ?default int_of_string_opt parameter let get_float ?default parameter = get ?default float_of_string_opt parameter -let get_string ?default parameter = get ?default (fun x -> Some x) parameter +let get_string ?default parameter = get ?default Option.some parameter diff --git a/tezt/lib/cli.mli b/tezt/lib/cli.mli index 385dafd2b4..9fb13afc74 100644 --- a/tezt/lib/cli.mli +++ b/tezt/lib/cli.mli @@ -24,7 +24,11 @@ (* *) (*****************************************************************************) -(** Command-line interface. *) +(** Command-line interface. + + When this module is loaded, it parses command line options + unconditionally as a side-effect. +*) open Base @@ -107,22 +111,6 @@ type options = { (** Values for command-line options. *) val options : options -(** Read command-line options to initialize [options]. - - By default arguments are read from [Sys.argv], but you can specify [args] - to override this behavior. Note that [args] must not contain the executable - name ([Sys.argv.(0)]), only actual arguments. - - If you do not call [init], [options] will contain only default values. - - [init] exits the program on failure to parse the arguments (with code 2) or - when either [-help] or [--help] is present (with code 0). - - Warning: if [--log-file] is specified, the file is truncated. - So if you call [init] several times with the same [--log-file] argument, - all logs between the calls to [init] are lost in this file. *) -val init : ?args:string list -> unit -> unit - (** Get the value for a parameter specified with [--test-arg]. Usage: [get parse parameter] diff --git a/tezt/long_tests/main.ml b/tezt/long_tests/main.ml index 8faae6d927..2e883e8747 100644 --- a/tezt/long_tests/main.ml +++ b/tezt/long_tests/main.ml @@ -50,7 +50,6 @@ let () = let default_executors = Long_test.[x86_executor1] let () = - Cli.init () ; Long_test.init () ; (* Register your tests here. *) (* This test depends on [Tezos_protocol_alpha.*] Tezos libraries *) diff --git a/tezt/manual_tests/main.ml b/tezt/manual_tests/main.ml index 569c4de31f..f3914108fa 100644 --- a/tezt/manual_tests/main.ml +++ b/tezt/manual_tests/main.ml @@ -28,7 +28,6 @@ as functions to be called here. *) let () = - Cli.init () ; Migration.register () ; Migration_voting.register () ; (* Test.run () should be the last statement, don't register afterwards! *) diff --git a/tezt/records/update.ml b/tezt/records/update.ml index de0fbe1f3f..297587b37f 100644 --- a/tezt/records/update.ml +++ b/tezt/records/update.ml @@ -81,7 +81,6 @@ let fetch_pipeline_records () = Lwt_list.iter_p fetch_record records let () = - Cli.init () ; (* Register a test to benefit from error handling of Test.run, as well as [Background.start] etc. *) ( Test.register ~__FILE__ ~title:"update records" ~tags:["update"] @@ fun () -> diff --git a/tezt/self_tests/main.ml b/tezt/self_tests/main.ml index c96caf1909..7f3695c8e5 100644 --- a/tezt/self_tests/main.ml +++ b/tezt/self_tests/main.ml @@ -26,7 +26,6 @@ (* Tests that test Tezt itself. *) let () = - Cli.init () ; Test_check.register () ; Test_daemon.register () ; Test_retry.register () ; diff --git a/tezt/snoop/main.ml b/tezt/snoop/main.ml index 7b64e7b7b7..5ffab1d004 100644 --- a/tezt/snoop/main.ml +++ b/tezt/snoop/main.ml @@ -33,6 +33,5 @@ let run proto = Perform_inference.main ()) let () = - Cli.init () ; Background.start (fun x -> raise x) ; run Protocol.Alpha diff --git a/tezt/tests/main.ml b/tezt/tests/main.ml index 0ba837dda0..7fdc690ab4 100644 --- a/tezt/tests/main.ml +++ b/tezt/tests/main.ml @@ -42,7 +42,6 @@ let migrate_to = Protocol.Alpha Each module defines tests which are thematically related, as functions to be called here. *) let () = - Cli.init () ; (* Tests that are relatively protocol-agnostic. We can run them on all protocols, or only one if the CI would be too slow. *) Baker_test.register ~protocols:[Alpha] ; diff --git a/tezt/vesting_contract_test/main.ml b/tezt/vesting_contract_test/main.ml index 9d16475c54..eaf5773aab 100644 --- a/tezt/vesting_contract_test/main.ml +++ b/tezt/vesting_contract_test/main.ml @@ -54,7 +54,6 @@ let tests = let () = (* Register your tests here. *) - Cli.init () ; List.iter (fun (test, title, user_count) -> Test.register From b305ab7c8cd81a2d7d764c8e18c56c8f16a33d96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Proust?= Date: Mon, 14 Mar 2022 14:36:38 +0100 Subject: [PATCH 004/100] Proto-compiler,Proto-updater: convert to newer let* syntax --- src/lib_protocol_compiler/bin/replace.ml | 34 ++++----- src/lib_protocol_updater/updater.ml | 89 ++++++++++++++---------- 2 files changed, 69 insertions(+), 54 deletions(-) diff --git a/src/lib_protocol_compiler/bin/replace.ml b/src/lib_protocol_compiler/bin/replace.ml index f6b7a947c2..6986422728 100644 --- a/src/lib_protocol_compiler/bin/replace.ml +++ b/src/lib_protocol_compiler/bin/replace.ml @@ -127,22 +127,24 @@ let read_proto destination final_protocol_file = else Filename.dirname destination in Lwt_main.run - ( Lwt_utils_unix.read_file final_protocol_file >>= fun final_protocol -> - let final_protocol = - List.map Protocol_hash.of_b58check_exn - @@ String.split_on_char '\n' final_protocol - in - Tezos_base_unix.Protocol_files.read_dir source_dir >|= function - | Ok (None, proto) -> (Protocol.hash proto, proto, false) - | Ok (Some hash, proto) -> - (hash, proto, List.mem ~equal:Protocol_hash.equal hash final_protocol) - | Error err -> - Format.kasprintf - Stdlib.failwith - "Failed to read TEZOS_PROTOCOL in %s:@ %a" - source_dir - pp_print_trace - err ) + (let open Lwt_syntax in + let* final_protocol = Lwt_utils_unix.read_file final_protocol_file in + let final_protocol = + List.map Protocol_hash.of_b58check_exn + @@ String.split_on_char '\n' final_protocol + in + let+ r = Tezos_base_unix.Protocol_files.read_dir source_dir in + match r with + | Ok (None, proto) -> (Protocol.hash proto, proto, false) + | Ok (Some hash, proto) -> + (hash, proto, List.mem ~equal:Protocol_hash.equal hash final_protocol) + | Error err -> + Format.kasprintf + Stdlib.failwith + "Failed to read TEZOS_PROTOCOL in %s:@ %a" + source_dir + pp_print_trace + err) let main () = let template = Sys.argv.(1) in diff --git a/src/lib_protocol_updater/updater.ml b/src/lib_protocol_updater/updater.ml index 171ee2c8ff..435c28db9a 100644 --- a/src/lib_protocol_updater/updater.ml +++ b/src/lib_protocol_updater/updater.ml @@ -31,21 +31,20 @@ module Events = Updater_events let datadir = ref None let get_datadir () = + let open Lwt_syntax in match !datadir with | None -> - Events.(emit node_uninitialized) () >>= fun () -> + let* () = Events.(emit node_uninitialized) () in Lwt_exit.exit_and_raise 1 | Some m -> Lwt.return m let init dir = datadir := Some dir -(* An optimization trick to avoid allocating meaningless promisses. *) -let then_false () = Lwt.return_false - let compiler_name = "tezos-protocol-compiler" let do_compile hash p = - get_datadir () >>= fun datadir -> + let open Lwt_syntax in + let* datadir = get_datadir () in let source_dir = datadir // Protocol_hash.to_short_b58check hash // "src" in let log_file = datadir // Protocol_hash.to_short_b58check hash // "LOG" in let plugin_file = @@ -53,43 +52,57 @@ let do_compile hash p = // Protocol_hash.to_short_b58check hash // Format.asprintf "protocol_%a" Protocol_hash.pp hash in - ( Tezos_base_unix.Protocol_files.write_dir source_dir ~hash p >>=? fun () -> - let compiler_command = - ( Sys.executable_name, - Array.of_list - [compiler_name; "-register"; "-o"; plugin_file; source_dir] ) - in - let fd = Unix.(openfile log_file [O_WRONLY; O_CREAT; O_TRUNC] 0o644) in - Lwt_process.exec - ~stdin:`Close - ~stdout:(`FD_copy fd) - ~stderr:(`FD_move fd) - compiler_command - >>= return ) - >>= function - | Error err -> Events.(emit compiler_exit_error) err >>= then_false - | Ok (Unix.WSIGNALED _ | Unix.WSTOPPED _) -> - Events.(emit compilation_interrupted) log_file >>= then_false - | Ok (Unix.WEXITED x) when x <> 0 -> - Events.(emit compilation_error) log_file >>= then_false - | Ok (Unix.WEXITED _) -> ( - try - Dynlink.loadfile_private (plugin_file ^ ".cmxs") ; - Lwt.return_true - with - | Dynlink.(Error (Cannot_open_dynamic_library exn)) -> - Events.(emit dynlink_error_static) - (plugin_file, Printexc.to_string exn) - >>= then_false - | Dynlink.(Error err) -> - Events.(emit dynlink_error) (plugin_file, Dynlink.error_message err) - >>= then_false) + let* r = Tezos_base_unix.Protocol_files.write_dir source_dir ~hash p in + match r with + | Error err -> + let* () = Events.(emit compiler_exit_error) err in + Lwt.return_false + | Ok () -> ( + let compiler_command = + ( Sys.executable_name, + Array.of_list + [compiler_name; "-register"; "-o"; plugin_file; source_dir] ) + in + let fd = Unix.(openfile log_file [O_WRONLY; O_CREAT; O_TRUNC] 0o644) in + let* s = + Lwt_process.exec + ~stdin:`Close + ~stdout:(`FD_copy fd) + ~stderr:(`FD_move fd) + compiler_command + in + match s with + | Unix.WSIGNALED _ | Unix.WSTOPPED _ -> + let* () = Events.(emit compilation_interrupted) log_file in + Lwt.return_false + | Unix.WEXITED x when x <> 0 -> + let* () = Events.(emit compilation_error) log_file in + Lwt.return_false + | Unix.WEXITED _ -> ( + try + Dynlink.loadfile_private (plugin_file ^ ".cmxs") ; + Lwt.return_true + with + | Dynlink.(Error (Cannot_open_dynamic_library exn)) -> + let* () = + Events.(emit dynlink_error_static) + (plugin_file, Printexc.to_string exn) + in + Lwt.return_false + | Dynlink.(Error err) -> + let* () = + Events.(emit dynlink_error) + (plugin_file, Dynlink.error_message err) + in + Lwt.return_false)) let compile hash p = + let open Lwt_syntax in if Tezos_protocol_registerer.Registerer.mem hash then Lwt.return_true else - do_compile hash p >>= fun success -> + let* success = do_compile hash p in let loaded = Tezos_protocol_registerer.Registerer.mem hash in if success && not loaded then - Events.(emit internal_error) hash >>= fun () -> Lwt.return loaded + let* () = Events.(emit internal_error) hash in + Lwt.return loaded else Lwt.return loaded From 083dd96da6798f0c288800cbde67ad06e1fd5d2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Proust?= Date: Wed, 16 Mar 2022 09:32:48 +0100 Subject: [PATCH 005/100] Proto-updater: minor code improvement --- src/lib_protocol_updater/updater.ml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lib_protocol_updater/updater.ml b/src/lib_protocol_updater/updater.ml index 435c28db9a..b804f4abed 100644 --- a/src/lib_protocol_updater/updater.ml +++ b/src/lib_protocol_updater/updater.ml @@ -60,8 +60,7 @@ let do_compile hash p = | Ok () -> ( let compiler_command = ( Sys.executable_name, - Array.of_list - [compiler_name; "-register"; "-o"; plugin_file; source_dir] ) + [|compiler_name; "-register"; "-o"; plugin_file; source_dir|] ) in let fd = Unix.(openfile log_file [O_WRONLY; O_CREAT; O_TRUNC] 0o644) in let* s = From 49dcef3f933ea86261553a63455b27f7588f6f4f Mon Sep 17 00:00:00 2001 From: Richard Davison Date: Mon, 14 Mar 2022 17:20:50 +0000 Subject: [PATCH 006/100] Manifest: lib_sc_rollup --- src/proto_alpha/lib_sc_rollup/dune | 27 ++++++++++--------- src/proto_alpha/lib_sc_rollup/dune-project | 1 - .../lib_sc_rollup/tezos-sc-rollup-alpha.opam | 7 ++--- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/proto_alpha/lib_sc_rollup/dune b/src/proto_alpha/lib_sc_rollup/dune index 5294e32dc0..f946db0c5a 100644 --- a/src/proto_alpha/lib_sc_rollup/dune +++ b/src/proto_alpha/lib_sc_rollup/dune @@ -1,17 +1,20 @@ (library (name tezos_sc_rollup_alpha) - (instrumentation (backend bisect_ppx)) (public_name tezos-sc-rollup-alpha) - (libraries tezos-base - tezos-rpc - tezos-protocol-alpha - tezos-protocol-alpha-parameters - tezos-protocol-plugin-alpha) - (inline_tests) + (instrumentation (backend bisect_ppx)) + (libraries + tezos-base + tezos-protocol-alpha + tezos-protocol-plugin-alpha + tezos-protocol-alpha-parameters + tezos-rpc) + (inline_tests (flags -verbose)) (preprocess (pps ppx_inline_test)) (library_flags (:standard -linkall)) - (flags (:standard -open Tezos_base__TzPervasives - -open Tezos_protocol_alpha - -open Tezos_protocol_plugin_alpha - -open Tezos_protocol_alpha_parameters - -open Tezos_rpc))) + (flags + (:standard + -open Tezos_base.TzPervasives + -open Tezos_protocol_alpha + -open Tezos_protocol_plugin_alpha + -open Tezos_protocol_alpha_parameters + -open Tezos_rpc))) diff --git a/src/proto_alpha/lib_sc_rollup/dune-project b/src/proto_alpha/lib_sc_rollup/dune-project index e8836f1257..47aa0dd4c4 100644 --- a/src/proto_alpha/lib_sc_rollup/dune-project +++ b/src/proto_alpha/lib_sc_rollup/dune-project @@ -1,3 +1,2 @@ (lang dune 2.9) (formatting (enabled_for ocaml)) -(name tezos-client-alpha) diff --git a/src/proto_alpha/lib_sc_rollup/tezos-sc-rollup-alpha.opam b/src/proto_alpha/lib_sc_rollup/tezos-sc-rollup-alpha.opam index 00d5ef201a..206d8902e6 100644 --- a/src/proto_alpha/lib_sc_rollup/tezos-sc-rollup-alpha.opam +++ b/src/proto_alpha/lib_sc_rollup/tezos-sc-rollup-alpha.opam @@ -1,17 +1,18 @@ opam-version: "2.0" maintainer: "contact@tezos.com" -authors: [ "Tezos devteam" ] +authors: ["Tezos devteam"] homepage: "https://www.tezos.com/" bug-reports: "https://gitlab.com/tezos/tezos/issues" dev-repo: "git+https://gitlab.com/tezos/tezos.git" license: "MIT" depends: [ "dune" { >= "2.9" } + "ppx_inline_test" "tezos-base" - "tezos-rpc" + "tezos-protocol-alpha" "tezos-protocol-plugin-alpha" "tezos-protocol-alpha-parameters" - "tezos-protocol-alpha" + "tezos-rpc" ] build: [ ["dune" "build" "-p" name "-j" jobs] From 1b4db40b022ce46b3ba98dca9862c4d4275777fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Proust?= Date: Wed, 2 Mar 2022 14:57:56 +0100 Subject: [PATCH 007/100] Error_monad: document limitations of the error_encoding --- src/lib_error_monad/sig.ml | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/lib_error_monad/sig.ml b/src/lib_error_monad/sig.ml index 08a5979ae7..b3e041e656 100644 --- a/src/lib_error_monad/sig.ml +++ b/src/lib_error_monad/sig.ml @@ -49,6 +49,40 @@ module type CORE = sig val string_of_category : error_category -> string + (** The encoding for errors. + + Note that this encoding has a few peculiarities, some of which may impact + your code. These peculiarities are due to the type [error] being an + extensible variant. + + Because the [error] type is an extensible variant, you must register an + encoding for each error constructor you add to [error]. This is done via + {!register_error_kind}. + + Because the [error] type is an extensible variant, with dynamically + registered errors (see peculiarity above), there are no tags + associated with each error. This does not affect the JSON encoding, but it + does impose restrictions on the binary encoding. The chosen workaround is + to encode errors as JSON and to encode the JSON to binary form. As a + result, errors can be somewhat large in binary: they include field names + and such. + + Because the [error] type is an extensible variant, with dynamically + registered errors (see peculiarity above), the encoding must be recomputed + when a new error is registered. This is achieved by the means of a + {!Data_encoding.delayed} combinator: the encoding is recomputed on-demand. + There is a caching mechanism so that, in the case where no new errors have + been registered since the last use, the last result is used. + + This last peculiarity imposes a limit on the use of [error_encoding] + itself. Specifically, it is invalid to use [error_encoding] inside the + [~json] argument of a {!Data_encoding.splitted}. This is because + [splitted] evaluates the [delayed] combinator once-and-for-all to produce + a json encoding. (Note that the following + data-encoding combinators use [splitted] internally: + {!Data_encoding.Compact.make}, {!Data_encoding.assoc}, and + {!Data_encoding.lazy_encoding}. As a result, it is invalid to use + [error_encoding] within the arguments of these combinators as well.) *) val error_encoding : error Data_encoding.t val pp : Format.formatter -> error -> unit From 70e4e82c9b3c54d1d2b94c8e2fc85906cd7b4495 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Proust?= Date: Wed, 2 Mar 2022 16:01:00 +0100 Subject: [PATCH 008/100] Error_monad: add json+registration test --- manifest/main.ml | 4 +- src/lib_error_monad/test/dune | 9 +- .../test/test_splitted_error_encoding.ml | 98 +++++++++++++++++++ 3 files changed, 107 insertions(+), 4 deletions(-) create mode 100644 src/lib_error_monad/test/test_splitted_error_encoding.ml diff --git a/manifest/main.ml b/manifest/main.ml index b320b32f65..13c520ab47 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -625,8 +625,8 @@ let _tezos_hacl_tests_1 = ~js_compatible:true let _tezos_error_monad_tests = - test - "test_registration" + tests + ["test_registration"; "test_splitted_error_encoding"] ~path:"src/lib_error_monad/test" ~opam:"src/lib_error_monad/tezos-error-monad" ~modes:[Native; JS] diff --git a/src/lib_error_monad/test/dune b/src/lib_error_monad/test/dune index f64aba347c..db914524ba 100644 --- a/src/lib_error_monad/test/dune +++ b/src/lib_error_monad/test/dune @@ -1,8 +1,8 @@ ; This file was automatically generated, do not edit. ; Edit file manifest/main.ml instead. -(test - (name test_registration) +(tests + (names test_registration test_splitted_error_encoding) (package tezos-error-monad) (modes native js) (libraries @@ -16,3 +16,8 @@ (alias runtest_js) (package tezos-error-monad) (action (run node %{dep:./test_registration.bc.js}))) + +(rule + (alias runtest_js) + (package tezos-error-monad) + (action (run node %{dep:./test_splitted_error_encoding.bc.js}))) diff --git a/src/lib_error_monad/test/test_splitted_error_encoding.ml b/src/lib_error_monad/test/test_splitted_error_encoding.ml new file mode 100644 index 0000000000..f9ff46314f --- /dev/null +++ b/src/lib_error_monad/test/test_splitted_error_encoding.ml @@ -0,0 +1,98 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Error Monad + Invocation: dune build @src/lib_error_monad/runtest + Subject: On the wrapping of error_encoding in a splitted. +*) + +open TzCore + +let splitted_error_encoding = + Data_encoding.splitted ~json:error_encoding ~binary:error_encoding + +type error += Foo + +let msg error = Obj.Extension_constructor.(name @@ of_val error) + +let test_unregistered_binary () = + let e = Foo in + let blob = Data_encoding.Binary.to_string_exn error_encoding e in + let ee = Data_encoding.Binary.of_string_exn error_encoding blob in + (match ee with Unregistered_error _ -> () | _ -> assert false) ; + let sblob = Data_encoding.Binary.to_string_exn splitted_error_encoding e in + let see = Data_encoding.Binary.of_string_exn error_encoding sblob in + (match see with Unregistered_error _ -> () | _ -> assert false) ; + () + +let test_unregistered_json () = + let e = Foo in + let json = Data_encoding.Json.construct error_encoding e in + let ee = Data_encoding.Json.destruct error_encoding json in + (match ee with Unregistered_error _ -> () | _ -> assert false) ; + let sjson = Data_encoding.Json.construct splitted_error_encoding e in + let see = Data_encoding.Json.destruct error_encoding sjson in + (match see with Unregistered_error _ -> () | _ -> assert false) ; + () + +let test_registered () = + register_error_kind + `Permanent + ~id:"test.Foo" + ~title:"test-foo" + ~description:"Test Foo" + Data_encoding.(obj1 (req "test-foo" Data_encoding.unit)) + (function Foo -> Some () | _ -> None) + (fun () -> Foo) ; + let e = Foo in + let blob = Data_encoding.Binary.to_string_exn error_encoding e in + let ee = Data_encoding.Binary.of_string_exn error_encoding blob in + assert (ee = Foo) ; + let see = Data_encoding.Binary.of_string_exn splitted_error_encoding blob in + assert (see = Foo) ; + let sblob = Data_encoding.Binary.to_string_exn splitted_error_encoding e in + let ssee = Data_encoding.Binary.of_string_exn error_encoding sblob in + assert (ssee = Foo) ; + (* and now JSON *) + let json = Data_encoding.Json.construct error_encoding e in + let ee = Data_encoding.Json.destruct error_encoding json in + assert (ee = Foo) ; + let sjson = Data_encoding.Json.construct splitted_error_encoding e in + let see = Data_encoding.Json.destruct error_encoding sjson in + (match see with Unregistered_error _ -> () | _ -> assert false) ; + let ssee = Data_encoding.Json.destruct splitted_error_encoding json in + (match ssee with Unregistered_error _ -> () | _ -> assert false) ; + () + +let tests = + [ + Alcotest.test_case "unregistered(binary)" `Quick test_unregistered_binary; + Alcotest.test_case "unregistered(json)" `Quick test_unregistered_json; + Alcotest.test_case "registered" `Quick test_registered; + ] + +let () = Alcotest.run "splitted" [("splitted", tests)] From 29083eacd1773c49e28ab93455c42bb381c8f338 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Proust?= Date: Thu, 3 Mar 2022 11:51:53 +0100 Subject: [PATCH 009/100] Error_monad: introduce hack to clear json-encoding cache of error_encoding --- src/lib_error_monad/core_maker.ml | 41 +++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/lib_error_monad/core_maker.ml b/src/lib_error_monad/core_maker.ml index f129d160b8..d85e0290d6 100644 --- a/src/lib_error_monad/core_maker.ml +++ b/src/lib_error_monad/core_maker.ml @@ -418,6 +418,47 @@ end = struct let error_encoding = Data_encoding.delayed error_encoding + let () = + (* HACK + There is an issue with the interaction of + (a) error-monad's delayed error-encoding + (b) data-encoding's cached json-encoding conversion + + More specifically. + + On the error-monad side: The [error_encoding] is a + [Data_encoding.delayed] encoding. The delaying allows to dynamically find + the list of registered errors and generate the encoding based on that. + (There is a cache mechanism to avoid recomputing it if no new errors have + been registered. That is the original purpose of the + [set_error_encoding_cache_dirty].) + + On the data-encoding side: Each encoding is actually a record with the + [data-encoding] AST in one field and the [json-data-encoding] in the + other. The fields are used for serialisation/deserialisation in, + respectively, binary and in JSON. The JSON field is computed on-demand + (e.g., when `Data_encoding.Json.construct` is called). To avoid + expensive recomputations, the result of this conversion is stored in the + [json-data-encoding]. + + The end result is that, whilst the cache-invalidation mechanism can mark + the encoding {e inside} the [delayed] node dirty so it is recomputed on + each use, it cannot mark the json-encoding cache of the [delayed] node + itself dirty. + + As a result, the json encoding for errors is set in stone as soon as it + is used, even if new errors are registered. + + To circumvent this, we use the hack below: We explicitly tamper with the + internal representation of the encoding. More specifically, we reset the + json-encoding field of [error_encoding] to [None] to force it being + recomputed. *) + let set_older_caches_dirty = !set_error_encoding_cache_dirty in + set_error_encoding_cache_dirty := + fun () -> + set_older_caches_dirty () ; + error_encoding.Data_encoding__Encoding.json_encoding <- None + let json_of_error error = Data_encoding.Json.construct error_encoding error let error_of_json json = Data_encoding.Json.destruct error_encoding json From e604173ae7a6a63e0a0ed5e72600e7f4f507f79b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Proust?= Date: Mon, 14 Mar 2022 11:21:12 +0100 Subject: [PATCH 010/100] Error_monad: add documentation to JSON-hack test --- .../test/test_splitted_error_encoding.ml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/lib_error_monad/test/test_splitted_error_encoding.ml b/src/lib_error_monad/test/test_splitted_error_encoding.ml index f9ff46314f..d32505c59b 100644 --- a/src/lib_error_monad/test/test_splitted_error_encoding.ml +++ b/src/lib_error_monad/test/test_splitted_error_encoding.ml @@ -33,6 +33,9 @@ open TzCore let splitted_error_encoding = + (* As documented in [Sig.Core.error_encoding], this use of [error_encoding] + suffers from significant drawbacks. Specifically, The json-encoding via + [splitted] is not updated when new errors are registered. *) Data_encoding.splitted ~json:error_encoding ~binary:error_encoding type error += Foo @@ -40,6 +43,8 @@ type error += Foo let msg error = Obj.Extension_constructor.(name @@ of_val error) let test_unregistered_binary () = + (* The error was declared but not registered so we expect all encoding + attempts to fail. *) let e = Foo in let blob = Data_encoding.Binary.to_string_exn error_encoding e in let ee = Data_encoding.Binary.of_string_exn error_encoding blob in @@ -50,6 +55,8 @@ let test_unregistered_binary () = () let test_unregistered_json () = + (* The error was declared but not registered so we expect all encoding + attempts to fail. *) let e = Foo in let json = Data_encoding.Json.construct error_encoding e in let ee = Data_encoding.Json.destruct error_encoding json in @@ -60,6 +67,7 @@ let test_unregistered_json () = () let test_registered () = + (* We register the error. *) register_error_kind `Permanent ~id:"test.Foo" @@ -68,6 +76,7 @@ let test_registered () = Data_encoding.(obj1 (req "test-foo" Data_encoding.unit)) (function Foo -> Some () | _ -> None) (fun () -> Foo) ; + (* We check that binary encoding works fine. *) let e = Foo in let blob = Data_encoding.Binary.to_string_exn error_encoding e in let ee = Data_encoding.Binary.of_string_exn error_encoding blob in @@ -81,6 +90,8 @@ let test_registered () = let json = Data_encoding.Json.construct error_encoding e in let ee = Data_encoding.Json.destruct error_encoding json in assert (ee = Foo) ; + (* and now JSON with splitted. This fail as per the documentation of + [error_encoding] (see [sig.ml]). *) let sjson = Data_encoding.Json.construct splitted_error_encoding e in let see = Data_encoding.Json.destruct error_encoding sjson in (match see with Unregistered_error _ -> () | _ -> assert false) ; From f7f23db50dc88600529ea218eec501a80b6c0306 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Kr=C3=BCger?= Date: Wed, 9 Mar 2022 15:35:04 +0000 Subject: [PATCH 011/100] Proto: Use inbox level to speed up conflict point detection (#2454) --- .../lib_protocol/sc_rollup_storage.ml | 141 +++++++++++------- 1 file changed, 84 insertions(+), 57 deletions(-) diff --git a/src/proto_alpha/lib_protocol/sc_rollup_storage.ml b/src/proto_alpha/lib_protocol/sc_rollup_storage.ml index 9571d91a97..69bd206f60 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_storage.ml +++ b/src/proto_alpha/lib_protocol/sc_rollup_storage.ml @@ -416,7 +416,9 @@ let withdraw_stake ctxt rollup staker = tested for. *) let sc_rollup_max_lookahead = 30_000l -let sc_rollup_commitment_frequency = 20 +let sc_rollup_commitment_frequency = + (* Think twice before changing this. And then avoid doing it. *) + 20 (* 76 for Commitments entry + 4 for Commitment_stake_count entry + 4 for Commitment_added entry *) let sc_rollup_commitment_storage_size_in_bytes = 84 @@ -438,7 +440,10 @@ let assert_commitment_not_too_far_ahead ctxt rollup lcc commitment = then fail Sc_rollup_too_far_ahead else return ctxt -let assert_commitment_frequency ctxt rollup commitment check = +(** Enfore that a commitment's inbox level increases by an exact fixed amount over its predecessor. + This property is used in several places - not obeying it causes severe breakage. +*) +let assert_commitment_frequency ctxt rollup commitment = let open Lwt_tzresult_syntax in let pred = Commitment.(commitment.predecessor) in let* (ctxt, pred_level) = @@ -451,24 +456,6 @@ let assert_commitment_frequency ctxt rollup commitment check = in return (ctxt, Commitment.(pred.inbox_level)) in - if - Raw_level_repr.( - check - commitment.inbox_level - (add pred_level sc_rollup_commitment_frequency)) - then return ctxt - else fail Sc_rollup_bad_inbox_level - -(** Check invariants on [inbox_level], enforcing overallocation of storage and - regularity of block prorudction. - - The constants used by [assert_refine_conditions_met] must be chosen such - that the maximum cost of storage allocated by each staker at most the size - of their deposit. - *) -let assert_refine_conditions_met ctxt rollup lcc commitment = - let open Lwt_tzresult_syntax in - let* ctxt = assert_commitment_not_too_far_ahead ctxt rollup lcc commitment in (* We want to check the following inequalities on [commitment.inbox_level], [commitment.predecessor.inbox_level] and the constant [sc_rollup_commitment_frequency]. @@ -486,8 +473,23 @@ let assert_refine_conditions_met ctxt rollup lcc commitment = Because [a >= b && a = b] is equivalent to [a = b], we can the latter as an optimization. *) - let check = Raw_level_repr.( = ) in - assert_commitment_frequency ctxt rollup commitment check + if + Raw_level_repr.( + commitment.inbox_level = add pred_level sc_rollup_commitment_frequency) + then return ctxt + else fail Sc_rollup_bad_inbox_level + +(** Check invariants on [inbox_level], enforcing overallocation of storage and + regularity of block prorudction. + + The constants used by [assert_refine_conditions_met] must be chosen such + that the maximum cost of storage allocated by each staker at most the size + of their deposit. + *) +let assert_refine_conditions_met ctxt rollup lcc commitment = + let open Lwt_tzresult_syntax in + let* ctxt = assert_commitment_not_too_far_ahead ctxt rollup lcc commitment in + assert_commitment_frequency ctxt rollup commitment let refine_stake ctxt rollup staker commitment = let open Lwt_tzresult_syntax in @@ -594,47 +596,72 @@ let cement_commitment ctxt rollup new_lcc = in return ctxt -module Successor_map = Commitment_hash.Map - type conflict_point = Commitment_hash.t * Commitment_hash.t +(** [goto_inbox_level ctxt rollup inbox_level commit] Follows the predecessors of [commit] until it + arrives at the exact [inbox_level]. The result is the commit hash at the given inbox level. *) +let goto_inbox_level ctxt rollup inbox_level commit = + let open Lwt_tzresult_syntax in + let rec go ctxt commit = + let* (info, ctxt) = get_commitment ctxt rollup commit in + if Raw_level_repr.(info.Commitment.inbox_level <= inbox_level) then ( + (* Assert that we're exactly at that level. If this isn't the case, we're most likely in a + situation where inbox levels are inconsistent. *) + assert (Raw_level_repr.(info.inbox_level = inbox_level)) ; + return (commit, ctxt)) + else (go [@ocaml.tailcall]) ctxt info.predecessor + in + go ctxt commit + let get_conflict_point ctxt rollup staker1 staker2 = let open Lwt_tzresult_syntax in - let* (lcc, ctxt) = last_cemented_commitment ctxt rollup in - let* (staker1_branch, ctxt) = find_staker ctxt rollup staker1 in - let* (staker2_branch, ctxt) = find_staker ctxt rollup staker2 in - (* Build a map from commitments on the staker1 branch to their direct - successor on this branch. *) - let* (staker1_succ_map, ctxt) = - let rec go node prev_map ctxt = - if Commitment_hash.(node = lcc) then return (prev_map, ctxt) - else - let* (pred, ctxt) = get_predecessor ctxt rollup node in - let new_map = Successor_map.add pred node prev_map in - (go [@ocaml.tailcall]) pred new_map ctxt - in - go staker1_branch Successor_map.empty ctxt + (* Find out on which commitments the competitors are staked. *) + let* (commit1, ctxt) = find_staker ctxt rollup staker1 in + let* (commit2, ctxt) = find_staker ctxt rollup staker2 in + let* (commit1_info, ctxt) = get_commitment ctxt rollup commit1 in + let* (commit2_info, ctxt) = get_commitment ctxt rollup commit2 in + (* Make sure that both commits are at the same inbox level. In case they are not move the commit + that is farther ahead to the exact inbox level of the other. + + We do this instead of an alternating traversal of either commit to ensure the we can detect + wonky inbox level increases. For example, if the inbox levels decrease in different intervals + between commits for either history, we risk going past the conflict point and accidentally + determined that the commits are not in conflict by joining at the same commit. *) + let target_inbox_level = + Raw_level_repr.min commit1_info.inbox_level commit2_info.inbox_level in - (* Traverse from staker2 towards LCC. *) - if Successor_map.mem staker2_branch staker1_succ_map then - (* The staker1 branch contains the tip of the staker2 branch. - Commitments are perfect agreement, or in partial agreement with staker1 - ahead. *) - fail Sc_rollup_no_conflict - else - let rec go node ctxt = - if Commitment_hash.(node = staker1_branch) then - (* The staker2 branch contains the tip of the staker1 branch. - The commitments are in partial agreement with staker2 ahead. *) - fail Sc_rollup_no_conflict + let* (commit1, ctxt) = + goto_inbox_level ctxt rollup target_inbox_level commit1 + in + let* (commit2, ctxt) = + goto_inbox_level ctxt rollup target_inbox_level commit2 + in + (* The inbox level of a commitment increases by a fixed amount over the preceding commitment. + We use this fact in the following to efficiently traverse both commitment histories towards + the conflict points. *) + let rec traverse_in_parallel ctxt commit1 commit2 = + if Commitment_hash.(commit1 = commit2) then + (* This case will most dominantly happen when either commit is part of the other's history. + It occurs when the commit that is farther ahead gets dereferenced to its predecessor often + enough to land at the other commit. *) + fail Sc_rollup_no_conflict + else + let* (commit1_info, ctxt) = get_commitment ctxt rollup commit1 in + let* (commit2_info, ctxt) = get_commitment ctxt rollup commit2 in + assert ( + Raw_level_repr.(commit1_info.inbox_level = commit2_info.inbox_level)) ; + if Commitment_hash.(commit1_info.predecessor = commit2_info.predecessor) + then + (* Same predecessor means we've found the conflict points. *) + return ((commit1, commit2), ctxt) else - let right = node in - let* (pred, ctxt) = get_predecessor ctxt rollup node in - match Successor_map.find pred staker1_succ_map with - | None -> (go [@ocaml.tailcall]) pred ctxt - | Some left -> return ((left, right), ctxt) - in - go staker2_branch ctxt + (* Different predecessors means they run in parallel. *) + (traverse_in_parallel [@ocaml.tailcall]) + ctxt + commit1_info.predecessor + commit2_info.predecessor + in + traverse_in_parallel ctxt commit1 commit2 let remove_staker ctxt rollup staker = let open Lwt_tzresult_syntax in From 861584dcb221de55d9f679e06f3f778a4131de3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Kr=C3=BCger?= Date: Tue, 15 Mar 2022 17:44:07 +0000 Subject: [PATCH 012/100] Proto: Make SCORU conflict detection fail early --- .../lib_protocol/sc_rollup_storage.ml | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/proto_alpha/lib_protocol/sc_rollup_storage.ml b/src/proto_alpha/lib_protocol/sc_rollup_storage.ml index 69bd206f60..047625eb9c 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_storage.ml +++ b/src/proto_alpha/lib_protocol/sc_rollup_storage.ml @@ -603,7 +603,7 @@ type conflict_point = Commitment_hash.t * Commitment_hash.t let goto_inbox_level ctxt rollup inbox_level commit = let open Lwt_tzresult_syntax in let rec go ctxt commit = - let* (info, ctxt) = get_commitment ctxt rollup commit in + let* (info, ctxt) = get_commitment_internal ctxt rollup commit in if Raw_level_repr.(info.Commitment.inbox_level <= inbox_level) then ( (* Assert that we're exactly at that level. If this isn't the case, we're most likely in a situation where inbox levels are inconsistent. *) @@ -615,11 +615,23 @@ let goto_inbox_level ctxt rollup inbox_level commit = let get_conflict_point ctxt rollup staker1 staker2 = let open Lwt_tzresult_syntax in + (* Ensure the LCC is set. *) + let* (lcc, ctxt) = last_cemented_commitment ctxt rollup in (* Find out on which commitments the competitors are staked. *) let* (commit1, ctxt) = find_staker ctxt rollup staker1 in let* (commit2, ctxt) = find_staker ctxt rollup staker2 in - let* (commit1_info, ctxt) = get_commitment ctxt rollup commit1 in - let* (commit2_info, ctxt) = get_commitment ctxt rollup commit2 in + let* () = + fail_when + Commitment_hash.( + (* If PVM is in pre-boot state, there might be stakes on the zero commitment. *) + commit1 = zero || commit2 = zero + (* If either commit is the LCC, that also means there can't be a conflict. *) + || commit1 = lcc + || commit2 = lcc) + Sc_rollup_no_conflict + in + let* (commit1_info, ctxt) = get_commitment_internal ctxt rollup commit1 in + let* (commit2_info, ctxt) = get_commitment_internal ctxt rollup commit2 in (* Make sure that both commits are at the same inbox level. In case they are not move the commit that is farther ahead to the exact inbox level of the other. @@ -646,8 +658,8 @@ let get_conflict_point ctxt rollup staker1 staker2 = enough to land at the other commit. *) fail Sc_rollup_no_conflict else - let* (commit1_info, ctxt) = get_commitment ctxt rollup commit1 in - let* (commit2_info, ctxt) = get_commitment ctxt rollup commit2 in + let* (commit1_info, ctxt) = get_commitment_internal ctxt rollup commit1 in + let* (commit2_info, ctxt) = get_commitment_internal ctxt rollup commit2 in assert ( Raw_level_repr.(commit1_info.inbox_level = commit2_info.inbox_level)) ; if Commitment_hash.(commit1_info.predecessor = commit2_info.predecessor) From d78a9968a3e8c931723902499d0a085e452510a0 Mon Sep 17 00:00:00 2001 From: Pietro Date: Wed, 9 Mar 2022 11:02:32 +0100 Subject: [PATCH 013/100] node: add new command 'dump-metrics' --- src/bin_node/main.ml | 61 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/src/bin_node/main.ml b/src/bin_node/main.ml index 8a94ae11a8..2f9679759f 100644 --- a/src/bin_node/main.ml +++ b/src/bin_node/main.ml @@ -101,6 +101,66 @@ let info = let version = Tezos_version.Bin_version.version_string in Cmdliner.Term.info ~doc:"The Tezos node" ~man ~version "tezos-node" +module Node_metrics_command = struct + let dump_metrics () = + let open Prometheus in + let metric_type_to_string = function + | Counter -> "Counter" + | Gauge -> "Gauge" + | Summary -> "Summary" + | Histogram -> "Histogram" + in + let pp_label_names fmt = + Format.pp_print_list + ~pp_sep:(fun fmt () -> Format.fprintf fmt ";") + (fun fmt v -> Format.fprintf fmt "%a" LabelName.pp v) + fmt + in + Format.printf "name,metric_type,help,label_names\n" ; + List.iter + (fun (v, _) -> + Format.printf + "%a,%s,%s,%a\n" + MetricName.pp + v.MetricInfo.name + (metric_type_to_string v.MetricInfo.metric_type) + v.MetricInfo.help + pp_label_names + v.MetricInfo.label_names) + (Prometheus.MetricFamilyMap.to_list + Prometheus.CollectorRegistry.(collect default)) + + module Term = struct + let process _ = `Ok (dump_metrics ()) + + let docs = "METRICS OPTIONS" + + let dump_metrics = + let doc = "Show available openmetrics in csv format." in + Cmdliner.Arg.(value & flag & info ~docs ~doc ["dump-metrics"]) + + let term = Cmdliner.Term.(ret (const process $ dump_metrics)) + end + + module Manpage = struct + let command_description = + "The $(b,dump-metrics) command is meant to dump openmetrics that are \ + collected by the Tezos node on console." + + let description = [`S "DESCRIPTION"; `P command_description] + + let man = description + + let info = + Cmdliner.Term.info + ~doc:"Show all the openmetrics collected by the Tezos node" + ~man + "dump-metrics" + end + + let cmd = (Term.term, Manpage.info) +end + let commands = [ Node_run_command.cmd; @@ -111,6 +171,7 @@ let commands = Node_snapshot_command.cmd; Node_reconstruct_command.cmd; Node_storage_command.cmd; + Node_metrics_command.cmd; ] (* This call is not strictly necessary as the parameters are initialized From c054b41f0807b60afb9c225943b92e8c6b3be580 Mon Sep 17 00:00:00 2001 From: Pietro Date: Wed, 9 Mar 2022 11:49:48 +0100 Subject: [PATCH 014/100] doc: add doc for openmetrics --- docs/Makefile | 8 +++-- docs/developer/openmetrics.rst | 64 ++++++++++++++++++++++++++++++++++ docs/index.rst | 1 + src/bin_node/main.ml | 7 ++-- 4 files changed, 75 insertions(+), 5 deletions(-) create mode 100644 docs/developer/openmetrics.rst diff --git a/docs/Makefile b/docs/Makefile index 4b34b8ed93..4308abfbe3 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -98,6 +98,10 @@ api/errors.rst: $(DOCERRORDIR)/error_doc.ml @cd .. && dune build docs/$(DOCERRORDIR)/error_doc.exe ../_build/default/docs/$(DOCERRORDIR)/error_doc.exe > api/errors.rst +developer/metrics.csv: + make -C ../ tezos-node + ../tezos-node dump-metrics > developer/metrics.csv + $(DOCGENDIR)/rpc_doc.exe: @cd .. && dune build docs/$(DOCGENDIR)/rpc_doc.exe @@ -122,7 +126,7 @@ install-dependencies: # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -html: Makefile api/errors.rst rpc p2p install-dependencies +html: Makefile api/errors.rst developer/metrics.csv rpc p2p install-dependencies (echo ':orphan:'; echo ''; cat ../CHANGES.rst) > CHANGES-dev.rst @$(SPHINXBUILD) -b html "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) @ln -s active "$(BUILDDIR)/hangzhou" || true @@ -168,5 +172,5 @@ lint: pylint pycodestyle lint_black clean: @-rm -Rf "$(BUILDDIR)" - @-rm -Rf api/errors.rst active/rpc.rst hangzhou/rpc.rst ithaca/rpc.rst alpha/rpc.rst shell/rpc.rst shell/p2p_api.rst user/default-acl.json CHANGES-dev.rst + @-rm -Rf api/errors.rst developer/metrics.csv active/rpc.rst hangzhou/rpc.rst ithaca/rpc.rst alpha/rpc.rst shell/rpc.rst shell/p2p_api.rst user/default-acl.json CHANGES-dev.rst @-rm -Rf api/tezos-*.html api/tezos-*.txt active/tezos-*.html hangzhou/tezos-*.html ithaca/tezos-*.html alpha/tezos-*.html diff --git a/docs/developer/openmetrics.rst b/docs/developer/openmetrics.rst new file mode 100644 index 0000000000..4e925681e8 --- /dev/null +++ b/docs/developer/openmetrics.rst @@ -0,0 +1,64 @@ + +Octez Metrics +============= + +The Octez node is able to produce metrics information and serve them in the +`Open Metrics +`_ format, an emerging standard for exposing metrics data, especially used in cloud-based systems. + +Supported Open Metrics +---------------------- + +The Octez node supports the following metrics, characterized by: the name of +the metric, the type of the metric as in the `open metrics specification +`__, a user friendly description on the metric and a +list of labels (that can be used to aggregate or query metrics). + +For more information check the openmetrics specification: https://openmetrics.io/ + +.. csv-table:: + :file: metrics.csv + :header-rows: 1 + :widths: 20, 20, 20, 10 + + +Usage +----- + +To instruct the Octez node to produce metrics, the user needs to pass the option +``--listen-prometheus=``. The port specified on the command line is the port +where the integrated open metrics server will be available. + +Ex.:: + + tezos-node run --listen-prometheus=9091 + +To query the open metrics server the user can simply query the node. + +Ex.:: + + curl http://:9091/metrics + +Collecting metrics +------------------ + +Different third-party tools can be used to query the Octez node and collect +metrics from it. Let us illustrates this with the example of a `Prometheus +server `_. + +Update the Prometheus configuration file (typically, ``prometheus.yml``) +to add a "scrape job" - that is how Prometheus is made aware of a new data +source - using adequate values: + +- job_name: Use a unique name among other scrape jobs. All metrics collected + through this job will have automatically a ‘job’ label with this value added + to it +- targets: The URL of Octez node. + +:: + + - job_name: 'tezos-metrics' + scheme: http + static_configs: + - targets: ['localhost:9091'] + diff --git a/docs/index.rst b/docs/index.rst index 68d505163a..fa201dc590 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -206,6 +206,7 @@ in the :ref:`introduction `. developer/guidelines developer/repository_scope developer/time_measurement_ppx + developer/openmetrics README .. toctree:: diff --git a/src/bin_node/main.ml b/src/bin_node/main.ml index 2f9679759f..f150d54f15 100644 --- a/src/bin_node/main.ml +++ b/src/bin_node/main.ml @@ -116,11 +116,11 @@ module Node_metrics_command = struct (fun fmt v -> Format.fprintf fmt "%a" LabelName.pp v) fmt in - Format.printf "name,metric_type,help,label_names\n" ; + Format.printf "@[Name,Type,Description,Labels" ; List.iter (fun (v, _) -> Format.printf - "%a,%s,%s,%a\n" + "@,@[%a@],%s,\"%s\",%a" MetricName.pp v.MetricInfo.name (metric_type_to_string v.MetricInfo.metric_type) @@ -128,7 +128,8 @@ module Node_metrics_command = struct pp_label_names v.MetricInfo.label_names) (Prometheus.MetricFamilyMap.to_list - Prometheus.CollectorRegistry.(collect default)) + Prometheus.CollectorRegistry.(collect default)) ; + Format.printf "@]@." module Term = struct let process _ = `Ok (dump_metrics ()) From 7f37ed750fd7a7303ef4ee13fc82b2d270b6e87b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Proust?= Date: Mon, 14 Mar 2022 14:25:11 +0100 Subject: [PATCH 015/100] Everywhere: use the `let*` of QCheck Gens rather than the infix binds --- src/lib_context/test/test_merkle_proof.ml | 60 +++++++++++-------- .../test/test_cache.ml | 29 ++++----- .../test/test_proxy_server_config.ml | 26 ++++---- src/lib_shell/test/generators.ml | 8 ++- src/lib_shell/test/generators_tree.ml | 12 ++-- .../test/test_prevalidator_classification.ml | 2 +- ..._prevalidator_classification_operations.ml | 22 ++++--- .../test-unix/test_circular_buffer_fuzzy.ml | 18 +++--- 8 files changed, 100 insertions(+), 77 deletions(-) diff --git a/src/lib_context/test/test_merkle_proof.ml b/src/lib_context/test/test_merkle_proof.ml index 5542e035bc..b434ab59e2 100644 --- a/src/lib_context/test/test_merkle_proof.ml +++ b/src/lib_context/test/test_merkle_proof.ml @@ -62,9 +62,10 @@ module Proof32 (Encoding : Tezos_context_sigs.Context.PROOF_ENCODING) = struct let inode width gen_a = let* length = int_range 1 1000_000 in + let* n = int_bound (min 32 (max 5 width) - 1) in + let n = n + 1 in + let* indices = comb n (Stdlib.List.init 32 (fun x -> x)) in let+ proofs = - let* n = int_bound (min 32 (max 5 width) - 1) >|= ( + ) 1 in - let* indices = comb n (Stdlib.List.init 32 (fun x -> x)) in flatten_l @@ List.map (fun i -> @@ -76,7 +77,7 @@ module Proof32 (Encoding : Tezos_context_sigs.Context.PROOF_ENCODING) = struct let inode_extender gen_a = let* length = int_range 1 10 in - let* segment = list_size (int_bound 5 >|= ( + ) 1) (int_bound 4) in + let* segment = list_size (map succ (int_bound 5)) (int_bound 4) in let+ proof = gen_a in {length; segment; proof} @@ -85,14 +86,15 @@ module Proof32 (Encoding : Tezos_context_sigs.Context.PROOF_ENCODING) = struct let+ hash = hash in Blinded_inode hash else - int_bound 3 >>= function + let* i = int_bound 3 in + match i with | 0 -> let+ hash = hash in Blinded_inode hash | 1 -> let+ xs = list_size - (int_bound 3 >|= ( + ) 1) + (map succ (int_bound 3)) (pair step (tree (depth - 1, width))) in Inode_values xs @@ -106,7 +108,8 @@ module Proof32 (Encoding : Tezos_context_sigs.Context.PROOF_ENCODING) = struct and tree (depth, width) : tree t = if depth <= 0 then - int_bound 2 >>= function + let* i = int_bound 2 in + match i with | 0 -> let+ v = value in (Value v : tree) @@ -118,7 +121,8 @@ module Proof32 (Encoding : Tezos_context_sigs.Context.PROOF_ENCODING) = struct Blinded_node h | _ -> assert false else - int_bound 5 >>= function + let* i = int_bound 5 in + match i with | 0 -> let+ v = value in (Value v : tree) @@ -127,7 +131,7 @@ module Proof32 (Encoding : Tezos_context_sigs.Context.PROOF_ENCODING) = struct Blinded_value h | 2 -> let+ xs = - list_size (int_bound 4 >|= ( + ) 1) + list_size (map succ (int_bound 4)) @@ pair step (tree (depth - 1, width)) in (Node xs : tree) @@ -144,7 +148,8 @@ module Proof32 (Encoding : Tezos_context_sigs.Context.PROOF_ENCODING) = struct let kinded_hash = let* h = hash in - bool >|= function true -> `Value h | false -> `Node h + let+ b = bool in + match b with true -> `Value h | false -> `Node h let tree_proof = let* version = int_bound 3 in @@ -157,13 +162,14 @@ module Proof32 (Encoding : Tezos_context_sigs.Context.PROOF_ENCODING) = struct open Stream let elt = - int_bound 3 >>= function + let* i = int_bound 3 in + match i with | 0 -> let+ v = value in Value v | 1 -> let+ sks = - list_size (int_bound 4 >|= ( + ) 1) @@ pair step kinded_hash + list_size (map succ (int_bound 4)) @@ pair step kinded_hash in Node sks | 2 -> @@ -176,7 +182,7 @@ module Proof32 (Encoding : Tezos_context_sigs.Context.PROOF_ENCODING) = struct | _ -> assert false let t : Stream.t Gen.t = - let+ xs = list_size (int_bound 10 >|= ( + ) 1) elt in + let+ xs = list_size (map succ (int_bound 10)) elt in List.to_seq xs end @@ -288,9 +294,10 @@ module Proof2 (Encoding : Tezos_context_sigs.Context.PROOF_ENCODING) = struct let inode _width gen_a = let* length = int_range 1 1000_000 in + let* n = int_bound 1 in + let n = n + 1 in + let* indices = comb n [0; 1] in let+ proofs = - let* n = int_bound 1 >|= ( + ) 1 in - let* indices = comb n [0; 1] in flatten_l @@ List.map (fun i -> @@ -302,7 +309,7 @@ module Proof2 (Encoding : Tezos_context_sigs.Context.PROOF_ENCODING) = struct let inode_extender gen_a = let* length = int_range 1 10 in - let* segment = list_size (int_bound 5 >|= ( + ) 1) (int_bound 1) in + let* segment = list_size (map succ (int_bound 5)) (int_bound 1) in let+ proof = gen_a in {length; segment; proof} @@ -311,14 +318,15 @@ module Proof2 (Encoding : Tezos_context_sigs.Context.PROOF_ENCODING) = struct let+ hash = hash in Blinded_inode hash else - int_bound 3 >>= function + let* i = int_bound 3 in + match i with | 0 -> let+ hash = hash in Blinded_inode hash | 1 -> let+ xs = list_size - (int_bound 3 >|= ( + ) 1) + (map succ (int_bound 3)) (pair step (tree (depth - 1, width))) in Inode_values xs @@ -332,7 +340,8 @@ module Proof2 (Encoding : Tezos_context_sigs.Context.PROOF_ENCODING) = struct and tree (depth, width) : tree t = if depth <= 0 then - int_bound 2 >>= function + let* i = int_bound 2 in + match i with | 0 -> let+ v = value in (Value v : tree) @@ -344,7 +353,8 @@ module Proof2 (Encoding : Tezos_context_sigs.Context.PROOF_ENCODING) = struct Blinded_node h | _ -> assert false else - int_bound 5 >>= function + let* i = int_bound 5 in + match i with | 0 -> let+ v = value in (Value v : tree) @@ -353,7 +363,7 @@ module Proof2 (Encoding : Tezos_context_sigs.Context.PROOF_ENCODING) = struct Blinded_value h | 2 -> let+ xs = - list_size (int_bound 4 >|= ( + ) 1) + list_size (map succ (int_bound 4)) @@ pair step (tree (depth - 1, width)) in (Node xs : tree) @@ -370,7 +380,8 @@ module Proof2 (Encoding : Tezos_context_sigs.Context.PROOF_ENCODING) = struct let kinded_hash = let* h = hash in - bool >|= function true -> `Value h | false -> `Node h + let+ b = bool in + match b with true -> `Value h | false -> `Node h let tree_proof = let* version = int_bound 3 in @@ -383,13 +394,14 @@ module Proof2 (Encoding : Tezos_context_sigs.Context.PROOF_ENCODING) = struct open Stream let elt = - int_bound 3 >>= function + let* i = int_bound 3 in + match i with | 0 -> let+ v = value in Value v | 1 -> let+ sks = - list_size (int_bound 4 >|= ( + ) 1) @@ pair step kinded_hash + list_size (map succ (int_bound 4)) @@ pair step kinded_hash in Node sks | 2 -> @@ -402,7 +414,7 @@ module Proof2 (Encoding : Tezos_context_sigs.Context.PROOF_ENCODING) = struct | _ -> assert false let t : Stream.t Gen.t = - let+ xs = list_size (int_bound 10 >|= ( + ) 1) elt in + let+ xs = list_size (map succ (int_bound 10)) elt in List.to_seq xs end diff --git a/src/lib_protocol_environment/test/test_cache.ml b/src/lib_protocol_environment/test/test_cache.ml index 5ab56797ad..a798c66aea 100644 --- a/src/lib_protocol_environment/test/test_cache.ml +++ b/src/lib_protocol_environment/test/test_cache.ml @@ -81,10 +81,11 @@ let number_of_keys cache = let gen_entries ?(high_init_entries = high_init_entries) ncaches = QCheck.Gen.( - list_size - (int_range low_init_entries high_init_entries) - (pair (int_bound (ncaches - 1)) (pair string_printable small_int)) - >>= fun entries -> + let* entries = + list_size + (int_range low_init_entries high_init_entries) + (pair (int_bound (ncaches - 1)) (pair string_printable small_int)) + in List.sort_uniq (fun (n1, (k1, _)) (n2, (k2, _)) -> let c = compare n1 n2 in @@ -104,13 +105,13 @@ let insert_entries cache entries = let gen_cache ?(high_init_entries = high_init_entries) () = QCheck.( Gen.( - int_range 1 3 >>= fun ncaches -> + let* ncaches = int_range 1 3 in let layout = generate ~n:ncaches (int_range low_size high_size) in let cache = from_layout layout in - int_range 0 100 >>= fun k -> + let* k = int_range 0 100 in if k = 0 then return (layout, [], cache) else - gen_entries ~high_init_entries ncaches >>= fun entries -> + let* entries = gen_entries ~high_init_entries ncaches in let cache = insert_entries cache entries in return (layout, entries, cache))) @@ -200,11 +201,11 @@ let check_from_layout_with_negative_size = ~name:"from_layout fails on negative sizes" QCheck.Gen.( QCheck.make - ( int_range 1 10 >>= fun n -> - list_repeat n small_int >>= fun layout -> - int_range 0 (List.length layout - 1) >>= fun idx -> - int_range (-100) (-1) >>= fun neg_size -> - return (layout, idx, neg_size) )) + (let* n = int_range 1 10 in + let* layout = list_repeat n small_int in + let* idx = int_range 0 (List.length layout - 1) in + let* neg_size = int_range (-100) (-1) in + return (layout, idx, neg_size))) (fun (layout, idx, neg_size) -> let layout = List.mapi (fun i x -> if i = idx then neg_size else x) layout @@ -531,8 +532,8 @@ let check_after_sync_cache_nonce_are_set = QCheck.( make Gen.( - gen_cache () >>= fun (_, entries, cache) -> - gen_entries (number_of_caches cache) >>= fun fresh_entries -> + let* (_, entries, cache) = gen_cache () in + let* fresh_entries = gen_entries (number_of_caches cache) in return (entries, cache, fresh_entries))) after_sync_cache_nonce_are_set diff --git a/src/lib_proxy_server_config/test/test_proxy_server_config.ml b/src/lib_proxy_server_config/test/test_proxy_server_config.ml index a2878f602f..98d801ae76 100644 --- a/src/lib_proxy_server_config/test/test_proxy_server_config.ml +++ b/src/lib_proxy_server_config/test/test_proxy_server_config.ml @@ -36,7 +36,7 @@ open Lib_test open Tezos_proxy_server_config (** Lift an arbitrary of ['a] to ['a option] by always creating [Some] values *) -let to_some gen = QCheck.Gen.(gen >|= Option.some) +let to_some gen = QCheck.Gen.(map Option.some gen) (** A generator that generates valid values for the [rpc_addr] field *) let rpc_addr_gen = @@ -55,12 +55,16 @@ let rpc_addr_gen = let path_gen = let open QCheck.Gen in (* Generate something that looks like a Unix path *) - list_size (1 -- 8) (string_size ~gen:(char_range 'a' 'z') (1 -- 8)) - >|= fun s -> "/" ^ String.concat "/" s + let+ s = + list_size (1 -- 8) (string_size ~gen:(char_range 'a' 'z') (1 -- 8)) + in + "/" ^ String.concat "/" s (** A generator that generates valid values for the [rpc_tls] field *) let rpc_tls_gen = - QCheck.Gen.(pair path_gen path_gen >|= fun (cert, key) -> cert ^ "," ^ key) + QCheck.Gen.( + let+ (cert, key) = pair path_gen path_gen in + cert ^ "," ^ key) (** A generator that generates valid values for the [sym_block_caching_time] field *) @@ -77,13 +81,13 @@ let proxy_server_config_arb endpoint_gen rpc_addr_gen rpc_tls_gen sym_block_caching_time_gen data_dir_gen = let gen = QCheck.Gen.( - quad - endpoint_gen - rpc_addr_gen - rpc_tls_gen - (pair sym_block_caching_time_gen data_dir_gen) - >|= fun (endpoint, rpc_addr, rpc_tls, (sym_block_caching_time, data_dir)) - -> + let+ (endpoint, rpc_addr, rpc_tls, (sym_block_caching_time, data_dir)) = + quad + endpoint_gen + rpc_addr_gen + rpc_tls_gen + (pair sym_block_caching_time_gen data_dir_gen) + in Proxy_server_config.make ~endpoint ~rpc_addr diff --git a/src/lib_shell/test/generators.ml b/src/lib_shell/test/generators.ml index 6e98aed04e..76dc0278d1 100644 --- a/src/lib_shell/test/generators.ml +++ b/src/lib_shell/test/generators.ml @@ -61,8 +61,9 @@ let operation_gen ?(proto_gen = operation_proto_gen) ?block_hash_t () : Operation.t QCheck2.Gen.t = let open QCheck2.Gen in let prod_block_hash_gen = Option.value ~default:block_hash_gen block_hash_t in - let+ branch = prod_block_hash_gen - and+ proto = proto_gen >|= Bytes.of_string in + let* branch = prod_block_hash_gen in + let+ proto = proto_gen in + let proto = Bytes.of_string proto in Operation.{shell = {branch}; proto} (** Like {!operation_gen} with a hash. *) @@ -277,4 +278,5 @@ let with_t_operation_gen : unit t -> unit Prevalidation.operation QCheck2.Gen.t let t_with_operation_gen ?can_be_full () : (unit t * unit Prevalidation.operation) QCheck2.Gen.t = let open QCheck2.Gen in - t_gen ?can_be_full () >>= fun t -> pair (return t) (with_t_operation_gen t) + let* t = t_gen ?can_be_full () in + pair (return t) (with_t_operation_gen t) diff --git a/src/lib_shell/test/generators_tree.ml b/src/lib_shell/test/generators_tree.ml index d27e521bd6..5e718d5d27 100644 --- a/src/lib_shell/test/generators_tree.ml +++ b/src/lib_shell/test/generators_tree.ml @@ -305,7 +305,7 @@ let block_gen ?proto_gen () : Block.t QCheck2.Gen.t = optional generator for protocol bytes of operations. *) let unique_block_gen ?(list_gen = QCheck2.Gen.small_list) ?proto_gen () : Block.Set.t QCheck2.Gen.t = - QCheck2.Gen.(list_gen (block_gen ?proto_gen ()) >|= Block.Set.of_list) + QCheck2.Gen.(map Block.Set.of_list @@ list_gen (block_gen ?proto_gen ())) (* A generator of sets of {!Block.t} where all elements are guaranteed to be different and returned sets are guaranteed to be non empty. *) @@ -352,7 +352,7 @@ let tree_gen ?blocks () = | None -> (* no blocks received: generate them, use the [nonempty] flavor of the generator, to guarantee [blocks <> []] below. *) - unique_nonempty_block_gen >|= Block.set_to_list + map Block.set_to_list @@ unique_nonempty_block_gen | Some [] -> QCheck2.Test.fail_report "tree_gen should not be called with an empty list of blocks" @@ -373,10 +373,8 @@ let tree_gen ?blocks () = | None -> ret (Tree.Leaf x) | Some sub -> ret (Tree.Node1 (x, sub)) else - let* (left, right) = - QCheck2.Gen.int_bound (List.length xs - 1) >|= fun n -> - List.split_n n xs - in + let* n = QCheck2.Gen.int_bound (List.length xs - 1) in + let (left, right) = List.split_n n xs in let* left = go left and* right = go right in match (left, right) with | (None, None) -> ret (Tree.Leaf x) @@ -385,7 +383,7 @@ let tree_gen ?blocks () = in (* The assertion cannot break, because we made sure that [blocks] is not empty. *) - go blocks >|= Option.value_f ~default:(fun () -> assert false) + map (WithExceptions.Option.get ~loc:__LOC__) (go blocks) (** A generator for passing the last argument of [Prevalidator.handle_live_operations] *) diff --git a/src/lib_shell/test/test_prevalidator_classification.ml b/src/lib_shell/test/test_prevalidator_classification.ml index 954ef64850..e28791ba68 100644 --- a/src/lib_shell/test/test_prevalidator_classification.ml +++ b/src/lib_shell/test/test_prevalidator_classification.ml @@ -128,7 +128,7 @@ module Extra_generators = struct obtained by having applied all previous events to [t_initial]. *) let t_with_event_sequence_gen = let open QCheck2.Gen in - Generators.t_gen () >>= fun t -> + let* t = Generators.t_gen () in let t_initial = Internal_for_tests.copy t in let rec loop acc_gen n = if n <= 0 then acc_gen diff --git a/src/lib_shell/test/test_prevalidator_classification_operations.ml b/src/lib_shell/test/test_prevalidator_classification_operations.ml index 8f51994dff..dcf4f5cb4b 100644 --- a/src/lib_shell/test/test_prevalidator_classification_operations.ml +++ b/src/lib_shell/test/test_prevalidator_classification_operations.ml @@ -141,9 +141,9 @@ module Handle_operations = struct let* (tree, pair_blocks_opt, old_mempool) = Generators_tree.tree_gen ?blocks:None () in - let* live_blocks = - sublist (Tree.values tree) - >|= List.map (fun (blk : Block.t) -> blk.hash) + let* live_blocks = sublist (Tree.values tree) in + let live_blocks = + List.map (fun (blk : Block.t) -> blk.hash) live_blocks in return (tree, pair_blocks_opt, old_mempool, Block_hash.Set.of_list live_blocks) @@ -365,9 +365,8 @@ module Recyle_operations = struct to test the typical use case. *) let gen = let open QCheck2.Gen in - let* blocks = - Generators_tree.unique_nonempty_block_gen >|= Block.set_to_list - in + let* blocks = Generators_tree.unique_nonempty_block_gen in + let blocks = Block.set_to_list blocks in assert (blocks <> []) ; let to_ops (blk : Block.t) = List.concat blk.operations in let oph_op_list_to_map l = List.to_seq l |> Op_map.of_seq in @@ -376,7 +375,6 @@ module Recyle_operations = struct |> List.map (fun op -> (op.Prevalidation.hash, op)) |> oph_op_list_to_map in - let both f (a, b) = (f a, f b) in let blocks_hashes = List.map Block.to_hash blocks in let block_hash_t = (* For classification and pending, put 50% of them in live_blocks. @@ -388,12 +386,18 @@ module Recyle_operations = struct (* For classification and pending, we want operations that are NOT in the blocks already. Hence: *) Generators.op_map_gen ~block_hash_t () - >|= Op_map.filter (fun oph _ -> not (Op_map.mem oph blocks_ops)) + in + let classification_pendings_ops = + Op_map.filter + (fun oph _ -> not (Op_map.mem oph blocks_ops)) + classification_pendings_ops in let* (classification_ops, pending_ops) = Op_map.bindings classification_pendings_ops - |> Generators_tree.split_in_two >|= both oph_op_list_to_map + |> Generators_tree.split_in_two in + let classification_ops = oph_op_list_to_map classification_ops in + let pending_ops = oph_op_list_to_map pending_ops in let* (tree, from_to, _) = Generators_tree.tree_gen ~blocks () in let+ classification = classification_of_ops_gen classification_ops in (tree, from_to, classification, pending_ops) diff --git a/src/lib_stdlib/test-unix/test_circular_buffer_fuzzy.ml b/src/lib_stdlib/test-unix/test_circular_buffer_fuzzy.ml index a27d514e47..b99db03fd4 100644 --- a/src/lib_stdlib/test-unix/test_circular_buffer_fuzzy.ml +++ b/src/lib_stdlib/test-unix/test_circular_buffer_fuzzy.ml @@ -126,13 +126,13 @@ let rec ops_gen acc i = let open QCheck in let open Gen in ops_gen - ( acc >>= fun (nb_writes, ops) -> - let gen = if nb_writes > 0 then op else write_op in - map - (fun op -> - let delta = match op with Write _ -> 1 | Read _ -> -1 in - (nb_writes + delta, op :: ops)) - gen ) + (let* (nb_writes, ops) = acc in + let gen = if nb_writes > 0 then op else write_op in + map + (fun op -> + let delta = match op with Write _ -> 1 | Read _ -> -1 in + (nb_writes + delta, op :: ops)) + gen) (i - 1) (* Scenarios start with a write operation. *) @@ -147,7 +147,9 @@ let values = - quick execution *) let size_gen = Gen.int_range 0 1000 in - Gen.(size_gen >>= ops_gen) + Gen.( + let* size = size_gen in + ops_gen size) let values = QCheck.make ~print:(Format.asprintf "%a" pp) values From 26097bc6f4e41cfa93951a96d2061898e26b3f78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Proust?= Date: Tue, 15 Mar 2022 10:23:28 +0100 Subject: [PATCH 016/100] Everywhere: minor improvement in Qcheck generators --- src/lib_context/test/test_merkle_proof.ml | 6 ++---- .../test/test_proxy_server_config.ml | 14 ++++++-------- src/lib_shell/test/generators_tree.ml | 2 +- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/lib_context/test/test_merkle_proof.ml b/src/lib_context/test/test_merkle_proof.ml index b434ab59e2..98e6560696 100644 --- a/src/lib_context/test/test_merkle_proof.ml +++ b/src/lib_context/test/test_merkle_proof.ml @@ -148,8 +148,7 @@ module Proof32 (Encoding : Tezos_context_sigs.Context.PROOF_ENCODING) = struct let kinded_hash = let* h = hash in - let+ b = bool in - match b with true -> `Value h | false -> `Node h + oneofl [`Value h; `Node h] let tree_proof = let* version = int_bound 3 in @@ -380,8 +379,7 @@ module Proof2 (Encoding : Tezos_context_sigs.Context.PROOF_ENCODING) = struct let kinded_hash = let* h = hash in - let+ b = bool in - match b with true -> `Value h | false -> `Node h + oneofl [`Value h; `Node h] let tree_proof = let* version = int_bound 3 in diff --git a/src/lib_proxy_server_config/test/test_proxy_server_config.ml b/src/lib_proxy_server_config/test/test_proxy_server_config.ml index 98d801ae76..d0c2d5ae4b 100644 --- a/src/lib_proxy_server_config/test/test_proxy_server_config.ml +++ b/src/lib_proxy_server_config/test/test_proxy_server_config.ml @@ -58,7 +58,7 @@ let path_gen = let+ s = list_size (1 -- 8) (string_size ~gen:(char_range 'a' 'z') (1 -- 8)) in - "/" ^ String.concat "/" s + String.concat "/" ("" :: s) (** A generator that generates valid values for the [rpc_tls] field *) let rpc_tls_gen = @@ -81,13 +81,11 @@ let proxy_server_config_arb endpoint_gen rpc_addr_gen rpc_tls_gen sym_block_caching_time_gen data_dir_gen = let gen = QCheck.Gen.( - let+ (endpoint, rpc_addr, rpc_tls, (sym_block_caching_time, data_dir)) = - quad - endpoint_gen - rpc_addr_gen - rpc_tls_gen - (pair sym_block_caching_time_gen data_dir_gen) - in + let* endpoint = endpoint_gen in + let* rpc_addr = rpc_addr_gen in + let* rpc_tls = rpc_tls_gen in + let* sym_block_caching_time = sym_block_caching_time_gen in + let+ data_dir = data_dir_gen in Proxy_server_config.make ~endpoint ~rpc_addr diff --git a/src/lib_shell/test/generators_tree.ml b/src/lib_shell/test/generators_tree.ml index 5e718d5d27..515fa0b6f5 100644 --- a/src/lib_shell/test/generators_tree.ml +++ b/src/lib_shell/test/generators_tree.ml @@ -352,7 +352,7 @@ let tree_gen ?blocks () = | None -> (* no blocks received: generate them, use the [nonempty] flavor of the generator, to guarantee [blocks <> []] below. *) - map Block.set_to_list @@ unique_nonempty_block_gen + map Block.set_to_list unique_nonempty_block_gen | Some [] -> QCheck2.Test.fail_report "tree_gen should not be called with an empty list of blocks" From 8a35a4c8e41250c1e635b2498f65fe245b41dd44 Mon Sep 17 00:00:00 2001 From: Mehdi Bouaziz Date: Mon, 4 Oct 2021 09:38:13 +0200 Subject: [PATCH 017/100] Proto/Michelson: introduce ty_ex_c It will be used to introduce an existential on the soon-to-be-added second parameter of ty --- .../lib_benchmark/michelson_samplers.ml | 4 +- .../interpreter_benchmarks.ml | 18 +++--- .../lib_benchmarks_proto/michelson_types.ml | 4 +- .../lib_benchmarks_proto/ticket_benchmarks.ml | 6 +- .../translator_benchmarks.ml | 6 +- .../lib_protocol/script_interpreter.ml | 3 +- .../lib_protocol/script_ir_translator.ml | 51 +++++++++-------- .../lib_protocol/script_typed_ir.ml | 10 ++-- .../lib_protocol/script_typed_ir.mli | 9 ++- .../lib_protocol/script_typed_ir_size.ml | 7 +-- .../integration/michelson/test_sapling.ml | 2 +- .../michelson/test_ticket_accounting.ml | 2 +- .../michelson/test_typechecking.ml | 57 ++++++++++--------- 13 files changed, 98 insertions(+), 81 deletions(-) diff --git a/src/proto_alpha/lib_benchmark/michelson_samplers.ml b/src/proto_alpha/lib_benchmark/michelson_samplers.ml index dbbb1f8d7f..a19d6db445 100644 --- a/src/proto_alpha/lib_benchmark/michelson_samplers.ml +++ b/src/proto_alpha/lib_benchmark/michelson_samplers.ml @@ -382,7 +382,7 @@ end) let* (Ex_ty right) = m_type ~size:rsize in match pair_t (-1) left right with | Error _ -> assert false - | Ok res_ty -> return @@ Ex_ty res_ty) + | Ok (Ty_ex_c res_ty) -> return @@ Ex_ty res_ty) | `TLambda -> ( let* (lsize, rsize) = pick_split (size - 1) in let* (Ex_ty domain) = m_type ~size:lsize in @@ -396,7 +396,7 @@ end) let* (Ex_ty right) = m_type ~size:rsize in match union_t (-1) left right with | Error _ -> assert false - | Ok res_ty -> return @@ Ex_ty res_ty) + | Ok (Ty_ex_c res_ty) -> return @@ Ex_ty res_ty) | `TOption -> ( let* (Ex_ty t) = m_type ~size:(size - 1) in match option_t (-1) t with diff --git a/src/proto_alpha/lib_benchmarks_proto/interpreter_benchmarks.ml b/src/proto_alpha/lib_benchmarks_proto/interpreter_benchmarks.ml index 53d3028f37..1a91337abe 100644 --- a/src/proto_alpha/lib_benchmarks_proto/interpreter_benchmarks.ml +++ b/src/proto_alpha/lib_benchmarks_proto/interpreter_benchmarks.ml @@ -850,7 +850,7 @@ module Registration_section = struct else match comb_acc with | Ex_value {value; ty} -> - let ty = pair unit ty in + let (Ty_ex_c ty) = pair unit ty in make_comb (comb_width - 1) (Ex_value {value = ((), value); ty}) let () = @@ -2178,7 +2178,7 @@ module Registration_section = struct let () = let lambda = let open Script_typed_ir in - let pair_list_operation_unit = pair (list operation) unit in + let (Ty_ex_c pair_list_operation_unit) = pair (list operation) unit in let descr = { kloc = 0; @@ -2462,8 +2462,10 @@ module Registration_section = struct let kinstr = let spl_state = sapling_state memo_size in let spl_tx = sapling_transaction memo_size in - let pair_int_spl_state = pair int spl_state in - let pair_bytes_pair_int_spl_state = pair bytes pair_int_spl_state in + let (Ty_ex_c pair_int_spl_state) = pair int spl_state in + let (Ty_ex_c pair_bytes_pair_int_spl_state) = + pair bytes pair_int_spl_state + in ISapling_verify_update ( kinfo (spl_tx @$ spl_state @$ bot), halt (option pair_bytes_pair_int_spl_state @$ bot) ) @@ -2668,7 +2670,7 @@ module Registration_section = struct () let () = - let pair_bls12_381_g1_g2 = pair bls12_381_g1 bls12_381_g2 in + let (Ty_ex_c pair_bls12_381_g1_g2) = pair bls12_381_g1 bls12_381_g2 in simple_benchmark ~name:Interpreter_workload.N_IPairing_check_bls12_381 ~kinstr: @@ -2697,7 +2699,9 @@ module Registration_section = struct let split_ticket_instr = let ticket_unit = ticket unit_cmp in - let pair_ticket_unit_ticket_unit = pair ticket_unit ticket_unit in + let (Ty_ex_c pair_ticket_unit_ticket_unit) = + pair ticket_unit ticket_unit + in ISplit_ticket ( kinfo (ticket_unit @$ cpair nat nat @$ bot), halt (option pair_ticket_unit_ticket_unit @$ bot) ) @@ -2745,7 +2749,7 @@ module Registration_section = struct let join_tickets_instr = let ticket_str = ticket string_cmp in - let pair_ticket_str_ticket_str = pair ticket_str ticket_str in + let (Ty_ex_c pair_ticket_str_ticket_str) = pair ticket_str ticket_str in IJoin_tickets ( kinfo (pair_ticket_str_ticket_str @$ bot), string_cmp, diff --git a/src/proto_alpha/lib_benchmarks_proto/michelson_types.ml b/src/proto_alpha/lib_benchmarks_proto/michelson_types.ml index f8fcd1d897..019736f39f 100644 --- a/src/proto_alpha/lib_benchmarks_proto/michelson_types.ml +++ b/src/proto_alpha/lib_benchmarks_proto/michelson_types.ml @@ -98,7 +98,7 @@ let pair k1 k2 = (* (will become) comparable pair type constructor *) let cpair k1 k2 = - match pair_t (-1) k1 k2 with Error _ -> assert false | Ok t -> t + match pair_t (-1) k1 k2 with Error _ -> assert false | Ok (Ty_ex_c t) -> t (* union type constructor*) let union k1 k2 = @@ -106,7 +106,7 @@ let union k1 k2 = (* (will become) comparable union type constructor *) let cunion k1 k2 = - match union_t (-1) k1 k2 with Error _ -> assert false | Ok t -> t + match union_t (-1) k1 k2 with Error _ -> assert false | Ok (Ty_ex_c t) -> t let lambda x y = match lambda_t (-1) x y with Error _ -> assert false | Ok t -> t diff --git a/src/proto_alpha/lib_benchmarks_proto/ticket_benchmarks.ml b/src/proto_alpha/lib_benchmarks_proto/ticket_benchmarks.ml index 421e96959a..23fadf09a6 100644 --- a/src/proto_alpha/lib_benchmarks_proto/ticket_benchmarks.ml +++ b/src/proto_alpha/lib_benchmarks_proto/ticket_benchmarks.ml @@ -188,8 +188,10 @@ let rec dummy_type_generator ~rng_state size = if size <= 1 then ticket_or_int else match (ticket_or_int, dummy_type_generator ~rng_state (size - 3)) with - | (Ex_ty l, Ex_ty r) -> - Ex_ty (match pair_t (-1) l r with Error _ -> assert false | Ok t -> t) + | (Ex_ty l, Ex_ty r) -> ( + match pair_t (-1) l r with + | Error _ -> assert false + | Ok (Ty_ex_c t) -> Ex_ty t) (** A benchmark for {!Ticket_costs.Constants.cost_has_tickets_of_ty}. *) module Has_tickets_type_benchmark : Benchmark.S = struct diff --git a/src/proto_alpha/lib_benchmarks_proto/translator_benchmarks.ml b/src/proto_alpha/lib_benchmarks_proto/translator_benchmarks.ml index a967e3a0b1..e24350e3e5 100644 --- a/src/proto_alpha/lib_benchmarks_proto/translator_benchmarks.ml +++ b/src/proto_alpha/lib_benchmarks_proto/translator_benchmarks.ml @@ -637,9 +637,11 @@ let rec dummy_type_generator size = if size <= 1 then Ex_ty unit_t else match dummy_type_generator (size - 2) with - | Ex_ty r -> + | Ex_ty r -> ( let l = unit_t in - Ex_ty (match pair_t (-1) l r with Error _ -> assert false | Ok t -> t) + match pair_t (-1) l r with + | Error _ -> assert false + | Ok (Ty_ex_c t) -> Ex_ty t) (* A dummy comparable type generator, sampling linear terms of a given size. *) let rec dummy_comparable_type_generator size = diff --git a/src/proto_alpha/lib_protocol/script_interpreter.ml b/src/proto_alpha/lib_protocol/script_interpreter.ml index a066cc5035..44bf599995 100644 --- a/src/proto_alpha/lib_protocol/script_interpreter.ml +++ b/src/proto_alpha/lib_protocol/script_interpreter.ml @@ -1084,7 +1084,8 @@ and step : type a s b t r f. (a, s, b, t, r, f) step_type = kinstr; }, _script_view ) -> ( - pair_t kloc input_ty storage_type >>?= fun pair_ty -> + pair_t kloc input_ty storage_type + >>?= fun (Ty_ex_c pair_ty) -> let io_ty = let open Gas_monad.Syntax in let* out_eq = diff --git a/src/proto_alpha/lib_protocol/script_ir_translator.ml b/src/proto_alpha/lib_protocol/script_ir_translator.ml index 38df9c7a99..f923123e09 100644 --- a/src/proto_alpha/lib_protocol/script_ir_translator.ml +++ b/src/proto_alpha/lib_protocol/script_ir_translator.ml @@ -1362,7 +1362,7 @@ let[@coq_axiom_with_reason "complex mutually recursive definition"] rec parse_ty utr >>? fun (Ex_ty tr, ctxt) -> check_type_annot loc annot >>? fun () -> - pair_t loc tl tr >|? fun ty -> return ctxt ty + pair_t loc tl tr >|? fun (Ty_ex_c ty) -> return ctxt ty | Prim (loc, T_or, [utl; utr], annot) -> ( (match ret with | Don't_parse_entrypoints -> @@ -1397,7 +1397,7 @@ let[@coq_axiom_with_reason "complex mutually recursive definition"] rec parse_ty | Don't_parse_entrypoints -> let (Ex_ty tl) = parsed_l in let (Ex_ty tr) = parsed_r in - union_t loc tl tr >|? fun ty -> ((Ex_ty ty : ret), ctxt) + union_t loc tl tr >|? fun (Ty_ex_c ty) -> ((Ex_ty ty : ret), ctxt) | Parse_entrypoints -> let (Ex_parameter_ty_and_entrypoints {arg_type = tl; entrypoints = left}) = @@ -1407,7 +1407,7 @@ let[@coq_axiom_with_reason "complex mutually recursive definition"] rec parse_ty {arg_type = tr; entrypoints = right}) = parsed_r in - union_t loc tl tr >|? fun arg_type -> + union_t loc tl tr >|? fun (Ty_ex_c arg_type) -> let entrypoints = {name; nested = Entrypoints_Union {left; right}} in @@ -1721,8 +1721,8 @@ let parse_storage_ty : remaining_storage >>? fun (Ex_ty remaining_storage, ctxt) -> check_composed_type_annot loc storage_annot >>? fun () -> - pair_t loc big_map_ty remaining_storage >|? fun ty -> (Ex_ty ty, ctxt) - ) + pair_t loc big_map_ty remaining_storage >|? fun (Ty_ex_c ty) -> + (Ex_ty ty, ctxt)) | _ -> (parse_normal_storage_ty [@tailcall]) ctxt ~stack_depth ~legacy node let check_packable ~legacy loc root = @@ -1907,12 +1907,12 @@ let rec make_comb_set_proof_argument : match (n, ty) with | (0, _) -> ok @@ Comb_set_proof_argument (Comb_set_zero, value_ty) | (1, Pair_t (_hd_ty, tl_ty, _)) -> - pair_t loc value_ty tl_ty >|? fun after_ty -> + pair_t loc value_ty tl_ty >|? fun (Ty_ex_c after_ty) -> Comb_set_proof_argument (Comb_set_one, after_ty) | (n, Pair_t (hd_ty, tl_ty, _)) -> make_comb_set_proof_argument ctxt stack_ty loc (n - 2) value_ty tl_ty >>? fun (Comb_set_proof_argument (comb_set_left_witness, tl_ty')) -> - pair_t loc hd_ty tl_ty' >|? fun after_ty -> + pair_t loc hd_ty tl_ty' >|? fun (Ty_ex_c after_ty) -> Comb_set_proof_argument (Comb_set_plus_two comb_set_left_witness, after_ty) | _ -> let whole_stack = serialize_stack_for_error ctxt stack_ty in @@ -2962,7 +2962,7 @@ and parse_view_returning : (Some "return of view", strip_locations output_ty, output_ty_loc)) (parse_view_output_ty ctxt ~stack_depth:0 ~legacy output_ty) >>?= fun (Ex_ty output_ty', ctxt) -> - pair_t input_ty_loc input_ty' storage_type >>?= fun pair_ty -> + pair_t input_ty_loc input_ty' storage_type >>?= fun (Ty_ex_c pair_ty) -> parse_instr ?type_logger ~stack_depth:0 @@ -3326,7 +3326,7 @@ and[@coq_axiom_with_reason "gadt"] parse_instr : (* pairs *) | (Prim (loc, I_PAIR, [], annot), Item_t (a, Item_t (b, rest))) -> check_constr_annot loc annot >>?= fun () -> - pair_t loc a b >>?= fun ty -> + pair_t loc a b >>?= fun (Ty_ex_c ty) -> let stack_ty = Item_t (ty, rest) in let cons_pair = {apply = (fun kinfo k -> ICons_pair (kinfo, k))} in typed ctxt loc cons_pair stack_ty @@ -3343,7 +3343,7 @@ and[@coq_axiom_with_reason "gadt"] parse_instr : make_proof_argument (n - 1) tl_ty >>? fun (Comb_proof_argument (comb_witness, Item_t (b_ty, tl_ty'))) -> - pair_t loc a_ty b_ty >|? fun pair_t -> + pair_t loc a_ty b_ty >|? fun (Ty_ex_c pair_t) -> Comb_proof_argument (Comb_succ comb_witness, Item_t (pair_t, tl_ty')) | _ -> let whole_stack = serialize_stack_for_error ctxt stack_ty in @@ -3426,7 +3426,7 @@ and[@coq_axiom_with_reason "gadt"] parse_instr : >>?= fun (Ex_ty tr, ctxt) -> check_constr_annot loc annot >>?= fun () -> let cons_left = {apply = (fun kinfo k -> ICons_left (kinfo, k))} in - union_t loc tl tr >>?= fun ty -> + union_t loc tl tr >>?= fun (Ty_ex_c ty) -> let stack_ty = Item_t (ty, rest) in typed ctxt loc cons_left stack_ty | (Prim (loc, I_RIGHT, [tl], annot), Item_t (tr, rest)) -> @@ -3434,7 +3434,7 @@ and[@coq_axiom_with_reason "gadt"] parse_instr : >>?= fun (Ex_ty tl, ctxt) -> check_constr_annot loc annot >>?= fun () -> let cons_right = {apply = (fun kinfo k -> ICons_right (kinfo, k))} in - union_t loc tl tr >>?= fun ty -> + union_t loc tl tr >>?= fun (Ty_ex_c ty) -> let stack_ty = Item_t (ty, rest) in typed ctxt loc cons_right stack_ty | ( Prim (loc, I_IF_LEFT, [bt; bf], annot), @@ -3671,7 +3671,7 @@ and[@coq_axiom_with_reason "gadt"] parse_instr : let k = ty_of_comparable_ty ck in check_kind [Seq_kind] body >>?= fun () -> check_var_type_annot loc annot >>?= fun () -> - pair_t loc k elt >>?= fun ty -> + pair_t loc k elt >>?= fun (Ty_ex_c ty) -> non_terminal_recursion ?type_logger tc_context @@ -3713,7 +3713,7 @@ and[@coq_axiom_with_reason "gadt"] parse_instr : check_kind [Seq_kind] body >>?= fun () -> error_unexpected_annot loc annot >>?= fun () -> let key = ty_of_comparable_ty comp_elt in - pair_t loc key element_ty >>?= fun ty -> + pair_t loc key element_ty >>?= fun (Ty_ex_c ty) -> non_terminal_recursion ?type_logger tc_context @@ -3868,7 +3868,7 @@ and[@coq_axiom_with_reason "gadt"] parse_instr : apply = (fun kinfo k -> ISapling_verify_update_deprecated (kinfo, k)); } in - pair_t loc int_t state_ty >>?= fun pair_ty -> + pair_t loc int_t state_ty >>?= fun (Ty_ex_c pair_ty) -> option_t loc pair_ty >>?= fun ty -> let stack = Item_t (ty, rest) in typed ctxt loc instr stack @@ -3885,8 +3885,8 @@ and[@coq_axiom_with_reason "gadt"] parse_instr : let instr = {apply = (fun kinfo k -> ISapling_verify_update (kinfo, k))} in - pair_t loc int_t state_ty >>?= fun pair_ty -> - pair_t loc bytes_t pair_ty >>?= fun pair_ty -> + pair_t loc int_t state_ty >>?= fun (Ty_ex_c pair_ty) -> + pair_t loc bytes_t pair_ty >>?= fun (Ty_ex_c pair_ty) -> option_t loc pair_ty >>?= fun ty -> let stack = Item_t (ty, rest) in typed ctxt loc instr stack @@ -4595,8 +4595,9 @@ and[@coq_axiom_with_reason "gadt"] parse_instr : ~legacy storage_type) >>?= fun (Ex_ty storage_type, ctxt) -> - pair_t loc arg_type storage_type >>?= fun arg_type_full -> - pair_t loc list_operation_t storage_type >>?= fun ret_type_full -> + pair_t loc arg_type storage_type >>?= fun (Ty_ex_c arg_type_full) -> + pair_t loc list_operation_t storage_type + >>?= fun (Ty_ex_c ret_type_full) -> trace (Ill_typed_contract (canonical_code, [])) (parse_returning @@ -4860,7 +4861,7 @@ and[@coq_axiom_with_reason "gadt"] parse_instr : ) -> check_var_annot loc annot >>?= fun () -> let () = check_dupable_comparable_ty t in - pair_t loc ticket_t ticket_t >>?= fun pair_tickets_ty -> + pair_t loc ticket_t ticket_t >>?= fun (Ty_ex_c pair_tickets_ty) -> option_t loc pair_tickets_ty >>?= fun res_ty -> let instr = {apply = (fun kinfo k -> ISplit_ticket (kinfo, k))} in let stack = Item_t (res_ty, rest) in @@ -5421,9 +5422,10 @@ let parse_code : (Ill_formed_type (Some "storage", code, storage_type_loc)) (parse_storage_ty ctxt ~stack_depth:0 ~legacy storage_type) >>?= fun (Ex_ty storage_type, ctxt) -> - pair_t storage_type_loc arg_type storage_type >>?= fun arg_type_full -> + pair_t storage_type_loc arg_type storage_type + >>?= fun (Ty_ex_c arg_type_full) -> pair_t storage_type_loc list_operation_t storage_type - >>?= fun ret_type_full -> + >>?= fun (Ty_ex_c ret_type_full) -> trace (Ill_typed_contract (code, [])) (parse_returning @@ -5517,9 +5519,10 @@ let typecheck_code : (Ill_formed_type (Some "storage", code, storage_type_loc)) (parse_storage_ty ctxt ~stack_depth:0 ~legacy storage_type) >>?= fun (Ex_ty storage_type, ctxt) -> - pair_t storage_type_loc arg_type storage_type >>?= fun arg_type_full -> + pair_t storage_type_loc arg_type storage_type + >>?= fun (Ty_ex_c arg_type_full) -> pair_t storage_type_loc list_operation_t storage_type - >>?= fun ret_type_full -> + >>?= fun (Ty_ex_c ret_type_full) -> let type_logger loc ~stack_ty_before ~stack_ty_after = type_map := (loc, (stack_ty_before, stack_ty_after)) :: !type_map in diff --git a/src/proto_alpha/lib_protocol/script_typed_ir.ml b/src/proto_alpha/lib_protocol/script_typed_ir.ml index 38aeb1b605..07d0f2ac52 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir.ml +++ b/src/proto_alpha/lib_protocol/script_typed_ir.ml @@ -1793,6 +1793,8 @@ let ty_size t = (ty_metadata t).size let comparable_ty_size t = (comparable_ty_metadata t).size +type 'v ty_ex_c = Ty_ex_c : 'v ty -> 'v ty_ex_c [@@ocaml.unboxed] + let unit_t = Unit_t let unit_key = Unit_key @@ -1847,7 +1849,7 @@ let tx_rollup_l2_address_key = Tx_rollup_l2_address_key let pair_t loc l r = Type_size.compound2 loc (ty_size l) (ty_size r) >|? fun size -> - Pair_t (l, r, {size}) + Ty_ex_c (Pair_t (l, r, {size})) let pair_key loc l r = Type_size.compound2 loc (comparable_ty_size l) (comparable_ty_size r) @@ -1857,7 +1859,7 @@ let pair_3_key loc l m r = pair_key loc m r >>? fun r -> pair_key loc l r let union_t loc l r = Type_size.compound2 loc (ty_size l) (ty_size r) >|? fun size -> - Union_t (l, r, {size}) + Ty_ex_c (Union_t (l, r, {size})) let union_bytes_bool_t = Union_t (bytes_t, bool_t, {size = Type_size.three}) @@ -2343,5 +2345,5 @@ let value_traverse (type t) (ty : (t ty, t comparable_ty) union) (x : t) init f | R cty -> aux' init cty x (fun accu -> accu) [@@coq_axiom_with_reason "local mutually recursive definition not handled"] -let stack_top_ty : type a b s. (a, b * s) stack_ty -> a ty = function - | Item_t (ty, _) -> ty +let stack_top_ty : type a b s. (a, b * s) stack_ty -> a ty_ex_c = function + | Item_t (ty, _) -> Ty_ex_c ty diff --git a/src/proto_alpha/lib_protocol/script_typed_ir.mli b/src/proto_alpha/lib_protocol/script_typed_ir.mli index d7e8496272..a983ed4911 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir.mli +++ b/src/proto_alpha/lib_protocol/script_typed_ir.mli @@ -1540,6 +1540,8 @@ val ty_size : 'a ty -> 'a Type_size.t val comparable_ty_size : 'a comparable_ty -> 'a Type_size.t +type 'v ty_ex_c = Ty_ex_c : 'v ty -> 'v ty_ex_c [@@ocaml.unboxed] + val unit_key : unit comparable_ty val never_key : never comparable_ty @@ -1618,9 +1620,10 @@ val tx_rollup_l2_address_t : tx_rollup_l2_address ty val bool_t : bool ty -val pair_t : Script.location -> 'a ty -> 'b ty -> ('a, 'b) pair ty tzresult +val pair_t : Script.location -> 'a ty -> 'b ty -> ('a, 'b) pair ty_ex_c tzresult -val union_t : Script.location -> 'a ty -> 'b ty -> ('a, 'b) union ty tzresult +val union_t : + Script.location -> 'a ty -> 'b ty -> ('a, 'b) union ty_ex_c tzresult val union_bytes_bool_t : (Bytes.t, bool) union ty @@ -1736,4 +1739,4 @@ type 'a value_traverse = { val value_traverse : ('t ty, 't comparable_ty) union -> 't -> 'r -> 'r value_traverse -> 'r -val stack_top_ty : ('a, 'b * 's) stack_ty -> 'a ty +val stack_top_ty : ('a, 'b * 's) stack_ty -> 'a ty_ex_c diff --git a/src/proto_alpha/lib_protocol/script_typed_ir_size.ml b/src/proto_alpha/lib_protocol/script_typed_ir_size.ml index bcc08ee530..2555e15858 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir_size.ml +++ b/src/proto_alpha/lib_protocol/script_typed_ir_size.ml @@ -433,11 +433,8 @@ and kinstr_size : | ISwap (kinfo, _) -> ret_succ_adding accu (base kinfo) | IConst (kinfo, x, k) -> let accu = ret_succ_adding accu (base kinfo +! word_size) in - (value_size [@ocaml.tailcall]) - ~count_lambda_nodes - accu - (L (stack_top_ty (kinfo_of_kinstr k).kstack_ty)) - x + let (Ty_ex_c top_ty) = stack_top_ty (kinfo_of_kinstr k).kstack_ty in + (value_size [@ocaml.tailcall]) ~count_lambda_nodes accu (L top_ty) x | ICons_pair (kinfo, _) -> ret_succ_adding accu (base kinfo) | ICar (kinfo, _) -> ret_succ_adding accu (base kinfo) | ICdr (kinfo, _) -> ret_succ_adding accu (base kinfo) diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_sapling.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_sapling.ml index 5413552618..4e9918de5d 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_sapling.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_sapling.ml @@ -1049,7 +1049,7 @@ module Interpreter_tests = struct let open Script_typed_ir in let state_ty = sapling_state_t ~memo_size in pair_t (-1) state_ty state_ty) - >>??= fun tytype -> + >>??= fun (Ty_ex_c tytype) -> Script_ir_translator.parse_storage ctx_without_gas ~legacy:true diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_accounting.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_accounting.ml index 86c5c4002d..9a70b37d20 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_accounting.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_accounting.ml @@ -785,7 +785,7 @@ let test_diffs_args_storage_and_lazy_diffs () = let*? int_ticket_big_map_ty = big_map_type ~key_type:int_key ~value_type:ticket_string_type in - let*? list_big_map_pair_type = + let*? (Ty_ex_c list_big_map_pair_type) = Environment.wrap_tzresult @@ pair_t (-1) ticket_string_list_type int_ticket_big_map_ty in diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_typechecking.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_typechecking.ml index c63cd71ce4..90f03f0606 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_typechecking.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_typechecking.ml @@ -197,54 +197,56 @@ let test_parse_comb_type () = let pair_ty ty1 ty2 = pair_t (-1) ty1 ty2 in let pair_prim2 a b = pair_prim [a; b] in let pair_nat_nat_prim = pair_prim2 nat_prim nat_prim in - pair_ty nat_ty nat_ty >>??= fun pair_nat_nat_ty -> + pair_ty nat_ty nat_ty >>??= fun (Ty_ex_c pair_nat_nat_ty) -> test_context () >>=? fun ctxt -> (* pair nat nat *) test_parse_ty ctxt pair_nat_nat_prim pair_nat_nat_ty >>?= fun ctxt -> (* pair (pair nat nat) nat *) - pair_ty pair_nat_nat_ty nat_ty >>??= fun pair_pair_nat_nat_nat_ty -> + pair_ty pair_nat_nat_ty nat_ty >>??= fun (Ty_ex_c pair_pair_nat_nat_nat_ty) -> test_parse_ty ctxt (pair_prim2 pair_nat_nat_prim nat_prim) pair_pair_nat_nat_nat_ty >>?= fun ctxt -> (* pair nat (pair nat nat) *) - pair_ty nat_ty pair_nat_nat_ty >>??= fun pair_nat_pair_nat_nat_ty -> + pair_ty nat_ty pair_nat_nat_ty >>??= fun (Ty_ex_c pair_nat_pair_nat_nat_ty) -> test_parse_ty ctxt (pair_prim2 nat_prim pair_nat_nat_prim) pair_nat_pair_nat_nat_ty >>?= fun ctxt -> (* pair nat nat nat *) - pair_ty nat_ty pair_nat_nat_ty >>??= fun pair_nat_nat_nat_ty -> + pair_ty nat_ty pair_nat_nat_ty >>??= fun (Ty_ex_c pair_nat_nat_nat_ty) -> test_parse_ty ctxt (pair_prim [nat_prim; nat_prim; nat_prim]) pair_nat_nat_nat_ty >>?= fun ctxt -> (* pair (nat %a) nat *) - pair_t (-1) nat_ty nat_ty >>??= fun pair_nat_a_nat_ty -> + pair_t (-1) nat_ty nat_ty >>??= fun (Ty_ex_c pair_nat_a_nat_ty) -> test_parse_ty ctxt (pair_prim2 nat_prim_a nat_prim) pair_nat_a_nat_ty >>?= fun ctxt -> (* pair nat (nat %b) *) - pair_t (-1) nat_ty nat_ty >>??= fun pair_nat_nat_b_ty -> + pair_t (-1) nat_ty nat_ty >>??= fun (Ty_ex_c pair_nat_nat_b_ty) -> test_parse_ty ctxt (pair_prim2 nat_prim nat_prim_b) pair_nat_nat_b_ty >>?= fun ctxt -> (* pair (nat %a) (nat %b) *) - pair_t (-1) nat_ty nat_ty >>??= fun pair_nat_a_nat_b_ty -> + pair_t (-1) nat_ty nat_ty >>??= fun (Ty_ex_c pair_nat_a_nat_b_ty) -> test_parse_ty ctxt (pair_prim2 nat_prim_a nat_prim_b) pair_nat_a_nat_b_ty >>?= fun ctxt -> (* pair (nat %a) (nat %b) (nat %c) *) - pair_t (-1) nat_ty nat_ty >>??= fun pair_nat_b_nat_c_ty -> - pair_t (-1) nat_ty pair_nat_b_nat_c_ty >>??= fun pair_nat_a_nat_b_nat_c_ty -> + pair_t (-1) nat_ty nat_ty >>??= fun (Ty_ex_c pair_nat_b_nat_c_ty) -> + pair_t (-1) nat_ty pair_nat_b_nat_c_ty + >>??= fun (Ty_ex_c pair_nat_a_nat_b_nat_c_ty) -> test_parse_ty ctxt (pair_prim [nat_prim_a; nat_prim_b; nat_prim_c]) pair_nat_a_nat_b_nat_c_ty >>?= fun ctxt -> (* pair (nat %a) (pair %b nat nat) *) - pair_t (-1) nat_ty nat_ty >>??= fun pair_b_nat_nat_ty -> - pair_t (-1) nat_ty pair_b_nat_nat_ty >>??= fun pair_nat_a_pair_b_nat_nat_ty -> + pair_t (-1) nat_ty nat_ty >>??= fun (Ty_ex_c pair_b_nat_nat_ty) -> + pair_t (-1) nat_ty pair_b_nat_nat_ty + >>??= fun (Ty_ex_c pair_nat_a_pair_b_nat_nat_ty) -> test_parse_ty ctxt (pair_prim2 nat_prim_a (Prim (-1, T_pair, [nat_prim; nat_prim], ["%b"]))) @@ -266,13 +268,13 @@ let test_unparse_comb_type () = let pair_ty ty1 ty2 = pair_t (-1) ty1 ty2 in let pair_prim2 a b = pair_prim [a; b] in let pair_nat_nat_prim = pair_prim2 nat_prim nat_prim in - pair_ty nat_ty nat_ty >>??= fun pair_nat_nat_ty -> + pair_ty nat_ty nat_ty >>??= fun (Ty_ex_c pair_nat_nat_ty) -> test_context () >>=? fun ctxt -> (* pair nat nat *) test_unparse_ty __LOC__ ctxt pair_nat_nat_prim pair_nat_nat_ty >>?= fun ctxt -> (* pair (pair nat nat) nat *) - pair_ty pair_nat_nat_ty nat_ty >>??= fun pair_pair_nat_nat_nat_ty -> + pair_ty pair_nat_nat_ty nat_ty >>??= fun (Ty_ex_c pair_pair_nat_nat_nat_ty) -> test_unparse_ty __LOC__ ctxt @@ -280,7 +282,7 @@ let test_unparse_comb_type () = pair_pair_nat_nat_nat_ty >>?= fun ctxt -> (* pair nat nat nat *) - pair_ty nat_ty pair_nat_nat_ty >>??= fun pair_nat_nat_nat_ty -> + pair_ty nat_ty pair_nat_nat_ty >>??= fun (Ty_ex_c pair_nat_nat_nat_ty) -> test_unparse_ty __LOC__ ctxt @@ -373,7 +375,7 @@ let test_parse_comb_data () = let nat_ty = nat_t in let pair_prim l = Prim (-1, D_Pair, l, []) in let pair_ty ty1 ty2 = pair_t (-1) ty1 ty2 in - pair_ty nat_ty nat_ty >>??= fun pair_nat_nat_ty -> + pair_ty nat_ty nat_ty >>??= fun (Ty_ex_c pair_nat_nat_ty) -> let pair_prim2 a b = pair_prim [a; b] in let pair_z_z_prim = pair_prim2 z_prim z_prim in list_t (-1) nat_ty >>??= fun list_nat_ty -> @@ -391,7 +393,7 @@ let test_parse_comb_data () = (z, z) >>=? fun ctxt -> (* Pair (Pair 0 0) 0 *) - pair_ty pair_nat_nat_ty nat_ty >>??= fun pair_pair_nat_nat_nat_ty -> + pair_ty pair_nat_nat_ty nat_ty >>??= fun (Ty_ex_c pair_pair_nat_nat_nat_ty) -> test_parse_data __LOC__ ctxt @@ -400,7 +402,7 @@ let test_parse_comb_data () = ((z, z), z) >>=? fun ctxt -> (* Pair 0 (Pair 0 0) *) - pair_ty nat_ty pair_nat_nat_ty >>??= fun pair_nat_pair_nat_nat_ty -> + pair_ty nat_ty pair_nat_nat_ty >>??= fun (Ty_ex_c pair_nat_pair_nat_nat_ty) -> test_parse_data __LOC__ ctxt @@ -425,7 +427,7 @@ let test_parse_comb_data () = (z, (z, z)) >>=? fun ctxt -> (* Should fail: {0} against pair nat (list nat) *) - pair_ty nat_ty list_nat_ty >>??= fun pair_nat_list_nat_ty -> + pair_ty nat_ty list_nat_ty >>??= fun (Ty_ex_c pair_nat_list_nat_ty) -> test_parse_data_fails __LOC__ ctxt @@ -461,7 +463,8 @@ let test_parse_comb_data () = && Big_map_overlay.bindings big_map1.diff.map = Big_map_overlay.bindings big_map2.diff.map in - pair_ty nat_ty big_map_nat_nat_ty >>??= fun pair_nat_big_map_nat_nat_ty -> + pair_ty nat_ty big_map_nat_nat_ty + >>??= fun (Ty_ex_c pair_nat_big_map_nat_nat_ty) -> test_parse_data ~equal __LOC__ @@ -523,7 +526,7 @@ let test_unparse_comb_data () = let nat_ty = nat_t in let pair_prim l = Prim (-1, D_Pair, l, []) in let pair_ty ty1 ty2 = pair_t (-1) ty1 ty2 in - pair_ty nat_ty nat_ty >>??= fun pair_nat_nat_ty -> + pair_ty nat_ty nat_ty >>??= fun (Ty_ex_c pair_nat_nat_ty) -> let pair_prim2 a b = pair_prim [a; b] in let pair_z_z_prim = pair_prim2 z_prim z_prim in test_context () >>=? fun ctxt -> @@ -537,7 +540,7 @@ let test_unparse_comb_data () = ~expected_optimized:pair_z_z_prim >>=? fun ctxt -> (* Pair (Pair 0 0) 0 *) - pair_ty pair_nat_nat_ty nat_ty >>??= fun pair_pair_nat_nat_nat_ty -> + pair_ty pair_nat_nat_ty nat_ty >>??= fun (Ty_ex_c pair_pair_nat_nat_nat_ty) -> test_unparse_data __LOC__ ctxt @@ -547,7 +550,7 @@ let test_unparse_comb_data () = ~expected_optimized:(pair_prim2 pair_z_z_prim z_prim) >>=? fun ctxt -> (* Readable: Pair 0 0 0; Optimized: Pair 0 (Pair 0 0) *) - pair_ty nat_ty pair_nat_nat_ty >>??= fun pair_nat_pair_nat_nat_ty -> + pair_ty nat_ty pair_nat_nat_ty >>??= fun (Ty_ex_c pair_nat_pair_nat_nat_ty) -> test_unparse_data __LOC__ ctxt @@ -558,7 +561,7 @@ let test_unparse_comb_data () = >>=? fun ctxt -> (* Readable: Pair 0 0 0 0; Optimized: {0; 0; 0; 0} *) pair_ty nat_ty pair_nat_pair_nat_nat_ty - >>??= fun pair_nat_pair_nat_pair_nat_nat_ty -> + >>??= fun (Ty_ex_c pair_nat_pair_nat_pair_nat_nat_ty) -> test_unparse_data __LOC__ ctxt @@ -631,16 +634,16 @@ let test_optimal_comb () = in let pair_ty ty1 ty2 = pair_t (-1) ty1 ty2 in test_context () >>=? fun ctxt -> - pair_ty leaf_ty leaf_ty >>??= fun comb2_ty -> + pair_ty leaf_ty leaf_ty >>??= fun (Ty_ex_c comb2_ty) -> let comb2_v = (leaf_v, leaf_v) in check_optimal_comb __LOC__ ctxt comb2_ty comb2_v 2 >>=? fun ctxt -> - pair_ty leaf_ty comb2_ty >>??= fun comb3_ty -> + pair_ty leaf_ty comb2_ty >>??= fun (Ty_ex_c comb3_ty) -> let comb3_v = (leaf_v, comb2_v) in check_optimal_comb __LOC__ ctxt comb3_ty comb3_v 3 >>=? fun ctxt -> - pair_ty leaf_ty comb3_ty >>??= fun comb4_ty -> + pair_ty leaf_ty comb3_ty >>??= fun (Ty_ex_c comb4_ty) -> let comb4_v = (leaf_v, comb3_v) in check_optimal_comb __LOC__ ctxt comb4_ty comb4_v 4 >>=? fun ctxt -> - pair_ty leaf_ty comb4_ty >>??= fun comb5_ty -> + pair_ty leaf_ty comb4_ty >>??= fun (Ty_ex_c comb5_ty) -> let comb5_v = (leaf_v, comb4_v) in check_optimal_comb __LOC__ ctxt comb5_ty comb5_v 5 >>=? fun _ctxt -> return_unit From 780036ab9bf23085eb79ae49f69851de2ba5bd3e Mon Sep 17 00:00:00 2001 From: Mehdi Bouaziz Date: Sat, 26 Feb 2022 09:58:30 +0100 Subject: [PATCH 018/100] Proto/Michelson: add a 4th parameter to Pair_t constructor To be replaced in a later commit --- .../lib_benchmark/michelson_samplers.ml | 2 +- .../lib_benchmark/test/test_distribution.ml | 2 +- src/proto_alpha/lib_plugin/plugin.ml | 2 +- .../lib_protocol/script_interpreter_defs.ml | 4 +- .../lib_protocol/script_ir_translator.ml | 56 ++++++++++--------- .../lib_protocol/script_typed_ir.ml | 27 ++++++--- .../lib_protocol/script_typed_ir.mli | 6 +- .../lib_protocol/script_typed_ir_size.ml | 6 +- .../lib_protocol/ticket_scanner.ml | 4 +- 9 files changed, 62 insertions(+), 47 deletions(-) diff --git a/src/proto_alpha/lib_benchmark/michelson_samplers.ml b/src/proto_alpha/lib_benchmark/michelson_samplers.ml index a19d6db445..a77cb57a98 100644 --- a/src/proto_alpha/lib_benchmark/michelson_samplers.ml +++ b/src/proto_alpha/lib_benchmark/michelson_samplers.ml @@ -556,7 +556,7 @@ end) | Bool_t -> Base_samplers.uniform_bool | Address_t -> address | Tx_rollup_l2_address_t -> tx_rollup_l2_address - | Pair_t (left_t, right_t, _) -> + | Pair_t (left_t, right_t, _, _) -> M.( let* left_v = value left_t in let* right_v = value right_t in diff --git a/src/proto_alpha/lib_benchmark/test/test_distribution.ml b/src/proto_alpha/lib_benchmark/test/test_distribution.ml index 9253c16d39..2df11c3545 100644 --- a/src/proto_alpha/lib_benchmark/test/test_distribution.ml +++ b/src/proto_alpha/lib_benchmark/test/test_distribution.ml @@ -71,7 +71,7 @@ let rec tnames_of_type : | Script_typed_ir.Address_t -> `TAddress :: acc | Script_typed_ir.Tx_rollup_l2_address_t -> `TTx_rollup_l2_address :: acc | Script_typed_ir.Bool_t -> `TBool :: acc - | Script_typed_ir.Pair_t (lty, rty, _) -> + | Script_typed_ir.Pair_t (lty, rty, _, _) -> tnames_of_type lty (tnames_of_type rty (`TPair :: acc)) | Script_typed_ir.Union_t (lty, rty, _) -> tnames_of_type lty (tnames_of_type rty (`TUnion :: acc)) diff --git a/src/proto_alpha/lib_plugin/plugin.ml b/src/proto_alpha/lib_plugin/plugin.ml index 8667af203e..fe0f590b54 100644 --- a/src/proto_alpha/lib_plugin/plugin.ml +++ b/src/proto_alpha/lib_plugin/plugin.ml @@ -2043,7 +2043,7 @@ module RPC = struct | Contract_t (ut, _meta) -> let t = unparse_ty ~loc ut in return (T_contract, [t], []) - | Pair_t (utl, utr, _meta) -> + | Pair_t (utl, utr, _meta, _) -> let annot = [] in let tl = unparse_ty ~loc utl in let tr = unparse_ty ~loc utr in diff --git a/src/proto_alpha/lib_protocol/script_interpreter_defs.ml b/src/proto_alpha/lib_protocol/script_interpreter_defs.ml index 2bd9dbf35d..3a0e161d00 100644 --- a/src/proto_alpha/lib_protocol/script_interpreter_defs.ml +++ b/src/proto_alpha/lib_protocol/script_interpreter_defs.ml @@ -469,7 +469,7 @@ let apply ctxt gas capture_ty capture lam = let loc = Micheline.dummy_location in unparse_ty ~loc ctxt capture_ty >>?= fun (ty_expr, ctxt) -> match full_arg_ty with - | Pair_t (capture_ty, arg_ty, _) -> + | Pair_t (capture_ty, arg_ty, _, _) -> let arg_stack_ty = Item_t (arg_ty, Bot_t) in let full_descr = { @@ -532,7 +532,7 @@ let transfer (ctxt, sc) gas amount location parameters_ty parameters destination | Tx_rollup _ -> ( let open Micheline in match tp with - | Pair_t (Ticket_t (tp, _), _, _) -> + | Pair_t (Ticket_t (tp, _), _, _, _) -> Script_ir_translator.unparse_comparable_ty ~loc:dummy_location ctxt diff --git a/src/proto_alpha/lib_protocol/script_ir_translator.ml b/src/proto_alpha/lib_protocol/script_ir_translator.ml index f923123e09..33b89b6163 100644 --- a/src/proto_alpha/lib_protocol/script_ir_translator.ml +++ b/src/proto_alpha/lib_protocol/script_ir_translator.ml @@ -178,7 +178,7 @@ let rec ty_of_comparable_ty : type a. a comparable_ty -> a ty = function | Tx_rollup_l2_address_key -> Tx_rollup_l2_address_t | Chain_id_key -> Chain_id_t | Pair_key (l, r, meta) -> - Pair_t (ty_of_comparable_ty l, ty_of_comparable_ty r, meta) + Pair_t (ty_of_comparable_ty l, ty_of_comparable_ty r, meta, ()) | Union_key (l, r, meta) -> Union_t (ty_of_comparable_ty l, ty_of_comparable_ty r, meta) | Option_key (t, meta) -> Option_t (ty_of_comparable_ty t, meta) @@ -248,7 +248,7 @@ let rec unparse_ty_entrypoints_uncarbonated : | Contract_t (ut, _meta) -> let t = unparse_ty_entrypoints_uncarbonated ~loc ut no_entrypoints in (T_contract, [t]) - | Pair_t (utl, utr, _meta) -> ( + | Pair_t (utl, utr, _meta, _) -> ( let tl = unparse_ty_entrypoints_uncarbonated ~loc utl no_entrypoints in let tr = unparse_ty_entrypoints_uncarbonated ~loc utr no_entrypoints in (* Fold [pair a1 (pair ... (pair an-1 an))] into [pair a1 ... an] *) @@ -352,7 +352,7 @@ let[@coq_axiom_with_reason "gadt"] rec comparable_ty_of_ty : | Address_t -> ok (Address_key, ctxt) | Tx_rollup_l2_address_t -> ok (Tx_rollup_l2_address_key, ctxt) | Chain_id_t -> ok (Chain_id_key, ctxt) - | Pair_t (l, r, pname) -> + | Pair_t (l, r, pname, _) -> comparable_ty_of_ty ctxt loc l >>? fun (lty, ctxt) -> comparable_ty_of_ty ctxt loc r >|? fun (rty, ctxt) -> (Pair_key (lty, rty, pname), ctxt) @@ -706,7 +706,7 @@ let check_dupable_ty ctxt loc ty = | Chest_t -> return_unit | Chest_key_t -> return_unit | Ticket_t _ -> fail @@ Unexpected_ticket loc - | Pair_t (ty_a, ty_b, _) -> + | Pair_t (ty_a, ty_b, _, _) -> let* () = aux loc ty_a in aux loc ty_b | Union_t (ty_a, ty_b, _) -> @@ -951,7 +951,7 @@ let ty_eq : let+ Eq = comparable_ty_eq ~error_details ea eb in (Eq : (ta ty, tb ty) eq) | (Ticket_t _, _) -> not_equal () - | (Pair_t (tal, tar, meta1), Pair_t (tbl, tbr, meta2)) -> + | (Pair_t (tal, tar, meta1, _), Pair_t (tbl, tbr, meta2, _)) -> let* () = type_metadata_eq meta1 meta2 in let* Eq = help tal tbl in let+ Eq = help tar tbr in @@ -1753,7 +1753,7 @@ let check_packable ~legacy loc root = | Bls12_381_g1_t -> Result.return_unit | Bls12_381_g2_t -> Result.return_unit | Bls12_381_fr_t -> Result.return_unit - | Pair_t (l_ty, r_ty, _) -> check l_ty >>? fun () -> check r_ty + | Pair_t (l_ty, r_ty, _, _) -> check l_ty >>? fun () -> check r_ty | Union_t (l_ty, r_ty, _) -> check l_ty >>? fun () -> check r_ty | Option_t (v_ty, _) -> check v_ty | List_t (elt_ty, _) -> check elt_ty @@ -1885,9 +1885,9 @@ let rec make_comb_get_proof_argument : fun n ty -> match (n, ty) with | (0, value_ty) -> Some (Comb_get_proof_argument (Comb_get_zero, value_ty)) - | (1, Pair_t (hd_ty, _, _annot)) -> + | (1, Pair_t (hd_ty, _, _annot, _)) -> Some (Comb_get_proof_argument (Comb_get_one, hd_ty)) - | (n, Pair_t (_, tl_ty, _annot)) -> + | (n, Pair_t (_, tl_ty, _annot, _)) -> make_comb_get_proof_argument (n - 2) tl_ty |> Option.map @@ fun (Comb_get_proof_argument (comb_get_left_witness, ty')) -> @@ -1906,10 +1906,10 @@ let rec make_comb_set_proof_argument : fun ctxt stack_ty loc n value_ty ty -> match (n, ty) with | (0, _) -> ok @@ Comb_set_proof_argument (Comb_set_zero, value_ty) - | (1, Pair_t (_hd_ty, tl_ty, _)) -> + | (1, Pair_t (_hd_ty, tl_ty, _, _)) -> pair_t loc value_ty tl_ty >|? fun (Ty_ex_c after_ty) -> Comb_set_proof_argument (Comb_set_one, after_ty) - | (n, Pair_t (hd_ty, tl_ty, _)) -> + | (n, Pair_t (hd_ty, tl_ty, _, _)) -> make_comb_set_proof_argument ctxt stack_ty loc (n - 2) value_ty tl_ty >>? fun (Comb_set_proof_argument (comb_set_left_witness, tl_ty')) -> pair_t loc hd_ty tl_ty' >|? fun (Ty_ex_c after_ty) -> @@ -2679,7 +2679,7 @@ let[@coq_axiom_with_reason "gadt"] rec parse_data : ~entrypoint:address.entrypoint >|=? fun (ctxt, _) -> (Typed_contract {arg_ty; address}, ctxt) ) (* Pairs *) - | (Pair_t (tl, tr, _), expr) -> + | (Pair_t (tl, tr, _, _), expr) -> let r_witness = comb_witness1 tr in let parse_l ctxt v = non_terminal_recursion ?type_logger ctxt ~legacy tl v @@ -3365,7 +3365,7 @@ and[@coq_axiom_with_reason "gadt"] parse_instr : fun n stack_ty -> match (n, stack_ty) with | (1, stack) -> ok @@ Uncomb_proof_argument (Uncomb_one, stack) - | (n, Item_t (Pair_t (a_ty, b_ty, _), tl_ty)) -> + | (n, Item_t (Pair_t (a_ty, b_ty, _, _), tl_ty)) -> make_proof_argument (n - 1) (Item_t (b_ty, tl_ty)) >|? fun (Uncomb_proof_argument (uncomb_witness, after_ty)) -> Uncomb_proof_argument @@ -3408,15 +3408,15 @@ and[@coq_axiom_with_reason "gadt"] parse_instr : {apply = (fun kinfo k -> IComb_set (kinfo, n, witness, k))} in typed ctxt loc comb_set after_stack_ty - | (Prim (loc, I_UNPAIR, [], annot), Item_t (Pair_t (a, b, _), rest)) -> + | (Prim (loc, I_UNPAIR, [], annot), Item_t (Pair_t (a, b, _, _), rest)) -> check_unpair_annot loc annot >>?= fun () -> let unpair = {apply = (fun kinfo k -> IUnpair (kinfo, k))} in typed ctxt loc unpair (Item_t (a, Item_t (b, rest))) - | (Prim (loc, I_CAR, [], annot), Item_t (Pair_t (a, _, _), rest)) -> + | (Prim (loc, I_CAR, [], annot), Item_t (Pair_t (a, _, _, _), rest)) -> check_destr_annot loc annot >>?= fun () -> let car = {apply = (fun kinfo k -> ICar (kinfo, k))} in typed ctxt loc car (Item_t (a, rest)) - | (Prim (loc, I_CDR, [], annot), Item_t (Pair_t (_, b, _), rest)) -> + | (Prim (loc, I_CDR, [], annot), Item_t (Pair_t (_, b, _, _), rest)) -> check_destr_annot loc annot >>?= fun () -> let cdr = {apply = (fun kinfo k -> ICdr (kinfo, k))} in typed ctxt loc cdr (Item_t (b, rest)) @@ -4063,8 +4063,8 @@ and[@coq_axiom_with_reason "gadt"] parse_instr : | ( Prim (loc, I_APPLY, [], annot), Item_t ( capture, - Item_t (Lambda_t (Pair_t (capture_ty, arg_ty, _), ret, _), rest) ) ) - -> + Item_t (Lambda_t (Pair_t (capture_ty, arg_ty, _, _), ret, _), rest) ) + ) -> check_packable ~legacy:false loc capture_ty >>?= fun () -> check_item_ty ctxt capture capture_ty loc I_APPLY 1 2 >>?= fun (Eq, ctxt) -> @@ -4831,7 +4831,8 @@ and[@coq_axiom_with_reason "gadt"] parse_instr : let instr = {apply = (fun kinfo k -> INeg_bls12_381_fr (kinfo, k))} in typed ctxt loc instr stack | ( Prim (loc, I_PAIRING_CHECK, [], annot), - Item_t (List_t (Pair_t (Bls12_381_g1_t, Bls12_381_g2_t, _), _), rest) ) -> + Item_t (List_t (Pair_t (Bls12_381_g1_t, Bls12_381_g2_t, _, _), _), rest) + ) -> check_var_annot loc annot >>?= fun () -> let instr = {apply = (fun kinfo k -> IPairing_check_bls12_381 (kinfo, k))} @@ -4857,8 +4858,8 @@ and[@coq_axiom_with_reason "gadt"] parse_instr : typed ctxt loc instr stack | ( Prim (loc, I_SPLIT_TICKET, [], annot), Item_t - ((Ticket_t (t, _) as ticket_t), Item_t (Pair_t (Nat_t, Nat_t, _), rest)) - ) -> + ( (Ticket_t (t, _) as ticket_t), + Item_t (Pair_t (Nat_t, Nat_t, _, _), rest) ) ) -> check_var_annot loc annot >>?= fun () -> let () = check_dupable_comparable_ty t in pair_t loc ticket_t ticket_t >>?= fun (Ty_ex_c pair_tickets_ty) -> @@ -4871,6 +4872,7 @@ and[@coq_axiom_with_reason "gadt"] parse_instr : ( Pair_t ( (Ticket_t (contents_ty_a, _) as ty_a), Ticket_t (contents_ty_b, _), + _, _ ), rest ) ) -> check_var_annot loc annot >>?= fun () -> @@ -5159,7 +5161,7 @@ and[@coq_axiom_with_reason "complex mutually recursive definition"] parse_contra (* /!\ This pattern matching needs to remain in sync with [parse_contract] and [parse_tx_rollup_deposit_parameters]. *) match arg with - | Pair_t (Ticket_t (_, _), Tx_rollup_l2_address_t, _) -> + | Pair_t (Ticket_t (_, _), Tx_rollup_l2_address_t, _, _) -> let address = {destination; entrypoint} in return (ctxt, Typed_contract {arg_ty = arg; address}) | _ -> @@ -5368,7 +5370,7 @@ let parse_contract_for_script : [parse_contract_for_script] and [parse_tx_rollup_deposit_parameters]. *) match arg with - | Pair_t (Ticket_t (_, _), Tx_rollup_l2_address_t, _) + | Pair_t (Ticket_t (_, _), Tx_rollup_l2_address_t, _, _) when Entrypoint.( entrypoint = Alpha_context.Tx_rollup.deposit_entrypoint) -> ( Tx_rollup_state.find ctxt tx_rollup >|=? function @@ -5610,7 +5612,7 @@ let list_entrypoints ctxt (type full) (full : full ty) let comb_witness2 : type t. t ty -> (t, unit -> unit -> unit) comb_witness = function - | Pair_t (_, Pair_t _, _) -> Comb_Pair (Comb_Pair Comb_Any) + | Pair_t (_, Pair_t _, _, _) -> Comb_Pair (Comb_Pair Comb_Any) | Pair_t _ -> Comb_Pair Comb_Any | _ -> Comb_Any @@ -5654,7 +5656,7 @@ let[@coq_axiom_with_reason "gadt"] rec unparse_data : | (Bls12_381_g1_t, x) -> Lwt.return @@ unparse_bls12_381_g1 ~loc ctxt x | (Bls12_381_g2_t, x) -> Lwt.return @@ unparse_bls12_381_g2 ~loc ctxt x | (Bls12_381_fr_t, x) -> Lwt.return @@ unparse_bls12_381_fr ~loc ctxt x - | (Pair_t (tl, tr, _), pair) -> + | (Pair_t (tl, tr, _, _), pair) -> let r_witness = comb_witness2 tr in let unparse_l ctxt v = non_terminal_recursion ctxt mode tl v in let unparse_r ctxt v = non_terminal_recursion ctxt mode tr v in @@ -6152,7 +6154,7 @@ let rec has_lazy_storage : type t. t ty -> t has_lazy_storage = | Ticket_t _ -> False_f | Chest_key_t -> False_f | Chest_t -> False_f - | Pair_t (l, r, _) -> aux2 (fun l r -> Pair_f (l, r)) l r + | Pair_t (l, r, _, _) -> aux2 (fun l r -> Pair_f (l, r)) l r | Union_t (l, r, _) -> aux2 (fun l r -> Union_f (l, r)) l r | Option_t (t, _) -> aux1 (fun h -> Option_f h) t | List_t (t, _) -> aux1 (fun h -> List_f h) t @@ -6207,7 +6209,7 @@ let[@coq_axiom_with_reason "gadt"] extract_lazy_storage_updates ctxt mode let diff = Lazy_storage.make Sapling_state id diff in let ids_to_copy = Lazy_storage.IdSet.add Sapling_state id ids_to_copy in (ctxt, sapling_state, ids_to_copy, diff :: acc) - | (Pair_f (hl, hr), Pair_t (tyl, tyr, _), (xl, xr)) -> + | (Pair_f (hl, hr), Pair_t (tyl, tyr, _, _), (xl, xr)) -> aux ctxt mode ~temporary ids_to_copy acc tyl xl ~has_lazy_storage:hl >>=? fun (ctxt, xl, ids_to_copy, acc) -> aux ctxt mode ~temporary ids_to_copy acc tyr xr ~has_lazy_storage:hr @@ -6301,7 +6303,7 @@ let[@coq_axiom_with_reason "gadt"] rec fold_lazy_storage : ok (Fold_lazy_storage.Ok init, ctxt) | (Sapling_state_f, Sapling_state_t _, {id = None; _}) -> ok (Fold_lazy_storage.Ok init, ctxt) - | (Pair_f (hl, hr), Pair_t (tyl, tyr, _), (xl, xr)) -> ( + | (Pair_f (hl, hr), Pair_t (tyl, tyr, _, _), (xl, xr)) -> ( fold_lazy_storage ~f ~init ctxt tyl xl ~has_lazy_storage:hl >>? fun (init, ctxt) -> match init with diff --git a/src/proto_alpha/lib_protocol/script_typed_ir.ml b/src/proto_alpha/lib_protocol/script_typed_ir.ml index 07d0f2ac52..3593f71138 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir.ml +++ b/src/proto_alpha/lib_protocol/script_typed_ir.ml @@ -1223,6 +1223,8 @@ and logger = { get_log : unit -> execution_trace option tzresult Lwt.t; } +and to_be_replaced = unit + (* ---- Auxiliary types -----------------------------------------------------*) and 'ty ty = | Unit_t : unit ty @@ -1238,7 +1240,9 @@ and 'ty ty = | Address_t : address ty | Tx_rollup_l2_address_t : tx_rollup_l2_address ty | Bool_t : bool ty - | Pair_t : 'a ty * 'b ty * ('a, 'b) pair ty_metadata -> ('a, 'b) pair ty + | Pair_t : + 'a ty * 'b ty * ('a, 'b) pair ty_metadata * to_be_replaced + -> ('a, 'b) pair ty | Union_t : 'a ty * 'b ty * ('a, 'b) union ty_metadata -> ('a, 'b) union ty | Lambda_t : 'arg ty * 'ret ty * ('arg, 'ret) lambda ty_metadata @@ -1765,7 +1769,7 @@ let ty_metadata : type a. a ty -> a ty_metadata = function | Mutez_t | Bool_t | Key_hash_t | Key_t | Timestamp_t | Chain_id_t | Address_t | Tx_rollup_l2_address_t -> meta_basic - | Pair_t (_, _, meta) -> meta + | Pair_t (_, _, meta, _) -> meta | Union_t (_, _, meta) -> meta | Option_t (_, meta) -> meta | Lambda_t (_, _, meta) -> meta @@ -1849,7 +1853,7 @@ let tx_rollup_l2_address_key = Tx_rollup_l2_address_key let pair_t loc l r = Type_size.compound2 loc (ty_size l) (ty_size r) >|? fun size -> - Ty_ex_c (Pair_t (l, r, {size})) + Ty_ex_c (Pair_t (l, r, {size}, ())) let pair_key loc l r = Type_size.compound2 loc (comparable_ty_size l) (comparable_ty_size r) @@ -1884,20 +1888,23 @@ let option_nat_t = Option_t (nat_t, {size = Type_size.two}) let option_pair_nat_nat_t = Option_t - (Pair_t (nat_t, nat_t, {size = Type_size.three}), {size = Type_size.four}) + ( Pair_t (nat_t, nat_t, {size = Type_size.three}, ()), + {size = Type_size.four} ) let option_pair_nat_mutez_t = Option_t - (Pair_t (nat_t, mutez_t, {size = Type_size.three}), {size = Type_size.four}) + ( Pair_t (nat_t, mutez_t, {size = Type_size.three}, ()), + {size = Type_size.four} ) let option_pair_mutez_mutez_t = Option_t - ( Pair_t (mutez_t, mutez_t, {size = Type_size.three}), + ( Pair_t (mutez_t, mutez_t, {size = Type_size.three}, ()), {size = Type_size.four} ) let option_pair_int_nat_t = Option_t - (Pair_t (int_t, nat_t, {size = Type_size.three}), {size = Type_size.four}) + ( Pair_t (int_t, nat_t, {size = Type_size.three}, ()), + {size = Type_size.four} ) let option_key loc t = Type_size.compound1 loc (comparable_ty_size t) >|? fun size -> @@ -2188,7 +2195,8 @@ let (ty_traverse, comparable_ty_traverse) = (continue [@ocaml.tailcall]) accu | Ticket_t (cty, _) -> aux f accu cty continue | Chest_key_t | Chest_t -> (continue [@ocaml.tailcall]) accu - | Pair_t (ty1, ty2, _) -> (next2' [@ocaml.tailcall]) f accu ty1 ty2 continue + | Pair_t (ty1, ty2, _, _) -> + (next2' [@ocaml.tailcall]) f accu ty1 ty2 continue | Union_t (ty1, ty2, _) -> (next2' [@ocaml.tailcall]) f accu ty1 ty2 continue | Lambda_t (ty1, ty2, _) -> @@ -2267,7 +2275,8 @@ let value_traverse (type t) (ty : (t ty, t comparable_ty) union) (x : t) init f | Bls12_381_g2_t | Bls12_381_fr_t | Chest_key_t | Chest_t | Lambda_t (_, _, _) -> (return [@ocaml.tailcall]) () - | Pair_t (ty1, ty2, _) -> (next2 [@ocaml.tailcall]) ty1 ty2 (fst x) (snd x) + | Pair_t (ty1, ty2, _, _) -> + (next2 [@ocaml.tailcall]) ty1 ty2 (fst x) (snd x) | Union_t (ty1, ty2, _) -> ( match x with | L l -> (next [@ocaml.tailcall]) ty1 l diff --git a/src/proto_alpha/lib_protocol/script_typed_ir.mli b/src/proto_alpha/lib_protocol/script_typed_ir.mli index a983ed4911..cb63877d67 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir.mli +++ b/src/proto_alpha/lib_protocol/script_typed_ir.mli @@ -1327,6 +1327,8 @@ and logger = { produced. *) } +and to_be_replaced = unit + (* ---- Auxiliary types -----------------------------------------------------*) and 'ty ty = | Unit_t : unit ty @@ -1342,7 +1344,9 @@ and 'ty ty = | Address_t : address ty | Tx_rollup_l2_address_t : tx_rollup_l2_address ty | Bool_t : bool ty - | Pair_t : 'a ty * 'b ty * ('a, 'b) pair ty_metadata -> ('a, 'b) pair ty + | Pair_t : + 'a ty * 'b ty * ('a, 'b) pair ty_metadata * to_be_replaced + -> ('a, 'b) pair ty | Union_t : 'a ty * 'b ty * ('a, 'b) union ty_metadata -> ('a, 'b) union ty | Lambda_t : 'arg ty * 'ret ty * ('arg, 'ret) lambda ty_metadata diff --git a/src/proto_alpha/lib_protocol/script_typed_ir_size.ml b/src/proto_alpha/lib_protocol/script_typed_ir_size.ml index 2555e15858..70a6a66cd2 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir_size.ml +++ b/src/proto_alpha/lib_protocol/script_typed_ir_size.ml @@ -90,8 +90,8 @@ let ty_traverse_f = | Bls12_381_fr_t -> ret_succ_adding accu base_basic | Chest_key_t -> ret_succ_adding accu base_basic | Chest_t -> ret_succ_adding accu base_basic - | Pair_t (_ty1, _ty2, a) -> - ret_succ_adding accu @@ (base_compound a +! (word_size *? 2)) + | Pair_t (_ty1, _ty2, a, _) -> + ret_succ_adding accu @@ (base_compound a +! (word_size *? 3)) | Union_t (_ty1, _ty2, a) -> ret_succ_adding accu @@ (base_compound a +! (word_size *? 2)) | Lambda_t (_ty1, _ty2, a) -> @@ -285,7 +285,7 @@ let rec value_size : | Tx_rollup_l2_address_t -> ret_succ_adding accu (tx_rollup_l2_address_size x) | Bool_t -> ret_succ accu - | Pair_t (_, _, _) -> ret_succ_adding accu h2w + | Pair_t (_, _, _, _) -> ret_succ_adding accu h2w | Union_t (_, _, _) -> ret_succ_adding accu h1w | Lambda_t (_, _, _) -> (lambda_size [@ocaml.tailcall]) ~count_lambda_nodes (ret_succ accu) x diff --git a/src/proto_alpha/lib_protocol/ticket_scanner.ml b/src/proto_alpha/lib_protocol/ticket_scanner.ml index e533549b8c..e65c22c4bb 100644 --- a/src/proto_alpha/lib_protocol/ticket_scanner.ml +++ b/src/proto_alpha/lib_protocol/ticket_scanner.ml @@ -163,7 +163,7 @@ module Ticket_inspection = struct | Address_t -> (k [@ocaml.tailcall]) False_ht | Tx_rollup_l2_address_t -> (k [@ocaml.tailcall]) False_ht | Bool_t -> (k [@ocaml.tailcall]) False_ht - | Pair_t (ty1, ty2, _) -> + | Pair_t (ty1, ty2, _, _) -> (has_tickets_of_pair [@ocaml.tailcall]) ty1 ty2 @@ -322,7 +322,7 @@ module Ticket_collection = struct consume_gas_steps ctxt ~num_steps:1 >>?= fun ctxt -> match (hty, ty) with | (False_ht, _) -> (k [@ocaml.tailcall]) ctxt acc - | (Pair_ht (hty1, hty2), Pair_t (ty1, ty2, _)) -> + | (Pair_ht (hty1, hty2), Pair_t (ty1, ty2, _, _)) -> let (l, r) = x in (tickets_of_value [@ocaml.tailcall]) ~include_lazy From e118125eebab8061f8c103a3f55c6163c6a731f2 Mon Sep 17 00:00:00 2001 From: Mehdi Bouaziz Date: Sat, 26 Feb 2022 09:58:30 +0100 Subject: [PATCH 019/100] Proto/Michelson: add a 4th parameter to Union_t constructor To be replaced in a later commit --- .../lib_benchmark/michelson_samplers.ml | 2 +- .../lib_benchmark/test/test_distribution.ml | 2 +- src/proto_alpha/lib_plugin/plugin.ml | 2 +- .../lib_protocol/script_ir_translator.ml | 37 ++++++++++--------- .../lib_protocol/script_typed_ir.ml | 14 ++++--- .../lib_protocol/script_typed_ir.mli | 4 +- .../lib_protocol/script_typed_ir_size.ml | 6 +-- .../lib_protocol/ticket_scanner.ml | 4 +- 8 files changed, 38 insertions(+), 33 deletions(-) diff --git a/src/proto_alpha/lib_benchmark/michelson_samplers.ml b/src/proto_alpha/lib_benchmark/michelson_samplers.ml index a77cb57a98..b2edb5ae1d 100644 --- a/src/proto_alpha/lib_benchmark/michelson_samplers.ml +++ b/src/proto_alpha/lib_benchmark/michelson_samplers.ml @@ -561,7 +561,7 @@ end) let* left_v = value left_t in let* right_v = value right_t in return (left_v, right_v)) - | Union_t (left_t, right_t, _) -> + | Union_t (left_t, right_t, _, _) -> fun rng_state -> if Base_samplers.uniform_bool rng_state then L (value left_t rng_state) diff --git a/src/proto_alpha/lib_benchmark/test/test_distribution.ml b/src/proto_alpha/lib_benchmark/test/test_distribution.ml index 2df11c3545..ce45865956 100644 --- a/src/proto_alpha/lib_benchmark/test/test_distribution.ml +++ b/src/proto_alpha/lib_benchmark/test/test_distribution.ml @@ -73,7 +73,7 @@ let rec tnames_of_type : | Script_typed_ir.Bool_t -> `TBool :: acc | Script_typed_ir.Pair_t (lty, rty, _, _) -> tnames_of_type lty (tnames_of_type rty (`TPair :: acc)) - | Script_typed_ir.Union_t (lty, rty, _) -> + | Script_typed_ir.Union_t (lty, rty, _, _) -> tnames_of_type lty (tnames_of_type rty (`TUnion :: acc)) | Script_typed_ir.Lambda_t (dom, range, _) -> tnames_of_type dom (tnames_of_type range (`TLambda :: acc)) diff --git a/src/proto_alpha/lib_plugin/plugin.ml b/src/proto_alpha/lib_plugin/plugin.ml index fe0f590b54..77d52f60a5 100644 --- a/src/proto_alpha/lib_plugin/plugin.ml +++ b/src/proto_alpha/lib_plugin/plugin.ml @@ -2048,7 +2048,7 @@ module RPC = struct let tl = unparse_ty ~loc utl in let tr = unparse_ty ~loc utr in return (T_pair, [tl; tr], annot) - | Union_t (utl, utr, _meta) -> + | Union_t (utl, utr, _meta, _) -> let annot = [] in let tl = unparse_ty ~loc utl in let tr = unparse_ty ~loc utr in diff --git a/src/proto_alpha/lib_protocol/script_ir_translator.ml b/src/proto_alpha/lib_protocol/script_ir_translator.ml index 33b89b6163..9665644323 100644 --- a/src/proto_alpha/lib_protocol/script_ir_translator.ml +++ b/src/proto_alpha/lib_protocol/script_ir_translator.ml @@ -180,7 +180,7 @@ let rec ty_of_comparable_ty : type a. a comparable_ty -> a ty = function | Pair_key (l, r, meta) -> Pair_t (ty_of_comparable_ty l, ty_of_comparable_ty r, meta, ()) | Union_key (l, r, meta) -> - Union_t (ty_of_comparable_ty l, ty_of_comparable_ty r, meta) + Union_t (ty_of_comparable_ty l, ty_of_comparable_ty r, meta, ()) | Option_key (t, meta) -> Option_t (ty_of_comparable_ty t, meta) let rec unparse_comparable_ty_uncarbonated : @@ -257,7 +257,7 @@ let rec unparse_ty_entrypoints_uncarbonated : match tr with | Prim (_, T_pair, ts, []) -> (T_pair, tl :: ts) | _ -> (T_pair, [tl; tr])) - | Union_t (utl, utr, _meta) -> + | Union_t (utl, utr, _meta, _) -> let (entrypoints_l, entrypoints_r) = match nested_entrypoints with | Entrypoints_None -> (no_entrypoints, no_entrypoints) @@ -356,7 +356,7 @@ let[@coq_axiom_with_reason "gadt"] rec comparable_ty_of_ty : comparable_ty_of_ty ctxt loc l >>? fun (lty, ctxt) -> comparable_ty_of_ty ctxt loc r >|? fun (rty, ctxt) -> (Pair_key (lty, rty, pname), ctxt) - | Union_t (l, r, meta) -> + | Union_t (l, r, meta, _) -> comparable_ty_of_ty ctxt loc l >>? fun (lty, ctxt) -> comparable_ty_of_ty ctxt loc r >|? fun (rty, ctxt) -> (Union_key (lty, rty, meta), ctxt) @@ -709,7 +709,7 @@ let check_dupable_ty ctxt loc ty = | Pair_t (ty_a, ty_b, _, _) -> let* () = aux loc ty_a in aux loc ty_b - | Union_t (ty_a, ty_b, _) -> + | Union_t (ty_a, ty_b, _, _) -> let* () = aux loc ty_a in aux loc ty_b | Lambda_t (_, _, _) -> @@ -957,7 +957,7 @@ let ty_eq : let+ Eq = help tar tbr in (Eq : (ta ty, tb ty) eq) | (Pair_t _, _) -> not_equal () - | (Union_t (tal, tar, meta1), Union_t (tbl, tbr, meta2)) -> + | (Union_t (tal, tar, meta1, _), Union_t (tbl, tbr, meta2, _)) -> let* () = type_metadata_eq meta1 meta2 in let* Eq = help tal tbl in let+ Eq = help tar tbr in @@ -1754,7 +1754,7 @@ let check_packable ~legacy loc root = | Bls12_381_g2_t -> Result.return_unit | Bls12_381_fr_t -> Result.return_unit | Pair_t (l_ty, r_ty, _, _) -> check l_ty >>? fun () -> check r_ty - | Union_t (l_ty, r_ty, _) -> check l_ty >>? fun () -> check r_ty + | Union_t (l_ty, r_ty, _, _) -> check l_ty >>? fun () -> check r_ty | Option_t (v_ty, _) -> check v_ty | List_t (elt_ty, _) -> check elt_ty | Map_t (_, elt_ty, _) -> check elt_ty @@ -1934,7 +1934,8 @@ let find_entrypoint (type full error_trace) match (ty, entrypoints) with | (_, {name = Some name; _}) when Entrypoint.(name = entrypoint) -> return (Ex_ty_cstr (ty, fun e -> e)) - | (Union_t (tl, tr, _), {nested = Entrypoints_Union {left; right}; _}) -> ( + | (Union_t (tl, tr, _, _), {nested = Entrypoints_Union {left; right}; _}) + -> ( Gas_monad.bind_recover (find_entrypoint tl left entrypoint) @@ function | Ok (Ex_ty_cstr (t, f)) -> return (Ex_ty_cstr (t, fun e -> L (f e))) | Error () -> @@ -2004,7 +2005,7 @@ let well_formed_entrypoints (type full) (full : full ty) entrypoints = (prim list option * Entrypoint.Set.t) tzresult = fun t entrypoints path reachable acc -> match (t, entrypoints) with - | (Union_t (tl, tr, _), {nested = Entrypoints_Union {left; right}; _}) -> + | (Union_t (tl, tr, _, _), {nested = Entrypoints_Union {left; right}; _}) -> merge (D_Left :: path) tl left reachable acc >>? fun (acc, l_reachable) -> merge (D_Right :: path) tr right reachable acc @@ -2689,7 +2690,7 @@ let[@coq_axiom_with_reason "gadt"] rec parse_data : in traced @@ parse_pair parse_l parse_r ctxt ~legacy r_witness expr (* Unions *) - | (Union_t (tl, tr, _), expr) -> + | (Union_t (tl, tr, _, _), expr) -> let parse_l ctxt v = non_terminal_recursion ?type_logger ctxt ~legacy tl v in @@ -3438,7 +3439,7 @@ and[@coq_axiom_with_reason "gadt"] parse_instr : let stack_ty = Item_t (ty, rest) in typed ctxt loc cons_right stack_ty | ( Prim (loc, I_IF_LEFT, [bt; bf], annot), - (Item_t (Union_t (tl, tr, _), rest) as bef) ) -> + (Item_t (Union_t (tl, tr, _, _), rest) as bef) ) -> check_kind [Seq_kind] bt >>?= fun () -> check_kind [Seq_kind] bf >>?= fun () -> error_unexpected_annot loc annot >>?= fun () -> @@ -3983,7 +3984,7 @@ and[@coq_axiom_with_reason "gadt"] parse_instr : in typed_no_lwt ctxt loc instr rest) | ( Prim (loc, I_LOOP_LEFT, [body], annot), - (Item_t (Union_t (tl, tr, _), rest) as stack) ) -> ( + (Item_t (Union_t (tl, tr, _, _), rest) as stack) ) -> ( check_kind [Seq_kind] body >>?= fun () -> check_var_annot loc annot >>?= fun () -> non_terminal_recursion @@ -5588,7 +5589,7 @@ let list_entrypoints ctxt (type full) (full : full ty) tzresult = fun t entrypoints path reachable acc -> match (t, entrypoints) with - | (Union_t (tl, tr, _), {nested = Entrypoints_Union {left; right}; _}) -> + | (Union_t (tl, tr, _, _), {nested = Entrypoints_Union {left; right}; _}) -> merge (D_Left :: path) tl left reachable acc >>? fun (acc, l_reachable) -> merge (D_Right :: path) tr right reachable acc @@ -5661,7 +5662,7 @@ let[@coq_axiom_with_reason "gadt"] rec unparse_data : let unparse_l ctxt v = non_terminal_recursion ctxt mode tl v in let unparse_r ctxt v = non_terminal_recursion ctxt mode tr v in unparse_pair ~loc unparse_l unparse_r ctxt mode r_witness pair - | (Union_t (tl, tr, _), v) -> + | (Union_t (tl, tr, _, _), v) -> let unparse_l ctxt v = non_terminal_recursion ctxt mode tl v in let unparse_r ctxt v = non_terminal_recursion ctxt mode tr v in unparse_union ~loc unparse_l unparse_r ctxt v @@ -6155,7 +6156,7 @@ let rec has_lazy_storage : type t. t ty -> t has_lazy_storage = | Chest_key_t -> False_f | Chest_t -> False_f | Pair_t (l, r, _, _) -> aux2 (fun l r -> Pair_f (l, r)) l r - | Union_t (l, r, _) -> aux2 (fun l r -> Union_f (l, r)) l r + | Union_t (l, r, _, _) -> aux2 (fun l r -> Union_f (l, r)) l r | Option_t (t, _) -> aux1 (fun h -> Option_f h) t | List_t (t, _) -> aux1 (fun h -> List_f h) t | Map_t (_, t, _) -> aux1 (fun h -> Map_f h) t @@ -6215,10 +6216,10 @@ let[@coq_axiom_with_reason "gadt"] extract_lazy_storage_updates ctxt mode aux ctxt mode ~temporary ids_to_copy acc tyr xr ~has_lazy_storage:hr >|=? fun (ctxt, xr, ids_to_copy, acc) -> (ctxt, (xl, xr), ids_to_copy, acc) - | (Union_f (has_lazy_storage, _), Union_t (ty, _, _), L x) -> + | (Union_f (has_lazy_storage, _), Union_t (ty, _, _, _), L x) -> aux ctxt mode ~temporary ids_to_copy acc ty x ~has_lazy_storage >|=? fun (ctxt, x, ids_to_copy, acc) -> (ctxt, L x, ids_to_copy, acc) - | (Union_f (_, has_lazy_storage), Union_t (_, ty, _), R x) -> + | (Union_f (_, has_lazy_storage), Union_t (_, ty, _, _), R x) -> aux ctxt mode ~temporary ids_to_copy acc ty x ~has_lazy_storage >|=? fun (ctxt, x, ids_to_copy, acc) -> (ctxt, R x, ids_to_copy, acc) | (Option_f has_lazy_storage, Option_t (ty, _), Some x) -> @@ -6310,9 +6311,9 @@ let[@coq_axiom_with_reason "gadt"] rec fold_lazy_storage : | Fold_lazy_storage.Ok init -> fold_lazy_storage ~f ~init ctxt tyr xr ~has_lazy_storage:hr | Fold_lazy_storage.Error -> ok (init, ctxt)) - | (Union_f (has_lazy_storage, _), Union_t (ty, _, _), L x) -> + | (Union_f (has_lazy_storage, _), Union_t (ty, _, _, _), L x) -> fold_lazy_storage ~f ~init ctxt ty x ~has_lazy_storage - | (Union_f (_, has_lazy_storage), Union_t (_, ty, _), R x) -> + | (Union_f (_, has_lazy_storage), Union_t (_, ty, _, _), R x) -> fold_lazy_storage ~f ~init ctxt ty x ~has_lazy_storage | (_, Option_t (_, _), None) -> ok (Fold_lazy_storage.Ok init, ctxt) | (Option_f has_lazy_storage, Option_t (ty, _), Some x) -> diff --git a/src/proto_alpha/lib_protocol/script_typed_ir.ml b/src/proto_alpha/lib_protocol/script_typed_ir.ml index 3593f71138..65281c3e57 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir.ml +++ b/src/proto_alpha/lib_protocol/script_typed_ir.ml @@ -1243,7 +1243,9 @@ and 'ty ty = | Pair_t : 'a ty * 'b ty * ('a, 'b) pair ty_metadata * to_be_replaced -> ('a, 'b) pair ty - | Union_t : 'a ty * 'b ty * ('a, 'b) union ty_metadata -> ('a, 'b) union ty + | Union_t : + 'a ty * 'b ty * ('a, 'b) union ty_metadata * to_be_replaced + -> ('a, 'b) union ty | Lambda_t : 'arg ty * 'ret ty * ('arg, 'ret) lambda ty_metadata -> ('arg, 'ret) lambda ty @@ -1770,7 +1772,7 @@ let ty_metadata : type a. a ty -> a ty_metadata = function | Tx_rollup_l2_address_t -> meta_basic | Pair_t (_, _, meta, _) -> meta - | Union_t (_, _, meta) -> meta + | Union_t (_, _, meta, _) -> meta | Option_t (_, meta) -> meta | Lambda_t (_, _, meta) -> meta | List_t (_, meta) -> meta @@ -1863,9 +1865,9 @@ let pair_3_key loc l m r = pair_key loc m r >>? fun r -> pair_key loc l r let union_t loc l r = Type_size.compound2 loc (ty_size l) (ty_size r) >|? fun size -> - Ty_ex_c (Union_t (l, r, {size})) + Ty_ex_c (Union_t (l, r, {size}, ())) -let union_bytes_bool_t = Union_t (bytes_t, bool_t, {size = Type_size.three}) +let union_bytes_bool_t = Union_t (bytes_t, bool_t, {size = Type_size.three}, ()) let union_key loc l r = Type_size.compound2 loc (comparable_ty_size l) (comparable_ty_size r) @@ -2197,7 +2199,7 @@ let (ty_traverse, comparable_ty_traverse) = | Chest_key_t | Chest_t -> (continue [@ocaml.tailcall]) accu | Pair_t (ty1, ty2, _, _) -> (next2' [@ocaml.tailcall]) f accu ty1 ty2 continue - | Union_t (ty1, ty2, _) -> + | Union_t (ty1, ty2, _, _) -> (next2' [@ocaml.tailcall]) f accu ty1 ty2 continue | Lambda_t (ty1, ty2, _) -> (next2' [@ocaml.tailcall]) f accu ty1 ty2 continue @@ -2277,7 +2279,7 @@ let value_traverse (type t) (ty : (t ty, t comparable_ty) union) (x : t) init f (return [@ocaml.tailcall]) () | Pair_t (ty1, ty2, _, _) -> (next2 [@ocaml.tailcall]) ty1 ty2 (fst x) (snd x) - | Union_t (ty1, ty2, _) -> ( + | Union_t (ty1, ty2, _, _) -> ( match x with | L l -> (next [@ocaml.tailcall]) ty1 l | R r -> (next [@ocaml.tailcall]) ty2 r) diff --git a/src/proto_alpha/lib_protocol/script_typed_ir.mli b/src/proto_alpha/lib_protocol/script_typed_ir.mli index cb63877d67..e792208eec 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir.mli +++ b/src/proto_alpha/lib_protocol/script_typed_ir.mli @@ -1347,7 +1347,9 @@ and 'ty ty = | Pair_t : 'a ty * 'b ty * ('a, 'b) pair ty_metadata * to_be_replaced -> ('a, 'b) pair ty - | Union_t : 'a ty * 'b ty * ('a, 'b) union ty_metadata -> ('a, 'b) union ty + | Union_t : + 'a ty * 'b ty * ('a, 'b) union ty_metadata * to_be_replaced + -> ('a, 'b) union ty | Lambda_t : 'arg ty * 'ret ty * ('arg, 'ret) lambda ty_metadata -> ('arg, 'ret) lambda ty diff --git a/src/proto_alpha/lib_protocol/script_typed_ir_size.ml b/src/proto_alpha/lib_protocol/script_typed_ir_size.ml index 70a6a66cd2..74269ef8c5 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir_size.ml +++ b/src/proto_alpha/lib_protocol/script_typed_ir_size.ml @@ -92,8 +92,8 @@ let ty_traverse_f = | Chest_t -> ret_succ_adding accu base_basic | Pair_t (_ty1, _ty2, a, _) -> ret_succ_adding accu @@ (base_compound a +! (word_size *? 3)) - | Union_t (_ty1, _ty2, a) -> - ret_succ_adding accu @@ (base_compound a +! (word_size *? 2)) + | Union_t (_ty1, _ty2, a, _) -> + ret_succ_adding accu @@ (base_compound a +! (word_size *? 3)) | Lambda_t (_ty1, _ty2, a) -> ret_succ_adding accu @@ (base_compound a +! (word_size *? 2)) | Option_t (_ty, a) -> ret_succ_adding accu @@ (base_compound a +! word_size) @@ -286,7 +286,7 @@ let rec value_size : ret_succ_adding accu (tx_rollup_l2_address_size x) | Bool_t -> ret_succ accu | Pair_t (_, _, _, _) -> ret_succ_adding accu h2w - | Union_t (_, _, _) -> ret_succ_adding accu h1w + | Union_t (_, _, _, _) -> ret_succ_adding accu h1w | Lambda_t (_, _, _) -> (lambda_size [@ocaml.tailcall]) ~count_lambda_nodes (ret_succ accu) x | Option_t (_, _) -> ret_succ_adding accu (option_size (fun _ -> !!0) x) diff --git a/src/proto_alpha/lib_protocol/ticket_scanner.ml b/src/proto_alpha/lib_protocol/ticket_scanner.ml index e65c22c4bb..15f784839d 100644 --- a/src/proto_alpha/lib_protocol/ticket_scanner.ml +++ b/src/proto_alpha/lib_protocol/ticket_scanner.ml @@ -169,7 +169,7 @@ module Ticket_inspection = struct ty2 ~pair:(fun ht1 ht2 -> Pair_ht (ht1, ht2)) k - | Union_t (ty1, ty2, _) -> + | Union_t (ty1, ty2, _, _) -> (has_tickets_of_pair [@ocaml.tailcall]) ty1 ty2 @@ -340,7 +340,7 @@ module Ticket_collection = struct r acc k) - | (Union_ht (htyl, htyr), Union_t (tyl, tyr, _)) -> ( + | (Union_ht (htyl, htyr), Union_t (tyl, tyr, _, _)) -> ( match x with | L v -> (tickets_of_value [@ocaml.tailcall]) From 117cc337e56d3e9767783f2f0c15d10b38fbb34a Mon Sep 17 00:00:00 2001 From: Mehdi Bouaziz Date: Sat, 26 Feb 2022 09:58:30 +0100 Subject: [PATCH 020/100] Proto/Michelson: add a 3rd parameter to Option_t constructor To be replaced in a later commit --- .../lib_benchmark/michelson_samplers.ml | 2 +- .../lib_benchmark/test/test_distribution.ml | 2 +- src/proto_alpha/lib_plugin/plugin.ml | 2 +- .../lib_protocol/script_ir_translator.ml | 53 ++++++++++--------- .../lib_protocol/script_typed_ir.ml | 30 ++++++----- .../lib_protocol/script_typed_ir.mli | 2 +- .../lib_protocol/script_typed_ir_size.ml | 5 +- .../lib_protocol/ticket_scanner.ml | 4 +- 8 files changed, 54 insertions(+), 46 deletions(-) diff --git a/src/proto_alpha/lib_benchmark/michelson_samplers.ml b/src/proto_alpha/lib_benchmark/michelson_samplers.ml index b2edb5ae1d..c8dbb91666 100644 --- a/src/proto_alpha/lib_benchmark/michelson_samplers.ml +++ b/src/proto_alpha/lib_benchmark/michelson_samplers.ml @@ -567,7 +567,7 @@ end) L (value left_t rng_state) else R (value right_t rng_state) | Lambda_t (arg_ty, ret_ty, _) -> generate_lambda arg_ty ret_ty - | Option_t (ty, _) -> + | Option_t (ty, _, _) -> fun rng_state -> if Base_samplers.uniform_bool rng_state then None else Some (value ty rng_state) diff --git a/src/proto_alpha/lib_benchmark/test/test_distribution.ml b/src/proto_alpha/lib_benchmark/test/test_distribution.ml index ce45865956..2dee94ce5a 100644 --- a/src/proto_alpha/lib_benchmark/test/test_distribution.ml +++ b/src/proto_alpha/lib_benchmark/test/test_distribution.ml @@ -77,7 +77,7 @@ let rec tnames_of_type : tnames_of_type lty (tnames_of_type rty (`TUnion :: acc)) | Script_typed_ir.Lambda_t (dom, range, _) -> tnames_of_type dom (tnames_of_type range (`TLambda :: acc)) - | Script_typed_ir.Option_t (ty, _) -> tnames_of_type ty (`TOption :: acc) + | Script_typed_ir.Option_t (ty, _, _) -> tnames_of_type ty (`TOption :: acc) | Script_typed_ir.List_t (ty, _) -> tnames_of_type ty (`TList :: acc) | Script_typed_ir.Set_t (ty, _) -> tnames_of_comparable_type ty (`TSet :: acc) | Script_typed_ir.Map_t (kty, vty, _) -> diff --git a/src/proto_alpha/lib_plugin/plugin.ml b/src/proto_alpha/lib_plugin/plugin.ml index 77d52f60a5..8e0fe2cf24 100644 --- a/src/proto_alpha/lib_plugin/plugin.ml +++ b/src/proto_alpha/lib_plugin/plugin.ml @@ -2057,7 +2057,7 @@ module RPC = struct let ta = unparse_ty ~loc uta in let tr = unparse_ty ~loc utr in return (T_lambda, [ta; tr], []) - | Option_t (ut, _meta) -> + | Option_t (ut, _meta, _) -> let annot = [] in let ut = unparse_ty ~loc ut in return (T_option, [ut], annot) diff --git a/src/proto_alpha/lib_protocol/script_ir_translator.ml b/src/proto_alpha/lib_protocol/script_ir_translator.ml index 9665644323..a4ffaa7a2d 100644 --- a/src/proto_alpha/lib_protocol/script_ir_translator.ml +++ b/src/proto_alpha/lib_protocol/script_ir_translator.ml @@ -181,7 +181,7 @@ let rec ty_of_comparable_ty : type a. a comparable_ty -> a ty = function Pair_t (ty_of_comparable_ty l, ty_of_comparable_ty r, meta, ()) | Union_key (l, r, meta) -> Union_t (ty_of_comparable_ty l, ty_of_comparable_ty r, meta, ()) - | Option_key (t, meta) -> Option_t (ty_of_comparable_ty t, meta) + | Option_key (t, meta) -> Option_t (ty_of_comparable_ty t, meta, ()) let rec unparse_comparable_ty_uncarbonated : type a loc. loc:loc -> a comparable_ty -> loc Script.michelson_node = @@ -270,7 +270,7 @@ let rec unparse_ty_entrypoints_uncarbonated : let ta = unparse_ty_entrypoints_uncarbonated ~loc uta no_entrypoints in let tr = unparse_ty_entrypoints_uncarbonated ~loc utr no_entrypoints in (T_lambda, [ta; tr]) - | Option_t (ut, _meta) -> + | Option_t (ut, _meta, _) -> let ut = unparse_ty_entrypoints_uncarbonated ~loc ut no_entrypoints in (T_option, [ut]) | List_t (ut, _meta) -> @@ -360,7 +360,7 @@ let[@coq_axiom_with_reason "gadt"] rec comparable_ty_of_ty : comparable_ty_of_ty ctxt loc l >>? fun (lty, ctxt) -> comparable_ty_of_ty ctxt loc r >|? fun (rty, ctxt) -> (Union_key (lty, rty, meta), ctxt) - | Option_t (tt, meta) -> + | Option_t (tt, meta, _) -> comparable_ty_of_ty ctxt loc tt >|? fun (ty, ctxt) -> (Option_key (ty, meta), ctxt) | Lambda_t _ | List_t _ | Ticket_t _ | Set_t _ | Map_t _ | Big_map_t _ @@ -722,7 +722,7 @@ let check_dupable_ty ctxt loc ty = Hence non-dupable should imply non-packable. *) return_unit - | Option_t (ty, _) -> aux loc ty + | Option_t (ty, _, _) -> aux loc ty | List_t (ty, _) -> aux loc ty | Set_t (key_ty, _) -> let () = check_dupable_comparable_ty key_ty in @@ -974,7 +974,7 @@ let ty_eq : let+ Eq = help tal tbl in (Eq : (ta ty, tb ty) eq) | (Contract_t _, _) -> not_equal () - | (Option_t (tva, meta1), Option_t (tvb, meta2)) -> + | (Option_t (tva, meta1, _), Option_t (tvb, meta2, _)) -> let* () = type_metadata_eq meta1 meta2 in let+ Eq = help tva tvb in (Eq : (ta ty, tb ty) eq) @@ -1755,7 +1755,7 @@ let check_packable ~legacy loc root = | Bls12_381_fr_t -> Result.return_unit | Pair_t (l_ty, r_ty, _, _) -> check l_ty >>? fun () -> check r_ty | Union_t (l_ty, r_ty, _, _) -> check l_ty >>? fun () -> check r_ty - | Option_t (v_ty, _) -> check v_ty + | Option_t (v_ty, _, _) -> check v_ty | List_t (elt_ty, _) -> check elt_ty | Map_t (_, elt_ty, _) -> check elt_ty | Contract_t (_, _) when legacy -> Result.return_unit @@ -2713,7 +2713,7 @@ let[@coq_axiom_with_reason "gadt"] rec parse_data : | (Lambda_t _, expr) -> traced_fail (Invalid_kind (location expr, [Seq_kind], kind expr)) (* Options *) - | (Option_t (t, _), expr) -> + | (Option_t (t, _, _), expr) -> let parse_v ctxt v = non_terminal_recursion ?type_logger ctxt ~legacy t v in @@ -3265,7 +3265,7 @@ and[@coq_axiom_with_reason "gadt"] parse_instr : option_t loc t >>?= fun ty -> let stack_ty = Item_t (ty, stack) in typed ctxt loc cons_none stack_ty - | (Prim (loc, I_MAP, [body], annot), Item_t (Option_t (t, _), rest)) -> ( + | (Prim (loc, I_MAP, [body], annot), Item_t (Option_t (t, _, _), rest)) -> ( check_kind [Seq_kind] body >>?= fun () -> check_var_type_annot loc annot >>?= fun () -> non_terminal_recursion @@ -3299,7 +3299,7 @@ and[@coq_axiom_with_reason "gadt"] parse_instr : error (Invalid_map_body (loc, aft)) | Failed _ -> error (Invalid_map_block_fail loc)) | ( Prim (loc, I_IF_NONE, [bt; bf], annot), - (Item_t (Option_t (t, _), rest) as bef) ) -> + (Item_t (Option_t (t, _, _), rest) as bef) ) -> check_kind [Seq_kind] bt >>?= fun () -> check_kind [Seq_kind] bf >>?= fun () -> error_unexpected_annot loc annot >>?= fun () -> @@ -3767,8 +3767,9 @@ and[@coq_axiom_with_reason "gadt"] parse_instr : typed ctxt loc instr (Item_t (ty, rest)) | ( Prim (loc, I_UPDATE, [], annot), Item_t - (vk, Item_t (Option_t (vv, _), (Item_t (Map_t (ck, v, _), _) as stack))) - ) -> + ( vk, + Item_t (Option_t (vv, _, _), (Item_t (Map_t (ck, v, _), _) as stack)) + ) ) -> let k = ty_of_comparable_ty ck in check_item_ty ctxt vk k loc I_UPDATE 1 3 >>?= fun (Eq, ctxt) -> check_item_ty ctxt vv v loc I_UPDATE 2 3 >>?= fun (Eq, ctxt) -> @@ -3777,8 +3778,9 @@ and[@coq_axiom_with_reason "gadt"] parse_instr : (typed ctxt loc instr stack : ((a, s) judgement * context) tzresult Lwt.t) | ( Prim (loc, I_GET_AND_UPDATE, [], annot), Item_t - (vk, (Item_t (Option_t (vv, _), Item_t (Map_t (ck, v, _), _)) as stack)) - ) -> + ( vk, + (Item_t (Option_t (vv, _, _), Item_t (Map_t (ck, v, _), _)) as stack) + ) ) -> let k = ty_of_comparable_ty ck in check_item_ty ctxt vk k loc I_GET_AND_UPDATE 1 3 >>?= fun (Eq, ctxt) -> check_item_ty ctxt vv v loc I_GET_AND_UPDATE 2 3 >>?= fun (Eq, ctxt) -> @@ -3823,7 +3825,7 @@ and[@coq_axiom_with_reason "gadt"] parse_instr : Item_t ( set_key, Item_t - ( Option_t (set_value, _), + ( Option_t (set_value, _, _), (Item_t (Big_map_t (map_key, map_value, _), _) as stack) ) ) ) -> let k = ty_of_comparable_ty map_key in check_item_ty ctxt set_key k loc I_UPDATE 1 3 >>?= fun (Eq, ctxt) -> @@ -3835,8 +3837,8 @@ and[@coq_axiom_with_reason "gadt"] parse_instr : | ( Prim (loc, I_GET_AND_UPDATE, [], annot), Item_t ( vk, - (Item_t (Option_t (vv, _), Item_t (Big_map_t (ck, v, _), _)) as stack) - ) ) -> + (Item_t (Option_t (vv, _, _), Item_t (Big_map_t (ck, v, _), _)) as + stack) ) ) -> let k = ty_of_comparable_ty ck in check_item_ty ctxt vk k loc I_GET_AND_UPDATE 1 3 >>?= fun (Eq, ctxt) -> check_item_ty ctxt vv v loc I_GET_AND_UPDATE 2 3 >>?= fun (Eq, ctxt) -> @@ -4558,7 +4560,7 @@ and[@coq_axiom_with_reason "gadt"] parse_instr : let stack = Item_t (operation_t, rest) in (typed ctxt loc instr stack : ((a, s) judgement * context) tzresult Lwt.t) | ( Prim (loc, (I_SET_DELEGATE as prim), [], annot), - Item_t (Option_t (Key_hash_t, _), rest) ) -> + Item_t (Option_t (Key_hash_t, _, _), rest) ) -> Tc_context.check_not_in_view loc ~legacy tc_context prim >>?= fun () -> check_var_annot loc annot >>?= fun () -> let instr = {apply = (fun kinfo k -> ISet_delegate (kinfo, k))} in @@ -4572,8 +4574,9 @@ and[@coq_axiom_with_reason "gadt"] parse_instr : let stack = Item_t (contract_unit_t, rest) in typed ctxt loc instr stack | ( Prim (loc, (I_CREATE_CONTRACT as prim), [(Seq _ as code)], annot), - Item_t (Option_t (Key_hash_t, _), Item_t (Mutez_t, Item_t (ginit, rest))) - ) -> + Item_t + (Option_t (Key_hash_t, _, _), Item_t (Mutez_t, Item_t (ginit, rest))) ) + -> Tc_context.check_not_in_view ~legacy loc tc_context prim >>?= fun () -> check_two_var_annot loc annot >>?= fun () -> let canonical_code = Micheline.strip_locations code in @@ -5666,7 +5669,7 @@ let[@coq_axiom_with_reason "gadt"] rec unparse_data : let unparse_l ctxt v = non_terminal_recursion ctxt mode tl v in let unparse_r ctxt v = non_terminal_recursion ctxt mode tr v in unparse_union ~loc unparse_l unparse_r ctxt v - | (Option_t (t, _), v) -> + | (Option_t (t, _, _), v) -> let unparse_v ctxt v = non_terminal_recursion ctxt mode t v in unparse_option ~loc unparse_v ctxt v | (List_t (t, _), items) -> @@ -6157,7 +6160,7 @@ let rec has_lazy_storage : type t. t ty -> t has_lazy_storage = | Chest_t -> False_f | Pair_t (l, r, _, _) -> aux2 (fun l r -> Pair_f (l, r)) l r | Union_t (l, r, _, _) -> aux2 (fun l r -> Union_f (l, r)) l r - | Option_t (t, _) -> aux1 (fun h -> Option_f h) t + | Option_t (t, _, _) -> aux1 (fun h -> Option_f h) t | List_t (t, _) -> aux1 (fun h -> List_f h) t | Map_t (_, t, _) -> aux1 (fun h -> Map_f h) t @@ -6222,7 +6225,7 @@ let[@coq_axiom_with_reason "gadt"] extract_lazy_storage_updates ctxt mode | (Union_f (_, has_lazy_storage), Union_t (_, ty, _, _), R x) -> aux ctxt mode ~temporary ids_to_copy acc ty x ~has_lazy_storage >|=? fun (ctxt, x, ids_to_copy, acc) -> (ctxt, R x, ids_to_copy, acc) - | (Option_f has_lazy_storage, Option_t (ty, _), Some x) -> + | (Option_f has_lazy_storage, Option_t (ty, _, _), Some x) -> aux ctxt mode ~temporary ids_to_copy acc ty x ~has_lazy_storage >|=? fun (ctxt, x, ids_to_copy, acc) -> (ctxt, Some x, ids_to_copy, acc) | (List_f has_lazy_storage, List_t (ty, _), l) -> @@ -6265,7 +6268,7 @@ let[@coq_axiom_with_reason "gadt"] extract_lazy_storage_updates ctxt mode and type value = M.value), ids_to_copy, acc ) - | (_, Option_t (_, _), None) -> return (ctxt, None, ids_to_copy, acc) + | (_, Option_t (_, _, _), None) -> return (ctxt, None, ids_to_copy, acc) in let has_lazy_storage = has_lazy_storage ty in aux ctxt mode ~temporary ids_to_copy acc ty x ~has_lazy_storage @@ -6315,8 +6318,8 @@ let[@coq_axiom_with_reason "gadt"] rec fold_lazy_storage : fold_lazy_storage ~f ~init ctxt ty x ~has_lazy_storage | (Union_f (_, has_lazy_storage), Union_t (_, ty, _, _), R x) -> fold_lazy_storage ~f ~init ctxt ty x ~has_lazy_storage - | (_, Option_t (_, _), None) -> ok (Fold_lazy_storage.Ok init, ctxt) - | (Option_f has_lazy_storage, Option_t (ty, _), Some x) -> + | (_, Option_t (_, _, _), None) -> ok (Fold_lazy_storage.Ok init, ctxt) + | (Option_f has_lazy_storage, Option_t (ty, _, _), Some x) -> fold_lazy_storage ~f ~init ctxt ty x ~has_lazy_storage | (List_f has_lazy_storage, List_t (ty, _), l) -> List.fold_left_e diff --git a/src/proto_alpha/lib_protocol/script_typed_ir.ml b/src/proto_alpha/lib_protocol/script_typed_ir.ml index 65281c3e57..ed6a521f49 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir.ml +++ b/src/proto_alpha/lib_protocol/script_typed_ir.ml @@ -1249,7 +1249,7 @@ and 'ty ty = | Lambda_t : 'arg ty * 'ret ty * ('arg, 'ret) lambda ty_metadata -> ('arg, 'ret) lambda ty - | Option_t : 'v ty * 'v option ty_metadata -> 'v option ty + | Option_t : 'v ty * 'v option ty_metadata * to_be_replaced -> 'v option ty | List_t : 'v ty * 'v boxed_list ty_metadata -> 'v boxed_list ty | Set_t : 'v comparable_ty * 'v set ty_metadata -> 'v set ty | Map_t : @@ -1773,7 +1773,7 @@ let ty_metadata : type a. a ty -> a ty_metadata = function meta_basic | Pair_t (_, _, meta, _) -> meta | Union_t (_, _, meta, _) -> meta - | Option_t (_, meta) -> meta + | Option_t (_, meta, _) -> meta | Lambda_t (_, _, meta) -> meta | List_t (_, meta) -> meta | Set_t (_, meta) -> meta @@ -1878,35 +1878,39 @@ let lambda_t loc l r = Lambda_t (l, r, {size}) let option_t loc t = - Type_size.compound1 loc (ty_size t) >|? fun size -> Option_t (t, {size}) + Type_size.compound1 loc (ty_size t) >|? fun size -> Option_t (t, {size}, ()) -let option_mutez_t = Option_t (mutez_t, {size = Type_size.two}) +let option_mutez_t = Option_t (mutez_t, {size = Type_size.two}, ()) -let option_string_t = Option_t (string_t, {size = Type_size.two}) +let option_string_t = Option_t (string_t, {size = Type_size.two}, ()) -let option_bytes_t = Option_t (bytes_t, {size = Type_size.two}) +let option_bytes_t = Option_t (bytes_t, {size = Type_size.two}, ()) -let option_nat_t = Option_t (nat_t, {size = Type_size.two}) +let option_nat_t = Option_t (nat_t, {size = Type_size.two}, ()) let option_pair_nat_nat_t = Option_t ( Pair_t (nat_t, nat_t, {size = Type_size.three}, ()), - {size = Type_size.four} ) + {size = Type_size.four}, + () ) let option_pair_nat_mutez_t = Option_t ( Pair_t (nat_t, mutez_t, {size = Type_size.three}, ()), - {size = Type_size.four} ) + {size = Type_size.four}, + () ) let option_pair_mutez_mutez_t = Option_t ( Pair_t (mutez_t, mutez_t, {size = Type_size.three}, ()), - {size = Type_size.four} ) + {size = Type_size.four}, + () ) let option_pair_int_nat_t = Option_t ( Pair_t (int_t, nat_t, {size = Type_size.three}, ()), - {size = Type_size.four} ) + {size = Type_size.four}, + () ) let option_key loc t = Type_size.compound1 loc (comparable_ty_size t) >|? fun size -> @@ -2203,7 +2207,7 @@ let (ty_traverse, comparable_ty_traverse) = (next2' [@ocaml.tailcall]) f accu ty1 ty2 continue | Lambda_t (ty1, ty2, _) -> (next2' [@ocaml.tailcall]) f accu ty1 ty2 continue - | Option_t (ty1, _) -> (next' [@ocaml.tailcall]) f accu ty1 continue + | Option_t (ty1, _, _) -> (next' [@ocaml.tailcall]) f accu ty1 continue | List_t (ty1, _) -> (next' [@ocaml.tailcall]) f accu ty1 continue | Set_t (cty, _) -> (aux [@ocaml.tailcall]) f accu cty @@ continue | Map_t (cty, ty1, _) -> @@ -2283,7 +2287,7 @@ let value_traverse (type t) (ty : (t ty, t comparable_ty) union) (x : t) init f match x with | L l -> (next [@ocaml.tailcall]) ty1 l | R r -> (next [@ocaml.tailcall]) ty2 r) - | Option_t (ty, _) -> ( + | Option_t (ty, _, _) -> ( match x with | None -> return () | Some v -> (next [@ocaml.tailcall]) ty v) diff --git a/src/proto_alpha/lib_protocol/script_typed_ir.mli b/src/proto_alpha/lib_protocol/script_typed_ir.mli index e792208eec..b6ee0aca6e 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir.mli +++ b/src/proto_alpha/lib_protocol/script_typed_ir.mli @@ -1353,7 +1353,7 @@ and 'ty ty = | Lambda_t : 'arg ty * 'ret ty * ('arg, 'ret) lambda ty_metadata -> ('arg, 'ret) lambda ty - | Option_t : 'v ty * 'v option ty_metadata -> 'v option ty + | Option_t : 'v ty * 'v option ty_metadata * to_be_replaced -> 'v option ty | List_t : 'v ty * 'v boxed_list ty_metadata -> 'v boxed_list ty | Set_t : 'v comparable_ty * 'v set ty_metadata -> 'v set ty | Map_t : diff --git a/src/proto_alpha/lib_protocol/script_typed_ir_size.ml b/src/proto_alpha/lib_protocol/script_typed_ir_size.ml index 74269ef8c5..8ffaabc9a1 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir_size.ml +++ b/src/proto_alpha/lib_protocol/script_typed_ir_size.ml @@ -96,7 +96,8 @@ let ty_traverse_f = ret_succ_adding accu @@ (base_compound a +! (word_size *? 3)) | Lambda_t (_ty1, _ty2, a) -> ret_succ_adding accu @@ (base_compound a +! (word_size *? 2)) - | Option_t (_ty, a) -> ret_succ_adding accu @@ (base_compound a +! word_size) + | Option_t (_ty, a, _) -> + ret_succ_adding accu @@ (base_compound a +! (word_size *? 2)) | List_t (_ty, a) -> ret_succ_adding accu @@ (base_compound a +! word_size) | Set_t (_cty, a) -> ret_succ_adding accu @@ (base_compound a +! word_size) | Map_t (_cty, _ty, a) -> @@ -289,7 +290,7 @@ let rec value_size : | Union_t (_, _, _, _) -> ret_succ_adding accu h1w | Lambda_t (_, _, _) -> (lambda_size [@ocaml.tailcall]) ~count_lambda_nodes (ret_succ accu) x - | Option_t (_, _) -> ret_succ_adding accu (option_size (fun _ -> !!0) x) + | Option_t (_, _, _) -> ret_succ_adding accu (option_size (fun _ -> !!0) x) | List_t (_, _) -> ret_succ_adding accu (h2w +! (h2w *? x.length)) | Set_t (_, _) -> let module M = (val Script_set.get x) in diff --git a/src/proto_alpha/lib_protocol/ticket_scanner.ml b/src/proto_alpha/lib_protocol/ticket_scanner.ml index 15f784839d..2130c27671 100644 --- a/src/proto_alpha/lib_protocol/ticket_scanner.ml +++ b/src/proto_alpha/lib_protocol/ticket_scanner.ml @@ -179,7 +179,7 @@ module Ticket_inspection = struct (* As of H, closures cannot contain tickets because APPLY requires a packable type and tickets are not packable. *) (k [@ocaml.tailcall]) False_ht - | Option_t (ty, _) -> + | Option_t (ty, _, _) -> (has_tickets_of_ty [@ocaml.tailcall]) ty (fun ht -> let opt_hty = map_has_tickets (fun ht -> Option_ht ht) ht in (k [@ocaml.tailcall]) opt_hty) @@ -360,7 +360,7 @@ module Ticket_collection = struct v acc k) - | (Option_ht el_hty, Option_t (el_ty, _)) -> ( + | (Option_ht el_hty, Option_t (el_ty, _, _)) -> ( match x with | Some x -> (tickets_of_value [@ocaml.tailcall]) From 6348cc5e3b74e6248269d8aba4a41a43631c618e Mon Sep 17 00:00:00 2001 From: Mehdi Bouaziz Date: Mon, 14 Mar 2022 18:05:11 +0100 Subject: [PATCH 021/100] Proto/Tests: adapt cache size hardcoded values --- .../test/integration/michelson/test_script_cache.ml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_script_cache.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_script_cache.ml index 1f72c33d99..60247caa35 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_script_cache.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_script_cache.ml @@ -46,7 +46,7 @@ let err x = Exn (Script_cache_test_error x) model. It has been computed by a manual run of the test. *) -let liquidity_baking_contract_size = 266738 +let liquidity_baking_contract_size = 267304 let liquidity_baking_contract = Contract.of_b58check "KT1TxqZ8QtKvLu3V3JH7Gx58n7Co8pgtpQU5" |> function @@ -120,7 +120,7 @@ let add_some_contracts k src block baker = model. It has been computed by a manual run of the test. *) -let int_store_contract_size = 891 +let int_store_contract_size = 916 (* From a1d9723c1030f467e8b4768e115835d6a476ad55 Mon Sep 17 00:00:00 2001 From: David Dumas Date: Tue, 15 Mar 2022 18:42:54 +0100 Subject: [PATCH 022/100] CI: switch to Docker 20.10.12 socket binding --- .gitlab/ci/build_release.yml | 2 +- .gitlab/ci/publish_release.yml | 2 +- .gitlab/ci/templates.yml | 29 ++++++++--------------------- 3 files changed, 10 insertions(+), 23 deletions(-) diff --git a/.gitlab/ci/build_release.yml b/.gitlab/ci/build_release.yml index 12a41f5089..fa008b00de 100644 --- a/.gitlab/ci/build_release.yml +++ b/.gitlab/ci/build_release.yml @@ -2,7 +2,7 @@ .build_docker_release_template: extends: - .default_settings_template - - .image_template__latest # Docker-in-Docker (dind) + - .image_template__docker - .docker_registry_auth # Sets up a before_script variables: IMAGE_ARCH_PREFIX: "" diff --git a/.gitlab/ci/publish_release.yml b/.gitlab/ci/publish_release.yml index 31e915343e..5f74c6eb18 100644 --- a/.gitlab/ci/publish_release.yml +++ b/.gitlab/ci/publish_release.yml @@ -20,7 +20,7 @@ release-on-gitlab: docker:merge_manifests: extends: - .rules_template__master_and_releases - - .image_template__latest # Docker-in-Docker (dind) + - .image_template__docker - .docker_registry_auth # Sets up a before_script stage: publish_release # this job does not need artifacts from previous jobs. diff --git a/.gitlab/ci/templates.yml b/.gitlab/ci/templates.yml index 79da88e4ab..cf76be0e4d 100644 --- a/.gitlab/ci/templates.yml +++ b/.gitlab/ci/templates.yml @@ -32,28 +32,15 @@ variables: .image_template__runtime_prebuild_dependencies_template: image: ${build_deps_image_name}:runtime-prebuild-dependencies--${build_deps_image_version} -# We should only use the latest version of Docker for experimental features (ex: docker manifest) -.image_template__latest: +# Match GitLab executors version and directly use the Docker socket +# The Docker daemon is already configured, experimental features are enabled +# The following environment variables are already set: +# - BUILDKIT_PROGRESS +# - DOCKER_DRIVER +# - DOCKER_VERSION +# https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#use-docker-socket-binding +.image_template__docker: image: docker:20.10.12 - services: - - name: docker:20.10.12-dind - command: ["--experimental"] - variables: - DOCKER_DRIVER: overlay2 - DOCKER_BUILDKIT: 1 - BUILDKIT_PROGRESS: plain - -# We should use the stable version to build Docker images (this template is not used at the moment) -# Match the GitLab runners/executors version for Docker-in-Docker -# https://gitlab.com/nomadic-labs/iac/packer/pck-aws-baseimage/-/blob/master/roles/docker-ubuntu.yaml -.image_template__stable: - image: docker:19.03.15 - services: - - docker:19.03.15-dind - variables: - DOCKER_DRIVER: overlay2 - DOCKER_BUILDKIT: 1 - BUILDKIT_PROGRESS: plain # Rules template From 47ab32c9113a1329f6ea5fec4a487b6b987a4164 Mon Sep 17 00:00:00 2001 From: Victor Allombert Date: Mon, 28 Feb 2022 17:14:04 +0100 Subject: [PATCH 023/100] Tezt/Tx_rollup: expose rpc port and addr of a tx_rollup_node --- tezt/lib_tezos/tx_rollup_node.mli | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tezt/lib_tezos/tx_rollup_node.mli b/tezt/lib_tezos/tx_rollup_node.mli index 944b74cc1f..8a20705367 100644 --- a/tezt/lib_tezos/tx_rollup_node.mli +++ b/tezt/lib_tezos/tx_rollup_node.mli @@ -70,3 +70,9 @@ val run : t -> unit Lwt.t (** See [Daemon.Make.terminate]. *) val terminate : ?kill:bool -> t -> unit Lwt.t + +(** Get the RPC host given as [--rpc-addr] to a node. *) +val rpc_host : t -> string + +(** Get the RPC port given as [--rpc-port] to a node. *) +val rpc_port : t -> int From cf4b0e123fc9b79b651d358ce15efed974bf420f Mon Sep 17 00:00:00 2001 From: Victor Allombert Date: Mon, 28 Feb 2022 18:05:41 +0100 Subject: [PATCH 024/100] Tezt/Tx_rollup: test the ticket deposit (l1 to l2) --- tezt/tests/tx_rollup_node.ml | 186 ++++++++++++++++++++++++++++++++++- 1 file changed, 183 insertions(+), 3 deletions(-) diff --git a/tezt/tests/tx_rollup_node.ml b/tezt/tests/tx_rollup_node.ml index c8463269ac..105dce6332 100644 --- a/tezt/tests/tx_rollup_node.ml +++ b/tezt/tests/tx_rollup_node.ml @@ -196,7 +196,7 @@ let test_tx_node_store_inbox = Client.Tx_rollup.submit_batch ~content:batch ~rollup - ~src:Constant.bootstrap1.public_key_hash + ~src:operator client in let* () = Client.bake_for client in @@ -212,7 +212,7 @@ let test_tx_node_store_inbox = Client.Tx_rollup.submit_batch ~content:snd_batch ~rollup - ~src:Constant.bootstrap1.public_key_hash + ~src:operator client in let* () = Client.bake_for client in @@ -231,7 +231,187 @@ let test_tx_node_store_inbox = check_inbox_equality node_inbox_2 inbox_after_restart ; unit) +(* FIXME/TORU: This is a temporary way of querying the node without + tx_rollup_client. This aims to be replaced as soon as possible by + the dedicated client's RPC. *) +let raw_tx_node_rpc node ~url = + let* rpc = RPC.Curl.get () in + match rpc with + | None -> assert false + | Some curl -> + let url = + Printf.sprintf + "%s/%s" + (Rollup_node.rpc_host node ^ ":" + ^ Int.to_string (Rollup_node.rpc_port node)) + url + in + curl ~url + +(* FIXME/TORU: Must be replaced by the Tx_client.get_balance command *) +let tx_client_get_balance ~tx_node ~block ~ticket_id ~tz4_address = + let* wrapped_result = + raw_tx_node_rpc + tx_node + ~url: + ("context/" ^ block ^ "/tickets/" ^ ticket_id ^ "/balance/" + ^ tz4_address) + in + let json = JSON.parse ~origin:"tx_client_get_balance" wrapped_result in + match JSON.(json |-> "value" |> as_int_opt) with + | Some level -> Lwt.return level + | None -> Test.fail "Cannot retrieve balance of tz4 address %s" tz4_address + +(* Returns the ticket hash, if any, of a given operation. *) +let get_ticket_hash_from_op op = + let metadata = JSON.(op |-> "contents" |=> 0 |-> "metadata") in + let result = + JSON.(metadata |-> "internal_operation_results" |=> 0 |-> "result") + in + let kind = + JSON.( + metadata |-> "internal_operation_results" |=> 0 |-> "parameters" + |-> "entrypoint" |> as_string) + in + let deposit = "deposit" in + if not String.(equal kind deposit) then + Test.fail + "The internal operation was expected to be a %s but is a %s" + deposit + kind ; + let status = JSON.(result |-> "status" |> as_string_opt) in + match status with + | Some v when String.(equal v "applied") -> + let ticket_hash = JSON.(result |-> "ticket_hash" |> as_string) in + Lwt.return ticket_hash + | None | Some _ -> Test.fail "The contract origination failed" + +(* The contract is expecting a parameter of the form: + (Pair tx_rollup_txr1_address tx_rollup_tz4_address) *) +let make_tx_rollup_deposit_argument txr1 tz4 = + "( Pair " ^ "\"" ^ txr1 ^ "\" \"" ^ tz4 ^ "\")" + +(* FIXME/TORU: we should merge this into Tezos_crypto.Bls *) +module Bls_public_key_hash = struct + include + Tezos_crypto.Blake2B.Make + (Tezos_crypto.Base58) + (struct + let name = "Bls12_381.Public_key_hash" + + let title = "A Bls12_381 public key hash" + + let b58check_prefix = "\006\161\166" (* tz4(36) *) + + let size = Some 20 + end) +end + +let generate_bls_addr ?alias:_ _client = + (* FIXME/TORU: we should use the the client to generate keys *) + let seed = + let rng_state = Random.State.make_self_init () in + Bytes.init 32 (fun _ -> char_of_int @@ Random.State.int rng_state 255) + in + let sk = Bls12_381.Signature.generate_sk seed in + let pk = Bls12_381.Signature.MinPk.derive_pk sk in + let pkh = + Bls_public_key_hash.hash_bytes [Bls12_381.Signature.MinPk.pk_to_bytes pk] + in + Log.info + "A new BLS key was generated: %s" + (Bls_public_key_hash.to_b58check pkh) ; + (pkh, pk, sk) + +let check_tz4_balance ~tx_node ~block ~ticket_id ~tz4_address ~expected_balance + = + let* tz4_balance = + tx_client_get_balance ~tx_node ~block ~ticket_id ~tz4_address + in + Check.( + ( = ) + tz4_balance + expected_balance + int + ~error_msg: + (Format.sprintf + "The balance of %s was expected to be %d instead of %d." + tz4_address + expected_balance + tz4_balance)) ; + unit + +(* Checks that the a ticket can be transfered from the L1 to the rollup. *) +let test_ticket_deposit_from_l1_to_l2 = + Protocol.register_test + ~__FILE__ + ~title:"TX_rollup: deposit ticket from l1 to l2" + ~tags:["tx_rollup"; "deposit"; "ticket"] + (fun protocol -> + let* parameter_file = get_rollup_parameter_file ~protocol in + let* (node, client) = + Client.init_with_protocol ~parameter_file `Client ~protocol () + in + let operator = Constant.bootstrap1.public_key_hash in + let* (tx_rollup_hash, tx_node) = + init_and_run_rollup_node ~operator node client + in + let* contract_id = + Client.originate_contract + ~alias:"rollup_deposit" + ~amount:Tez.zero + ~src:"bootstrap1" + ~prg:"file:./tezt/tests/contracts/proto_alpha/tx_rollup_deposit.tz" + ~init:"Unit" + ~burn_cap:Tez.(of_int 1) + client + in + let* () = Client.bake_for client in + let* _ = Node.wait_for_level node 2 in + Log.info + "The tx_rollup_deposit %s contract was successfully originated" + contract_id ; + let (bls_pkh, _, _) = generate_bls_addr client in + let bls_pkh_str = Bls_public_key_hash.to_b58check bls_pkh in + let arg = make_tx_rollup_deposit_argument tx_rollup_hash bls_pkh_str in + (* This smart contract call will transfer 10 tickets to the + given address. *) + let* () = + Client.transfer + ~gas_limit:100_000 + ~fee:Tez.one + ~amount:Tez.zero + ~burn_cap:Tez.one + ~storage_limit:10_000 + ~giver:"bootstrap1" + ~receiver:contract_id + ~arg + client + in + let* () = Client.bake_for client in + let* _ = Node.wait_for_level node 3 in + (* Get the operation containing the ticket transfer. We assume + that only one operation is issued in this block. *) + let* op = + Client.rpc + Client.GET + ["chains"; "main"; "blocks"; "head"; "operations"; "3"; "0"] + client + in + let* ticket_id = get_ticket_hash_from_op op in + Log.info "Ticket %s was successfully emitted" ticket_id ; + let* () = + check_tz4_balance + ~tx_node + ~block:"head" + ~ticket_id + ~tz4_address:bls_pkh_str + ~expected_balance:10 + in + unit) + let register ~protocols = test_node_configuration protocols ; test_tx_node_origination protocols ; - test_tx_node_store_inbox protocols + test_tx_node_store_inbox protocols ; + test_ticket_deposit_from_l1_to_l2 protocols From 24c63c073c80c88f90e8890633f599242c853972 Mon Sep 17 00:00:00 2001 From: Victor Allombert Date: Thu, 3 Mar 2022 09:27:15 +0100 Subject: [PATCH 025/100] Tezt/Tx_rollup: test l2 to l2 transfers --- tezt/tests/tx_rollup_node.ml | 200 ++++++++++++++++++++++++++++++++++- 1 file changed, 199 insertions(+), 1 deletion(-) diff --git a/tezt/tests/tx_rollup_node.ml b/tezt/tests/tx_rollup_node.ml index 105dce6332..9716e5edeb 100644 --- a/tezt/tests/tx_rollup_node.ml +++ b/tezt/tests/tx_rollup_node.ml @@ -410,8 +410,206 @@ let test_ticket_deposit_from_l1_to_l2 = in unit) +let sign_transaction sks txs = + let open Tezos_protocol_alpha.Protocol in + let buf = + Data_encoding.Binary.to_bytes_exn + Tx_rollup_l2_batch.V1.transaction_encoding + txs + in + List.map (fun sk -> Bls12_381.Signature.MinPk.Aug.sign sk buf) sks + +let craft_tx ~counter ~signer ~dest ~ticket qty = + let open Tezos_protocol_alpha.Protocol in + let qty = Tx_rollup_l2_qty.of_int64_exn qty in + let l2_addr = Tx_rollup_l2_address.of_b58check_exn dest in + let destination = Tx_rollup_l2_batch.Layer2 (Indexable.from_value l2_addr) in + let ticket_hash = + Indexable.from_value + (Tezos_protocol_alpha.Protocol.Alpha_context.Ticket_hash.of_b58check_exn + ticket) + in + let content = Tx_rollup_l2_batch.V1.{destination; ticket_hash; qty} in + let signer = Indexable.from_value signer in + Tx_rollup_l2_batch.V1.{signer; counter; contents = [content]} + +let aggregate_signature_exn signatures = + match Bls12_381.Signature.MinPk.aggregate_signature_opt signatures with + | Some res -> res + | None -> invalid_arg "aggregate_signature_exn" + +let batch signatures contents = + let open Tezos_protocol_alpha.Protocol.Tx_rollup_l2_batch.V1 in + let aggregated_signature = aggregate_signature_exn signatures in + {aggregated_signature; contents} + +let craft_batch + (transactions : + ( 'signer, + 'content ) + Tezos_protocol_alpha.Protocol.Tx_rollup_l2_batch.V1.transaction + list) sks = + let signatures = + List.map2 (fun txs sk -> sign_transaction sk txs) transactions sks + |> List.concat + in + batch signatures transactions + +(* FIXME/TORU: Must be replaced by the Tx_client.get_inbox command *) +let tx_client_get_inbox ~tx_node ~block = + let* wrapped_result = + raw_tx_node_rpc tx_node ~url:("block/" ^ block ^ "/inbox") + in + let json = JSON.parse ~origin:"tx_client_get_balance" wrapped_result in + Lwt.return json + +(* Checks that the a ticket can be transfered within the rollup. *) +let test_l2_to_l2_transaction = + Protocol.register_test + ~__FILE__ + ~title:"TX_rollup: l2 to l2 transaction" + ~tags:["tx_rollup"; "rollup"; "internal"; "transaction"] + (fun protocol -> + let* parameter_file = get_rollup_parameter_file ~protocol in + let* (node, client) = + Client.init_with_protocol ~parameter_file `Client ~protocol () + in + let operator = Constant.bootstrap1.public_key_hash in + let* (tx_rollup_hash, tx_node) = + init_and_run_rollup_node ~operator node client + in + let* contract_id = + Client.originate_contract + ~alias:"rollup_deposit" + ~amount:Tez.zero + ~src:"bootstrap1" + ~prg:"file:./tezt/tests/contracts/proto_alpha/tx_rollup_deposit.tz" + ~init:"Unit" + ~burn_cap:Tez.(of_int 1) + client + in + let* () = Client.bake_for client in + let* _ = Node.wait_for_level node 3 in + Log.info + "The tx_rollup_deposit %s contract was successfully originated" + contract_id ; + (* Genarating some identities *) + let (bls_1_pkh, bls_pk_1, bls_sk_1) = generate_bls_addr client in + let bls_pkh_1_str = Bls_public_key_hash.to_b58check bls_1_pkh in + (* FIXME/TORU: Use the client *) + let (bls_2_pkh, _, _) = generate_bls_addr client in + let bls_pkh_2_str = Bls_public_key_hash.to_b58check bls_2_pkh in + let arg_1 = + make_tx_rollup_deposit_argument tx_rollup_hash bls_pkh_1_str + in + let* () = + Client.transfer + ~gas_limit:100_000 + ~fee:Tez.one + ~amount:Tez.zero + ~burn_cap:Tez.one + ~storage_limit:10_000 + ~giver:"bootstrap1" + ~receiver:contract_id + ~arg:arg_1 + client + in + let* () = Client.bake_for client in + let* _ = Node.wait_for_level node 4 in + let* _ = Rollup_node.wait_for_tezos_level tx_node 4 in + let* op = + Client.rpc + Client.GET + ["chains"; "main"; "blocks"; "head"; "operations"; "3"; "0"] + client + in + let* ticket_id = get_ticket_hash_from_op op in + Log.info "Ticket %s was successfully emitted" ticket_id ; + let* () = + check_tz4_balance + ~tx_node + ~block:"head" + ~ticket_id + ~tz4_address:bls_pkh_1_str + ~expected_balance:10 + in + let arg_2 = + make_tx_rollup_deposit_argument tx_rollup_hash bls_pkh_2_str + in + let* () = + Client.transfer + ~gas_limit:100_000 + ~fee:Tez.one + ~amount:Tez.zero + ~burn_cap:Tez.one + ~storage_limit:10_000 + ~giver:"bootstrap1" + ~receiver:contract_id + ~arg:arg_2 + client + in + let* () = Client.bake_for client in + let* _ = Node.wait_for_level node 5 in + let* _ = Rollup_node.wait_for_tezos_level tx_node 5 in + let* () = + check_tz4_balance + ~tx_node + ~block:"head" + ~ticket_id + ~tz4_address:bls_pkh_2_str + ~expected_balance:10 + in + Log.info "Crafting a l2 transaction" ; + (* FIXME/TORU: Use the client *) + let tx = + craft_tx + ~counter:1L + ~signer:bls_pk_1 + ~dest:bls_pkh_2_str + ~ticket:ticket_id + 1L + in + Log.info "Crafting a batch" ; + let batch = craft_batch [[tx]] [[bls_sk_1]] in + let raw_batch = + Data_encoding.Binary.to_bytes_exn + Tezos_protocol_alpha.Protocol.Tx_rollup_l2_batch.encoding + (Tezos_protocol_alpha.Protocol.Tx_rollup_l2_batch.V1 batch) + in + Log.info "Submiting a batch" ; + let*! () = + Client.Tx_rollup.submit_batch + ~content:(Bytes.to_string raw_batch) + ~rollup:tx_rollup_hash + ~src:operator + client + in + Log.info "Baking the batch" ; + let* () = Client.bake_for client in + let* _ = Node.wait_for_level node 6 in + let* _ = Rollup_node.wait_for_tezos_level tx_node 6 in + let* _node_inbox = get_node_inbox tx_node in + Format.printf "ticket 1 %s@." ticket_id ; + let* () = + check_tz4_balance + ~tx_node + ~block:"head" + ~ticket_id + ~tz4_address:bls_pkh_1_str + ~expected_balance:9 + and* () = + check_tz4_balance + ~tx_node + ~block:"head" + ~ticket_id + ~tz4_address:bls_pkh_2_str + ~expected_balance:11 + in + unit) + let register ~protocols = test_node_configuration protocols ; test_tx_node_origination protocols ; test_tx_node_store_inbox protocols ; - test_ticket_deposit_from_l1_to_l2 protocols + test_ticket_deposit_from_l1_to_l2 protocols ; + test_l2_to_l2_transaction protocols From b2829a164b117e241dc483b9973610c7e3b0aeec Mon Sep 17 00:00:00 2001 From: Richard Davison Date: Mon, 14 Mar 2022 17:26:57 +0000 Subject: [PATCH 026/100] Manifest: bin_accuser --- src/proto_011_PtHangz2/bin_accuser/dune | 36 ++++++++++--------- .../bin_accuser/dune-project | 1 - .../tezos-accuser-011-PtHangz2.opam | 4 ++- src/proto_012_Psithaca/bin_accuser/dune | 36 ++++++++++--------- .../bin_accuser/dune-project | 1 - .../tezos-accuser-012-Psithaca.opam | 4 ++- src/proto_alpha/bin_accuser/dune | 36 ++++++++++--------- src/proto_alpha/bin_accuser/dune-project | 1 - .../bin_accuser/tezos-accuser-alpha.opam | 4 ++- 9 files changed, 69 insertions(+), 54 deletions(-) diff --git a/src/proto_011_PtHangz2/bin_accuser/dune b/src/proto_011_PtHangz2/bin_accuser/dune index f4f72161b2..77b09a7257 100644 --- a/src/proto_011_PtHangz2/bin_accuser/dune +++ b/src/proto_011_PtHangz2/bin_accuser/dune @@ -1,20 +1,24 @@ -; build static executable with --profile static -(env - (static - (flags (:standard - -ccopt -static)))) +(env (static (flags (:standard -ccopt -static)))) (executable (name main_accuser_011_PtHangz2) - (instrumentation (backend bisect_ppx)) (public_name tezos-accuser-011-PtHangz2) - (libraries tezos-client-base-unix - tezos-client-commands - tezos-baking-011-PtHangz2-commands) - (flags (:standard -open Tezos_base__TzPervasives - -open Tezos_protocol_011_PtHangz2 - -open Tezos_client_011_PtHangz2 - -open Tezos_client_commands - -open Tezos_baking_011_PtHangz2_commands - -open Tezos_stdlib_unix - -open Tezos_client_base_unix))) + (package tezos-accuser-011-PtHangz2) + (instrumentation (backend bisect_ppx)) + (libraries + tezos-base + tezos-protocol-011-PtHangz2 + tezos-client-011-PtHangz2 + tezos-client-commands + tezos-baking-011-PtHangz2-commands + tezos-stdlib-unix + tezos-client-base-unix) + (flags + (:standard + -open Tezos_base.TzPervasives + -open Tezos_protocol_011_PtHangz2 + -open Tezos_client_011_PtHangz2 + -open Tezos_client_commands + -open Tezos_baking_011_PtHangz2_commands + -open Tezos_stdlib_unix + -open Tezos_client_base_unix))) diff --git a/src/proto_011_PtHangz2/bin_accuser/dune-project b/src/proto_011_PtHangz2/bin_accuser/dune-project index 97aa51842c..47aa0dd4c4 100644 --- a/src/proto_011_PtHangz2/bin_accuser/dune-project +++ b/src/proto_011_PtHangz2/bin_accuser/dune-project @@ -1,3 +1,2 @@ (lang dune 2.9) (formatting (enabled_for ocaml)) -(name tezos-accuser-alpha) diff --git a/src/proto_011_PtHangz2/bin_accuser/tezos-accuser-011-PtHangz2.opam b/src/proto_011_PtHangz2/bin_accuser/tezos-accuser-011-PtHangz2.opam index 82e6e5b196..0075534f7b 100644 --- a/src/proto_011_PtHangz2/bin_accuser/tezos-accuser-011-PtHangz2.opam +++ b/src/proto_011_PtHangz2/bin_accuser/tezos-accuser-011-PtHangz2.opam @@ -1,6 +1,6 @@ opam-version: "2.0" maintainer: "contact@tezos.com" -authors: [ "Tezos devteam" ] +authors: ["Tezos devteam"] homepage: "https://www.tezos.com/" bug-reports: "https://gitlab.com/tezos/tezos/issues" dev-repo: "git+https://gitlab.com/tezos/tezos.git" @@ -8,9 +8,11 @@ license: "MIT" depends: [ "dune" { >= "2.9" } "tezos-base" + "tezos-protocol-011-PtHangz2" "tezos-client-011-PtHangz2" "tezos-client-commands" "tezos-baking-011-PtHangz2-commands" + "tezos-stdlib-unix" "tezos-client-base-unix" ] build: [ diff --git a/src/proto_012_Psithaca/bin_accuser/dune b/src/proto_012_Psithaca/bin_accuser/dune index 4da948f22e..9e5c37f1d0 100644 --- a/src/proto_012_Psithaca/bin_accuser/dune +++ b/src/proto_012_Psithaca/bin_accuser/dune @@ -1,20 +1,24 @@ -; build static executable with --profile static -(env - (static - (flags (:standard - -ccopt -static)))) +(env (static (flags (:standard -ccopt -static)))) (executable (name main_accuser_012_Psithaca) - (instrumentation (backend bisect_ppx)) (public_name tezos-accuser-012-Psithaca) - (libraries tezos-client-base-unix - tezos-client-commands - tezos-baking-012-Psithaca-commands) - (flags (:standard -open Tezos_base__TzPervasives - -open Tezos_protocol_012_Psithaca - -open Tezos_client_012_Psithaca - -open Tezos_client_commands - -open Tezos_baking_012_Psithaca_commands - -open Tezos_stdlib_unix - -open Tezos_client_base_unix))) + (package tezos-accuser-012-Psithaca) + (instrumentation (backend bisect_ppx)) + (libraries + tezos-base + tezos-protocol-012-Psithaca + tezos-client-012-Psithaca + tezos-client-commands + tezos-baking-012-Psithaca-commands + tezos-stdlib-unix + tezos-client-base-unix) + (flags + (:standard + -open Tezos_base.TzPervasives + -open Tezos_protocol_012_Psithaca + -open Tezos_client_012_Psithaca + -open Tezos_client_commands + -open Tezos_baking_012_Psithaca_commands + -open Tezos_stdlib_unix + -open Tezos_client_base_unix))) diff --git a/src/proto_012_Psithaca/bin_accuser/dune-project b/src/proto_012_Psithaca/bin_accuser/dune-project index 97aa51842c..47aa0dd4c4 100644 --- a/src/proto_012_Psithaca/bin_accuser/dune-project +++ b/src/proto_012_Psithaca/bin_accuser/dune-project @@ -1,3 +1,2 @@ (lang dune 2.9) (formatting (enabled_for ocaml)) -(name tezos-accuser-alpha) diff --git a/src/proto_012_Psithaca/bin_accuser/tezos-accuser-012-Psithaca.opam b/src/proto_012_Psithaca/bin_accuser/tezos-accuser-012-Psithaca.opam index d1b3fe99ff..61051a7726 100644 --- a/src/proto_012_Psithaca/bin_accuser/tezos-accuser-012-Psithaca.opam +++ b/src/proto_012_Psithaca/bin_accuser/tezos-accuser-012-Psithaca.opam @@ -1,6 +1,6 @@ opam-version: "2.0" maintainer: "contact@tezos.com" -authors: [ "Tezos devteam" ] +authors: ["Tezos devteam"] homepage: "https://www.tezos.com/" bug-reports: "https://gitlab.com/tezos/tezos/issues" dev-repo: "git+https://gitlab.com/tezos/tezos.git" @@ -8,9 +8,11 @@ license: "MIT" depends: [ "dune" { >= "2.9" } "tezos-base" + "tezos-protocol-012-Psithaca" "tezos-client-012-Psithaca" "tezos-client-commands" "tezos-baking-012-Psithaca-commands" + "tezos-stdlib-unix" "tezos-client-base-unix" ] build: [ diff --git a/src/proto_alpha/bin_accuser/dune b/src/proto_alpha/bin_accuser/dune index fdccc1691e..cb3de5394e 100644 --- a/src/proto_alpha/bin_accuser/dune +++ b/src/proto_alpha/bin_accuser/dune @@ -1,20 +1,24 @@ -; build static executable with --profile static -(env - (static - (flags (:standard - -ccopt -static)))) +(env (static (flags (:standard -ccopt -static)))) (executable (name main_accuser_alpha) - (instrumentation (backend bisect_ppx)) (public_name tezos-accuser-alpha) - (libraries tezos-client-base-unix - tezos-client-commands - tezos-baking-alpha-commands) - (flags (:standard -open Tezos_base__TzPervasives - -open Tezos_protocol_alpha - -open Tezos_client_alpha - -open Tezos_client_commands - -open Tezos_baking_alpha_commands - -open Tezos_stdlib_unix - -open Tezos_client_base_unix))) + (package tezos-accuser-alpha) + (instrumentation (backend bisect_ppx)) + (libraries + tezos-base + tezos-protocol-alpha + tezos-client-alpha + tezos-client-commands + tezos-baking-alpha-commands + tezos-stdlib-unix + tezos-client-base-unix) + (flags + (:standard + -open Tezos_base.TzPervasives + -open Tezos_protocol_alpha + -open Tezos_client_alpha + -open Tezos_client_commands + -open Tezos_baking_alpha_commands + -open Tezos_stdlib_unix + -open Tezos_client_base_unix))) diff --git a/src/proto_alpha/bin_accuser/dune-project b/src/proto_alpha/bin_accuser/dune-project index 97aa51842c..47aa0dd4c4 100644 --- a/src/proto_alpha/bin_accuser/dune-project +++ b/src/proto_alpha/bin_accuser/dune-project @@ -1,3 +1,2 @@ (lang dune 2.9) (formatting (enabled_for ocaml)) -(name tezos-accuser-alpha) diff --git a/src/proto_alpha/bin_accuser/tezos-accuser-alpha.opam b/src/proto_alpha/bin_accuser/tezos-accuser-alpha.opam index 78eced602d..e0d01ecfea 100644 --- a/src/proto_alpha/bin_accuser/tezos-accuser-alpha.opam +++ b/src/proto_alpha/bin_accuser/tezos-accuser-alpha.opam @@ -1,6 +1,6 @@ opam-version: "2.0" maintainer: "contact@tezos.com" -authors: [ "Tezos devteam" ] +authors: ["Tezos devteam"] homepage: "https://www.tezos.com/" bug-reports: "https://gitlab.com/tezos/tezos/issues" dev-repo: "git+https://gitlab.com/tezos/tezos.git" @@ -8,9 +8,11 @@ license: "MIT" depends: [ "dune" { >= "2.9" } "tezos-base" + "tezos-protocol-alpha" "tezos-client-alpha" "tezos-client-commands" "tezos-baking-alpha-commands" + "tezos-stdlib-unix" "tezos-client-base-unix" ] build: [ From de1b47a915211394c78056ddc42f623fd5d3a7a5 Mon Sep 17 00:00:00 2001 From: "@sol.lederer" Date: Mon, 7 Mar 2022 08:01:34 -0500 Subject: [PATCH 027/100] doc: split Error Monad into 4 subfiles --- docs/developer/error_monad.rst | 2436 +----------------- docs/developer/error_monad_p1_result.rst | 997 +++++++ docs/developer/error_monad_p2_tzresult.rst | 587 +++++ docs/developer/error_monad_p3_advanced.rst | 340 +++ docs/developer/error_monad_p4_appendices.rst | 508 ++++ 5 files changed, 2446 insertions(+), 2422 deletions(-) create mode 100644 docs/developer/error_monad_p1_result.rst create mode 100644 docs/developer/error_monad_p2_tzresult.rst create mode 100644 docs/developer/error_monad_p3_advanced.rst create mode 100644 docs/developer/error_monad_p4_appendices.rst diff --git a/docs/developer/error_monad.rst b/docs/developer/error_monad.rst index 262ad06516..b29af70dcf 100644 --- a/docs/developer/error_monad.rst +++ b/docs/developer/error_monad.rst @@ -23,2433 +23,25 @@ foreshadowing is only useful in that it lets you know that the information is coming and that you can move on with a partial understanding. On subsequent reads, it helps putting things in context. -Note that the core of the tutorial focuses on error management in Octez. -A short section gives additional information about error management in -the protocol. +Note that the core of this tutorial focuses on error management in Octez. +For a short section on error management in the protocol see Part 3 :ref:`error_monad_within_protocol`. -Part 1: ``result``, Lwt, and Lwt-``result`` -------------------------------------------- +.. toctree:: + :maxdepth: 2 -The ``result`` type -~~~~~~~~~~~~~~~~~~~ + error_monad_p1_result -The type ``result`` is part of the standard library of OCaml. It is -defined as +.. toctree:: + :maxdepth: 2 -:: + error_monad_p2_tzresult - type ('a, 'b) result = - | Ok of 'a - | Error of 'b +.. toctree:: + :maxdepth: 2 -(See `reference -manual `__.) + error_monad_p3_advanced -The constructors of the ``result`` type have meaning: ``Ok`` is for -normal, successful cases that carry a value that is somewhat expected. -``Error`` is for abnormal, failure cases that carry information about -what went wrong. E.g., - -:: - - let get a index = - if index < 0 then - Error "negative index in array access" - else if index >= Array.length a then - Error "index beyond length in array access" - else - Ok a.(index) - -You can see the ``result`` type as an opinionated ``either``: a -left-or-right sum type where the left and right side have distinct -roles. Or you can see the ``result`` type as a buffed-up ``option`` -type: a type that either carries a value or doesn’t (but in this case it -carries an error instead). - -Exercises -^^^^^^^^^ - -- Write the implementation for - - :: - - (** [to_option r] is [Some x] if [r] is [Ok x]. Otherwise it is [None]. *) - val to_option : ('a, unit) result -> 'a option - -- Write the implementation for - - :: - - (** [to_option ?log r] is [Some x] if [r] is [Ok x]. Otherwise it calls - [log e] and returns [None] if [r] is [Error e]. By default [log] is - [ignore]. *) - val to_option : ?log:('e -> unit) -> ('a, 'e) result -> 'a option - -- Write the implementation for - - :: - - (** [catch f] is [Ok (f ())] except if [f] raises an exception [exc] in - which case it is [Error exc]. *) - val catch : (unit -> 'a) -> ('a, exn) result - -The binding operator -~~~~~~~~~~~~~~~~~~~~ - -Working directly with the ``result`` type can quickly become cumbersome. -Consider, for example the following code. - -:: - - (** [compose3 f g h x] is [f (g (h x))] except that it handles errors. *) - let compose3 f g h x - match h x with - | Error e -> Error e - | Ok y -> - match g y with - | Error e -> Error e - | Ok z -> - f z - -The nested ``match``-``with`` constructs lead to further and further -indentation. The ``Error`` cases are all identical and simply add noise. - -To circumvent this, in Octez we use a `binding -operator `__: a user-defined -``let``-binding. Specifically, you can open the ``Result_syntax`` module -which includes the binding operator ``let*`` dedicated to ``result``. - -:: - - (** [compose3 f g h x] is [f (g (h x))] except that it handles errors. *) - let compose3 f g h x - let open Result_syntax in (* adds [let*] in scope *) - let* y = h x in - let* z = g y in - f z - -An expression ``let* x = e in e'`` is equivalent to -``Result.bind e (fun x -> e')`` and also to -``match e with | Error err -> Error err | Ok x -> e'``. In all of these forms, -the expression ``e'`` is evaluated if and only if the expression ``e`` is -successful (i.e., evaluates to ``Ok``). - -.. _exercises-1: - -Exercises -^^^^^^^^^ - -- Rewrite the following code without ``match``-``with`` - - :: - - let apply2 (f, g) (x, y) = - match f x with - | Error e -> Error e - | Ok u -> - match g y with - | Error e -> Error e - | Ok v -> Ok (u, v) - - Did you remember to open the syntax module? - -- Write the implementation for - - :: - - (** [map f [x1; x2; x3; ..]] is a list [[y1; y2; y3; ..]] where [y1 = f x1], - [y2 = f x2], etc. except if [f] is fails on one of the inputs, in which - case it is an [Error] carrying the same error as [f]'s. *) - val map : ('a -> ('b, 'err) result) -> 'a list -> ('a list, 'err) result - - Note that this exercise is for learning only. You won’t need to write - this function in Octez. Indeed, a helper function which does exactly - that is provided in the extended standard library of Octez. - -Aside: the ``Error_monad`` module is opened everywhere -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -In Octez, the ``Error_monad`` module provides types and values for error -management. It is part of the ``tezos-error-monad`` package. And it is -opened in most of the source code. Apart from some specific libraries -(discussed later), the content of this module is already in scope. - -The ``Error_monad`` module contains the ``Result_syntax`` module. This -is why you can use ``let open Result_syntax in`` directly in your own -functions. - -The ``Error_monad`` module contains other modules and functions and -types which you will learn about later. - -Recovering from errors -~~~~~~~~~~~~~~~~~~~~~~ - -When given a value of type ``result``, you can inspect its content to -determine if it is an ``Ok`` or an ``Error``. You can use this feature -to recover from the failures. - -:: - - match e with - | Ok x -> do_something x - | Error e -> do_something_else e - -Recovering can mean different things depending on the task that failed -and the error with which it failed. Sometimes you just want to retry, -sometimes you want to retry with a different input, sometimes you want -to propagate the error, sometimes you want to log the error and continue -as if it hadn’t happened, etc. - -:: - - let rec write data = - match write_to_disk data with - | Ok () -> () - | Error EAGAIN -> write data (* again: try again *) - | Error ENOSPC -> Stdlib.exit 1 (* no space left on device: escalate to exit *) - -There is a correspondence between a ``match``-``with`` around a -``result`` and a ``try``-``with``. Both are for recovering from -failures. However, in Octez, you will mostly use a ``match``-``with`` -around a ``result``, because we favour ``result`` over exceptions. You -may use the ``try``-``with`` construct when interfacing with an external -library which uses exceptions. - -There are several ways to use the ``match``-``with`` recovery with the -binding operator from ``Result_syntax``. Depending on the size of the -expression you are recovering from, one may be more readable than the -other. Choose accordingly. - -You can simply place the expression directly inside the -``match``-``with``. - -:: - - match - let* x = get_horizontal point in - let* y = get_vertical point in - Ok (x, y) - with - | Ok (x, y) -> .. - | Error e -> .. - -Alternatively, if the expression grows too much in size or in -complexity, you can move the expression inside a vanilla -``let``-binding: ``let r = .. in match r with ..``. - -Alternatively, if the expression grows even more, or if the expression -may be re-used in other parts of the code, you may move the expression -inside a vanilla function which you can call inside the ``match``-``with``. - -You can also use the functions from `the standard library’s Result -module `__. Note however, that some -of these functions are shadowed in the extended library of Octez, which -you will learn more about later. - -Mixing different kinds of errors -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Occasionally, you may have to call a function which returns a value of -type, say, ``(_, unit) result`` and one, say, ``(_, string) result``. In -this case, you cannot simply bind the two expressions as is. -Specifically, the type checker will complain. You can see the constraint -you would be breaking in the type of ``let*`` where the two error types -are the same (``'e``): - -:: - - val ( let* ) : ('a, 'e) result -> ('a -> ('b, 'e) result) -> ('b, 'e) result - -When you need to mix those function, you have to either handle the -errors of each independently (see the section above about recovering from -errors) or you need to convert the errors so they have the same type. -You should use ``Result.map_error`` to do that. - -:: - - let* cfg = - Result.map_error (fun () -> "Error whilst reading configuration") - @@ read_configuration () - in - .. - -The ``Result_syntax`` module -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You have already learned about the ``let*`` binding operator from the -``Result_syntax``. But there are other values you can use from this -module. - -The following functions form the core of the ``Result_syntax`` module. - -- ``let*``: a binding operator to continue with the value in the ``Ok`` - constructor or interrupt with the error in the ``Error`` constructor. - - ``let* x = e in e'`` is equivalent to - ``match e with Error err -> Error err | Ok x -> e'``. - - (See above for examples and more details.) - -- ``return : 'a -> ('a, 'e) result``: the expression ``return x`` is - equivalent to ``Ok x``. The function is included for consistency with - other syntax modules presented later. You can use either form. - -- ``fail : 'e -> ('a, 'e) result``: the expression ``fail e`` is - equivalent to ``Error e``. The function is included for consistency - with other syntax modules presented later. You can use either form. - -The following functions offer additional, less often used -functionalities. - -- ``both : ('a, 'e) result -> ('b, 'e) result -> ('a * 'b, 'e list) result``: - the expression ``both e1 e2`` is ``Ok`` if both expressions - evaluate to ``Ok`` and ``Error`` otherwise. - - Note that the expression ``both e1 e2`` is different from the - expression ``let* x = e1 in let* y = e2 in return (x, y)``. In the - former (``both``) version, both ``e1`` and ``e2`` are evaluated, - regardless of success/failure of ``e1`` and ``e2``. In the latter - (``let*``-``let*``) version, ``e2`` is evaluated if and only if - ``e1`` is successful. - - This distinction is important when the expressions ``e1`` and ``e2`` - have side effects: ``both (f ()) (g ())``. - -- ``all : ('a, 'e) result list -> ('a list, 'e list) result``: the - function ``all`` is a generalisation of ``both`` from tuples to - lists. - - Note that, as a generalisation of ``both``, in a call to the function - ``all``, all the elements of the list are evaluated, regardless of - success/failure of the elements: ``all (List.map f xs)``. - -- ``join : (unit, 'e) result list -> (unit, 'e list) result``: the - function ``join`` is a specialisation of ``all`` for lists of - unit-typed expressions (typically, for side-effects). - - Note that, as a specialisation of ``all``, in a call to the function - ``join``, all the elements of the list are evaluated, regardless of - success/failure of the elements: ``join (List.map f xs)``. - -The following functions do not provide new functionalities but they are -useful for small performance gains or for shorter syntax. - -- ``return_unit`` is equivalent to ``return ()`` but it avoids one - allocation. This is important in parts of the code that are - performance critical, and it is a good habit to take otherwise. - - | ``return_nil`` is equivalent to ``return []`` but it avoids one - allocation. - | ``return_true`` is equivalent to ``return true`` but it avoids one - allocation. - | ``return_false`` is equivalent to ``return false`` but it avoids - one allocation. - - | ``return_none`` is equivalent to ``return None`` but it avoids one - allocation. - | ``return_some x`` is equivalent to ``return (Some x)`` and it is - provided for completeness with ``return_none``. - -- ``let+`` is a binding operator similar to ``let*`` but when the - expression which follows the ``in`` returns a non-result value. In - other words, ``let+ x = e in e'`` is equivalent to - ``let* x = e in return (e')``. - - The ``let+`` is purely for syntactic conciseness (compared to the ``*`` - variant), use it if it makes - your code more readable. - -Lwt -~~~ - -In Octez, I/O and concurrency are handled using the Lwt library. With -Lwt you use *promises* to handle I/O and concurrency. You can think of -promises as data structures that are empty until they *resolve*, at -which point they hold a value. - -A promise for a value of type ``'a`` has type ``'a Lwt.t``. The function -``Lwt.bind : 'a t -> ('a -> 'b t) -> 'b t`` waits for the promise to -resolve (i.e., to carry a value of type ``'a``) before applying the -provided function. The expression ``bind p f`` is a promise which -resolves only once the promise ``p`` has resolved *and then* the promise -returned by ``f`` has resolved too. - -If you are not familiar with Lwt, you should check out `the official manual -`__ and `this -introduction `__ -before continuing. This is important. Do it. - -Unlike is mentioned in those separate resources on Lwt, in Octez, we -do not in general use the success/failure mechanism of Lwt. Instead, we -mostly rely on ``result`` (as mentioned above). - -Thus, in the rest of this tutorial we only consider the subset of Lwt -without failures. In practice, you might need to take care of exceptions -in some cases, but this is discussed in the later, more advanced parts of the -tutorial. - -The ``Lwt_syntax`` module -~~~~~~~~~~~~~~~~~~~~~~~~~ - -In Octez, because Lwt is pervasive, you need to bind promises often. To -make it easier, you can use the ``Lwt_syntax`` module. The -``Lwt_syntax`` module is made available everywhere by the -``Error_monad`` module. The ``Lwt_syntax`` module is similar to the -``Result_syntax`` module but for the Lwt monad (more about monads -later). - -- ``let*``: a binding operator to wait for the promise to resolve - before continuing. - - ``let* x = e in e'`` is a promise that resolves after ``e`` has - resolved to a given value and then ``e'`` has resolved with that - value carried by ``x``. - - Note that ``Lwt_syntax`` and ``Result_syntax`` (see above) both use - ``let*`` for their main binding operator. Consequently, the specific - meaning of ``let*`` depends on which module is open. This extends to - other syntax modules introduced later in this tutorial. - - (What if you need to use both Lwt and ``result``? Which syntax module - should you use? You will learn about that in the next section!) - -- ``return : 'a -> 'a Lwt.t``: the expression ``return x`` is equivalent to - ``Lwt.return x``. It is a promise that is already resolved with the value of - ``x``. - -- ``and*``: a binding operator alias for ``both`` (see below). You can - use it with ``let*`` the same way you use ``and`` with ``let``. - - :: - - let apply_triple f (x, y, z) = - let open Lwt_syntax in - let* u = f x - and* v = f y - and* w = f z - in - return (u, v, w) - - When you use ``and*``, the bound promises (``f x``, ``f y``, and - ``f z``) are evaluated concurrently, and the expression which follows - the ``in`` (``return ..``) is evaluated once all the bound promises - have all resolved. - -The following functions offer additional, less often used -functionalities. - -- ``both: 'a Lwt.t -> 'b Lwt.t -> ('a * 'b) Lwt.t``: the expression - ``both p q`` is a promise that resolves only once both promises - ``p`` and ``q`` (which make progress concurrently) have resolved. - - In practice, you will most likely use ``and*`` instead of both. - -- ``all: 'a Lwt.t list -> 'a list Lwt.t``: the function ``all`` is a - generalisation of ``both`` from tuples to lists. - - Note that, as a generalisation of ``both``, in a call to the function - ``all``, all the promises in the provided list make progress towards - resolution concurrently. - -- ``join : unit Lwt.t list -> unit Lwt.t``: the function ``join`` is a - specialisation of ``all`` to lists of units (i.e., side-effects). - -The following functions do not provide new functionalities but they are -useful for small performance gains or for shorter syntax. - -- ``return_unit`` is equivalent to ``return ()`` but it avoids one - allocation. This is important in parts of the code that are - performance critical, and it is a good habit to take otherwise. - - | ``return_nil`` is equivalent to ``return []`` but it avoids one - allocation. - | ``return_true`` is equivalent to ``return true`` but it avoids one - allocation. - | ``return_false`` is equivalent to ``return false`` but it avoids - one allocation. - - | ``return_none`` is equivalent to ``return None`` but it avoids one - allocation. - | ``return_some x`` is equivalent to ``return (Some x)`` and it is - provided for completeness. - - | ``return_ok x`` is equivalent to ``return (Ok x)`` and it is - provided for completeness. - | ``return_error x`` is equivalent to ``return (Error x)`` and it is - provided for completeness. - -- ``let+`` and ``and+`` are binding operators similar to ``let*`` and - ``and*`` but when the expression which follows the ``in`` returns a - non-promise value. In other words, ``let+ x = e1 and+ y = e2 in e`` is - equivalent to ``let* x = e1 and* y = e2 in return e``. - - The ``let+`` and ``and+`` are purely for syntactic conciseness (compared to - the ``*`` variants), use them if it makes your code more readable. - -Promises of results: Lwt and ``result`` together -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -In Octez, we have functions that perform I/O and also may fail. In this -case, the function returns a promise of a ``result``. This is the topic -of this section. - -Note that Lwt and ``result`` are orthogonal concerns. On the one hand, -Lwt is for concurrency, for automatically scheduling code around I/O, -for making progress on different parts of the program side-by-side. On -the other hand, ``result`` is for aborting computations, for handling -success/failures. It is because Lwt and ``result`` are orthogonal that -we can use them together. - -:: - - 'a --------------> ('a, 'e) result - | | - | | - V V - 'a Lwt.t ---------> ('a, 'e) result Lwt.t - -When we combine Lwt and ``result`` for control-flow purpose we combine -both of the orthogonal behaviours. We can achieve this combined -behaviour “by hand”. However, doing so requires mixing -``Lwt_syntax.( let* )`` and regular ``match``-``with``: - -:: - - let apply2 (f, g) (x, y) = - let open Lwt_syntax in - let* r = f x in - match r with - | Error e -> return (Error e) - | Ok u -> - let* r = g y in - match r with - | Error e -> return (Error e) - | Ok v -> return (Ok (u, v)) - -This is interesting to consider because it shows the two orthogonal -features of control-flow separately: wait for the promise to resolve, -and check for errors. However, in practice, this becomes cumbersome even -faster than when working with plain ``result`` values. - -To make this easier, in Octez we use a binding operator. Specifically, -you can open the ``Lwt_result_syntax`` (instead of the other syntax -modules) which includes a binding operator dedicated to promises of -``result``. - -:: - - let apply2 (f, g) (x, y) = - let open Lwt_result_syntax in - let* u = f x in - let* v = g y in - return (u, v) - -When a promise resolves to ``Ok`` we say that it resolves successfully. -When it resolves to ``Error`` we say that it resolves unsuccessfully or -that it fails. - -.. _exercises-2: - -Exercises -^^^^^^^^^ - -- Rewrite the following code without ``match``-``with`` - - :: - - let compose3 f g h x - let open Lwt_syntax in - let* r = h x in - match r with - | Error e -> return (Error e) - | Ok y -> - let* s = g y in - match s with - | Error e -> return (Error e) - | Ok z -> - f z - - Did you remember to change the opened syntax module? - -The ``Lwt_result_syntax`` module -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Octez provides the ``Lwt_result_syntax`` module to help handle promises -of results. - -- ``let*``: a binding operator to wait for the promise to resolve - before continuing with the value in the ``Ok`` constructor or - interrupting with the error in the ``Error`` constructor. - - Note how the ``let*`` binding operator combines the behaviour of - ``Lwt_syntax.( let* )`` and ``Result_syntax.( let* )``. Also note - that the different ``let*``\ s are differentiated by context; - specifically by what syntax module has been opened. - -- ``return: 'a -> ('a, 'e) result Lwt.t``: the expression ``return x`` - is a promise already successfully resolved to ``x``. More formally, - ``return x`` is equivalent to - ``Lwt_syntax.return (Result_syntax.return x)``. - -- ``fail: 'e -> ('a, 'e) result Lwt.t``: the expression ``fail e`` is a - promise already unsuccessfully resolved with the error ``e``. More - formally, ``fail e`` is equivalent to - ``Lwt_syntax.return (Result_syntax.fail e)``. - -The following functions offer additional, less often used -functionalities. - -- ``both : ('a, 'e) result Lwt.t -> ('b, 'e) result Lwt.t -> ('a * 'b, 'e list) result Lwt.t``: - the expression ``both p1 p2`` is a promise that resolves - successfully if both ``p1`` and ``p2`` resolve successfully. It - resolves unsuccessfully if either ``p1`` or ``p2`` resolve - unsuccessfully. - - Note that in the expression ``both p1 p2``, both promises ``p1`` and - ``p2`` are evaluated concurrently. Moreover, the returned promise - only resolves once both promises have resolved, even if one resolves - unsuccessfully. - - Note that this syntax module does not offer ``and*`` as a binding - operator alias for ``both``. This is because, as with - ``Result_syntax``, the type for errors in ``both`` is not stable (it - is ``'e`` on the argument side and ``'e list`` on the return side). - This hinders practical uses of ``and*``. - -- ``all : ('a, 'e) result Lwt.t list -> ('a list, 'e list) result Lwt.t``: - the function ``all`` is a generalisation of ``both`` from tuples to - lists. - - Note that, as a generalisation of ``both``, in a call to the function - ``all``, all the promises in the provided list make progress towards - resolution concurrently and continue to evaluate until resolution - regardless of successes and failures. - -- ``join : (unit, 'e) result Lwt.t list -> (unit, 'e list) result Lwt.t``: - the function ``join`` is a specialisation of ``all`` for lists of - unit-type expressions (typically, for side-effects). - -The following functions do not provide new functionalities but they are -useful for small performance gains or for shorter syntax. - -- ``return_unit`` is equivalent to ``return ()`` but it avoids one - allocation. This is important in parts of the code that are - performance critical, and it is a good habit to take otherwise. - - | ``return_nil`` is equivalent to ``return []`` but it avoids one - allocation. - | ``return_true`` is equivalent to ``return true`` but it avoids one - allocation. - | ``return_false`` is equivalent to ``return false`` but it avoids - one allocation. - - | ``return_none`` is equivalent to ``return None`` but it avoids one - allocation. - | ``return_some x`` is equivalent to ``return (Some x)`` and it is - provided for completeness. - - Note that, like with ``Result_syntax``, this syntax module does not - provide ``return_ok`` and ``return_error``. This is to avoid nested - ``result`` types. If you need to nest ``result``\ s you can do so by - hand. - -- ``let+`` is a binding operator similar to ``let*`` but when the - expression which follows the ``in`` returns a non-promise value. In - other words, ``let+ x = e in e'`` is equivalent to - ``let* x = e in return (e')``. - - The ``let+`` is purely for syntactic conciseness (compared to the ``*`` - variant), use it if it makes your code more readable. - -.. _exercises-3: - -Exercises -^^^^^^^^^ - -- Write the implementation for - - :: - - (** [map f [x1; x2; ..]] is a promise for a list [[y1; y2; .. ]] where [y1] - is the value that [f x1] successfully resolves to, etc. except if [f] - resolves unsuccessfully on one of the input in which case it also - resolves unsuccessfully with the same error as [f]. *) - map : ('a -> ('b, 'e) result Lwt.t) -> 'a list -> ('b list, 'e) result Lwt.t - - How does your code compare to the one in the ``result``-only variant - of this exercise? - - Note that this exercise is for learning only. You won’t need to write - this function in Octez. Indeed, a helper function which does exactly - that is provided in the extended standard library of Octez. - -- Make your ``map`` function tail-recursive. - -- What type error is triggered by the following code? - - :: - - open Lwt_result_syntax ;; - let ( and* ) = both ;; - let _ = - let* x = return 0 and* y = return 1 in - let* z = return 2 in - return (x + y + z) ;; - -- Rewrite the following function without ``match``-``with`` - - :: - - let compose3 f g h x = - let open Lwt_syntax in - let* y_result = f x in - match y_result with - | Error e -> return (Error e) - | Ok y -> - let* z_result = g y in - match z_result with - | Error e -> return (Error e) - | Ok z -> - h z - -Converting errors of promises -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Remember that, with ``Result_syntax``, you cannot mix different types of -errors in a single sequence of ``let*``. This also applies to -``Lwt_result_syntax``. Indeed, the type checker will prevent you from -doing so. - -You can use the same ``Result.map_error`` function as for plain -``result``\ s. But when you are working with promises of ``result``, the -syntactic cost of doing so is high: - -:: - - let open Lwt_result_syntax in - let* config = - let open Lwt_syntax in - let* config_result = read_configuration () in - Lwt.return (Result.map_error (fun () -> ..) config_result) - in - .. - -To avoid this syntactic weight, the ``Lwt_result_module`` provides a -dedicated function: - -:: - - lwt_map_error : ('e -> 'f) -> ('a, 'e) result Lwt.t -> ('a, 'f) result Lwt.t - -Lifting -~~~~~~~ - -Occasionally, whilst you are working with promises of ``result`` (i.e., -working with values of the type ``(_, _) result Lwt.t``), you will need -to call a function that returns a simple promise (a promise that cannot -fail, a promise of a value that’s not a ``result``, i.e., a value of -type ``_ Lwt.t``) or a simple result (an immediate value of a -``result``, i.e., a value of type ``(_, _) result``). This is common -enough that the module ``Lwt_result_syntax`` provides helpers dedicated -to this. - -From ``result``-only into Lwt-``result`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The module ``Lwt_result_syntax`` includes the binding operator ``let*?``. It is -dedicated to binding Result-only expressions. - -:: - - let*? x = check foo bar in (* Result-only: checking doesn't yield *) - .. - - -.. sidebar:: Mnemonic - - The ``let*?`` binding operator uses the question mark (``?``) to represent - the uncertainty of the ``result``. Is it a success? Is it a failure? - - -From Lwt-only into Lwt-``result`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The module ``Lwt_result_syntax`` includes the binding operator ``let*!``. It is -dedicated to binding Lwt-only expressions. - -:: - - let*! x = Events.emit foo bar in (* Lwt-only: logs can't fail *) - .. - - -.. sidebar:: Mnemonic - - The ``let*!`` binding operator uses the exclamation mark (``!``) to represent - the impossibility of errors: Thou shall not fail! - - -Wait! There is too much! What module am I supposed to open locally and what operators should I use? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -If you are feeling overwhelmed by the different syntax modules, here are -some simple guidelines. - -- If your function returns ``(_, _) result Lwt.t`` values, then you - start the function with ``let open Lwt_result_syntax in``. Within the - function you use - - - ``let`` for vanilla expressions, - - ``let*`` for Lwt-``result`` expressions, - - ``let*!`` for Lwt-only expressions, - - ``let*?`` for ``result``-only expressions. - - And you end your function with a call to ``return``. - -- If your function returns ``(_, _) result`` values, then you start the - function with ``let open Result_syntax in``. Within the function you - use - - - ``let`` for vanilla expressions, - - ``let*`` for ``result`` expressions, - - And you end your function with a call to ``return``. - -- If your function returns ``_ Lwt.t`` values, then you start the - function with ``let open Lwt_syntax in``. - - - ``let`` for vanilla expressions, - - ``let*`` for Lwt expressions, - - And you end your function with a call to ``return``. - -These are rules of thumb and there are exceptions to them. Still, they -should cover most of your uses and, as such, they are a good starting -point. - -What’s an error? -~~~~~~~~~~~~~~~~ - -So far, this tutorial has considered errors in an abstract way. Most of -the types carried by the ``Error`` constructors have been parameters -(``'e``). This is a common pattern for higher-order functions that -compose multiple ``result`` and Lwt-``result`` functions together. But, -in practice, not every function is a higher-order abstract combinator -and you sometimes need to choose a concrete error. This section explores -common choices. - -**A dedicated algebraic data type** - -Often, a dedicated algebraic data type is appropriate. A sum type -represents the different kinds of failures that might occur. E.g., -``type hashing_error = Not_enough_data | Invalid_escape_sequence``. A -product type (typically a record) carries multiple bits of information -about a failure. E.g., -``type parsing_error = { source: string; location: int; token: token; }`` - -This approach works best when a set of functions (say, all the functions -of a module) have similar ways to fail. Indeed, when that is the case, -you can simply define the error type once and all calls to these -functions can match on that error type if need be. - -E.g., `binary encoding and decoding errors in -data-encoding `__. - -**Polymorphic variants** - -In some cases, the different functions of a module may each fail with -different subsets of a common set of errors. In such a case, you can use -`polymorphic variants `__ to -represent errors. E.g., - -:: - - val connect_to_peer: - address -> (connection, [ `timeout | `connection_refused ]) result Lwt.t - val send_message: - connection -> signing_key -> string -> - (unit, [ `timeout | `connection_closed ]) result Lwt.t - val read_message: - connection -> - (string, [ `timeout | `unknown_signing_key | `invalid_signature | `connection_closed ]) result Lwt.t - val close_connection: connection -> (unit, [ `unread_messages of string list ]) result - -The benefit of this approach is that the caller can compose the -different functions together easily and match only on the union of -errors that may actually happen. The type checker keeps track of the -variants that can reach any program point. - -:: - - let handshake conn = - let open Lwt_result_syntax in - let* () = send_message conn "ping" in - let* m = read_message conn in - if m = "pong" then - return () - else - `unrecognised_message m - - let handshake conn = - let open Lwt_syntax in - let* r = handshake conn in - match r with - | Ok () -> return_unit - | Error (`unknown_signing_key | `invalid_signature) -> - (* we ignore unread messages if the peer had signature issues *) - let _ = close_connection conn in - return_unit - | Error (`timeout | `connection_closed) -> - match close_connection with - | Ok () -> return_unit - | Error (`unread_messages msgs) -> - let* () = log_unread_messages msgs in - return_unit - -**A human-readable string** - -In some cases, there is nothing to be done about an error but to inform -the user. In this case, the error may just as well be the message. - -It is important to note that these messages are not generally meant to -be matched against. Indeed, such messages may not be stable and even if -they are, they probably don’t carry precise enough information to be -acted upon. - -You should only use ``string`` as an error type when the error is not -recoverable and you should not try to recover from ``string`` errors (or -more precisely, your recovery should not depend on the content of the -string). - -**An abstract type** - -If the error is not meant to be recovered from, it is sometimes ok to use an -abstract type. This is generally useful at the interface of a module, -specifically when the functions within the module are meant to inspect -the errors and possibly attempt recovery, but the callers outside of the -modules are not. - -If you do use an abstract type for errors, you should also provide a -pretty-printing function. - -**A wrapper around one of the above** - -Sometimes you want to add context or information to an error. E.g., - -:: - - type 'a with_debug_info = { - payload: 'a; - timestamp: Time.System.t; - position: string * int * int * int; - } - - let with_debug_info ~position f = - match f () with - | Ok _ as ok -> ok - | Error e -> Error { payload = e; timestamp = Time.System.now (); position } - -This specific example can be useful for debugging, but other wrappers -can be useful in other contexts. - -**Mixing error types** - -It is difficult to work with different types of errors within the same -function. This most commonly happens if you are calling functions from -different libraries, which use different types of errors. - -This is difficult because the errors on both sides of the binding -operator are the same. - -:: - - val ( let* ) : ('a, 'e) result -> ('a -> ('b, 'e) result) -> ('b, 'e) result - -The error monad provides some support to deal with multiple types of -errors at once. But this support is limited. It is not generally an -issue because error-mixing is somewhat rare: it tends to happen at the -boundary between different levels of abstractions. - -If you encounter one of these situations, you will need to convert all -the errors to a common type. - -:: - - type error = Configuration_error | Command_line_error - - let* config = - match Config.parse_file config_file with - | Ok _ as ok -> ok - | Error Config.File_not_found -> Ok Config.default - | Error Config.Invalid_file -> Error Configuration_error - in - let* cli_parameters = - match Cli.parse_parameters () with - | Ok _ as ok -> ok - | Error Cli.Invalid_parameter -> Error Command_line_error - in - .. - -You can also use the ``Result.map_error`` and ``lwt_map_error`` -functions introduced in previous sections. - -Wait! It was supposed to be “one single uniform way of dealing with errors”! What is this? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The error management in Octez is a unified way (syntax modules -with regular, predictable interfaces) of handling different types of -errors. - -The variety of errors is a boon in that it lets you use whatever is the -most appropriate for the part of the code that you are working on. -However, the variety of errors is also a curse in that stitching -together functions which return different errors requires boilerplate -conversion functions. - -That’s where the global ``error`` type comes in: a unified type for -errors. And that’s for the next section to introduce. - -META COMMENTARY -~~~~~~~~~~~~~~~ - -The previous sections are not Octez-specific. True, the syntax modules -are defined within the Octez source tree, but they could be released -separately (and they will be) or they could easily be replicated in a -separate project. - -The next sections are Octez-specific. They introduce types and values -that are used within the whole of Octez. - -| You should take this opportunity to take a break. -| Come back in a few minutes. - -Part 2: ``tzresult`` and Lwt-``tzresult`` ------------------------------------------ - -``error``, ``trace``, and ``tzresult`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The ``error`` type is an `extensible variant -type `__ defined in -the ``Error_monad`` module. - -Each part of the Octez source code can extend it to include some errors -relevant to that part. E.g., the p2p layer adds -``type error += Connection_refused`` whilst the store layer adds -``type error += Snapshot_file_not_found of string``. More information on -errors is presented later. - -The ``'error trace`` type is a data structure dedicated to holding -``error``\ s. It is exported by the ``Error_monad`` module. It is only -ever instantiated as ``error trace``. It can accumulate multiple errors, -which helps present information about the context in which an error -occurs. More information on traces is presented later. - -The ``'a tzresult`` type is an alias for ``('a, error trace) result``. -It is used in Octez to represent the possibility of failure in a generic -way. Using ``tzresult`` is a trade-off. You should only use it in -situations where the pros outweigh the cons. - -Pros: - -- A generic error that is the same everywhere means that the - binding operator ``let*`` can be used everywhere without having to - convert errors to a common type. -- Traces allow you to easily add - context to an existing error (see how later). - -Cons: - -- A generic wrapper around generic errors that cannot be - meaningfully matched against (although the pattern exists in legacy - code). -- Type information about errors is coarse-grained to the point of - being meaningless (e.g., there is no exhaustiveness check when - matching). -- Registration is syntactically heavy and requires care (see - below). - -In general, the type ``tzresult`` is mostly useful at a high-enough -level of abstraction and in the outermost interface of a module or even -package (i.e., when exposing errors to callers that do not have access -to internal implementation details). - -Generic failing -~~~~~~~~~~~~~~~ - -The easiest way to return a ``tzresult`` is via functions provided by -the ``Error_monad``. These functions are located at the top-level of the -module, as such they are available, unqualified, everywhere in the code. -They do not even require the syntax modules to be open. - -- ``error_with`` is for formatting a string and wrapping it inside an - ``error`` inside a ``trace`` inside an ``Error``. E.g., - - :: - - let retry original_limit (f : unit -> unit tzresult) = - let rec retry limit f - if limit < 0 then - error_with "retried %d times" original_limit - else - match f () with - | Error _ -> retry (limit - 1) f - | Ok () -> Ok () - in - retry original_limit f - - You can use all the formatting percent-escapes from the `Format - module `__. However, you should - generally keep the message on a single line so that it can be printed - nicely in logs. - - Formally, ``error_with`` has type - ``('a, Format.formatter, unit, 'b tzresult) format4 -> 'a``. This is - somewhat inscrutable. Suffice to say: it is used with a format string - and returns an ``Error``. - -- ``error_with_exn : exn -> 'a tzresult`` is for wrapping an exception - inside an ``error`` inside a ``trace`` inside an ``Error``. - - :: - - let media_type_kind s = - match s with - | "json" | "bson" -> Ok `Json - | "octet-stream" -> Ok `Binary - | _ -> error_with_exn Not_found - -- ``failwith`` is for formatting a string and wrapping it inside an - ``error`` inside a ``trace`` inside an ``Error`` inside a promise. - E.g., - - :: - - failwith "Cannot read file %s (ot %s)" file_name (Unix.error_message error) - - ``failwith`` is similar to ``error_with`` but for the combined - Lwt-``tzresult`` monad. Again the type - (``('a, Format.formatter, unit, 'b tzresult Lwt.t) format4 -> 'a``) - is inscrutable, but again usage is as simple as a formatting. - -- ``fail_with_exn`` is for wrapping an exception inside an ``error`` - inside a ``trace`` inside an ``Error`` inside a promise. E.g., - - :: - - fail_with_exn Not_found - - ``fail_with_exn`` is similar to ``error_with_exn`` but for the - combined Lwt-``tzresult`` monad. - -These functions are useful as a way to fail with generic errors that -carry a simple payload. The next section is about using custom errors -with more content. - -.. _exercises-5: - -Exercises -^^^^^^^^^ - -- Write a function ``tzresult_of_option : 'a option -> 'a tzresult`` - which replaces ``None`` with a generic failure of your choosing. - -- Write a function ``catch : (unit -> 'a) -> 'a tzresult`` which wraps - any exception raised during the evaluation of the function call. - -Declaring and registering ``error``\ s -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -On many occasions, ``error_with`` and friends (see above) are not -sufficient: you may want your error to carry more information than can -be conveyed in a simple string or a simple exception. When you do, you -need a custom error. You must first *declare* and then *register* an -``error``. - -To declare a new error you simply extend the ``error`` type. Remember -that the ``error`` type is defined and exported to the rest of the code -by the ``Error_monad`` module. You extend it with the ``+=`` syntax: - -:: - - type error += - Invalid_configuration of { expected: string; got: string; line: int } - -The registration function ``register_error_kind`` is also part of the -``Error_monad`` module. You *register* a new error by calling this -function. - -:: - - let () = - register_error_kind - `Temporary - ~id:"invalid_configuration" - ~title:"Invalid configuration" - ~description:"The configuration is invalid." - ~pp:(fun f (expected, got, line) -> - Format.fprintf f - "When parsing configuration expected %s but got %s (at line %d)" - expected got line - ) - Data_encoding.( - obj3 - (req "expected" string) - (req "got" string) - (req "line" int31)) - (function - | Invalid_configuration {expected; got; line} -> - Some (expected, got, line) - | _ -> None) - (fun (expected, got, line) -> Invalid_configuration {expected; got; line}) - -Note that you **MUST** register the errors you declare. Failure to do so -can lead to serious issues. - -The arguments for the ``register_error_kind`` function are as follows: - -category (:literal:`\`Temporary`): the category argument is meaningless -in the shell, just use :literal:`\`Temporary`. - -- ``id``: a short string containing only characters that do not need escaping - (``[a-zA-Z0-9._-]``), must be unique across the whole program. -- ``title``: a short human readable string. -- ``description``: a longer human readable string. -- ``pp``: a pretty-printing function carrying enough information for a full - error message for the user. Note that the function does not receive the error, - instead it receives the *projected payload of the error* (here a 3-tuple - ``(expected, got, line)``. -- encoding: an encoding for the projected payload of the error. -- projection: a partial function that matches the specific error - (out of all of them) and return its projected payload. This function always - has the form - ``function | -> Some | _ -> None``. -- injection: a function that takes the projected payload and constructs - the error out of it. - -For errors that do not carry information (e.g., -``type error += Size_limit_exceeded``), the projected payload of the -error is unit. - -It is customary to either register the error immediately after the error -is declared or to register multiple errors immediately after declaring -them all. In some cases, the registration happens in a separate module. -Either way, registration of declared error is compulsory. - -.. _exercises-6: - -Exercises -^^^^^^^^^ - -- Register the following error - - :: - - (** [Size_limit_exceeded {limit; current_size; attempted_insertion}] is used - when an insertion into the global table of known blocks would cause the - size of the table to exceed the limit. The field [limit] holds the - maximum allowed size, the field [current_size] holds the current size of - the table and [attempted_insertion] holds the size of the element that - was passed to the insertion function. *) - type error += Size_limit_exceeded { - limit: int; - current_size: int; - attempted_insertion: int - } - -The ``Tzresult_syntax`` module -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Remember that ``'a tzresult`` is a special case of ``('a, 'e) result``. -Specifically, a special case where ``'e`` is ``error trace``. -Consequently, you can handle ``tzresult`` values using the -``Result_syntax`` module. However, a more specialised module -``Tzresult_syntax`` is available. - -The ``Tzresult_syntax`` module is identical to the ``Result_syntax`` -module but for the following differences. - -- ``fail: 'e -> ('a, 'e trace) result``: the expression ``fail e`` - wraps ``e`` in a ``trace`` inside an ``Error``. When ``e`` is of type - ``error`` as is the case throughout Octez, ``fail e`` is of type - ``'a tzresult``. - -- ``and*``: a binding operator alias for ``both`` (see below). You can - use it with ``let*`` the same way you use ``and`` with ``let``. - - :: - - let apply_triple f (x, y, z) = - let open Tzresult_syntax in - let* u = f x - and* v = f y - and* w = f z - in - return (u, v, w) - - When you use ``and*``, the bound results (``f x``, ``f y``, and - ``f z``) are all evaluated fully, regardless of the success/failure - of the others. The expression which follows the ``in`` - (``return ..``) is evaluated if all the bound results are successful. - -- ``both : ('a, 'e trace) result -> ('b, 'e trace) result -> ('a * 'b, 'e trace) result``: - the expression ``both a b`` is ``Ok`` if both ``a`` and ``b`` are - ``Ok`` and ``Error`` otherwise`. - - Note that unlike ``Result_syntax.both``, the type of errors - (``error trace``) is the same on both the argument and return side of - this function: the traces are combined automatically. This remark - applies to the ``all`` and ``join`` (see below) as well. - - The stability of the return type is what allows this syntax module to - include an ``and*`` binding operator. - -- ``all : ('a, 'e trace) result list -> ('a list, 'e trace) result``: - the function ``all`` is a generalisation of ``both`` from tuples to - lists. - -- ``join : (unit, 'e trace) result list -> (unit, 'e trace) result``: - the function ``join`` is a specialisation of ``all`` for list of - unit-typed expressions (typically, for side-effects). - -- ``and+`` is a binding operator similar to ``and*`` but for use with - ``let+`` rather than ``let*``. - -.. _exercises-7: - -Exercises -^^^^^^^^^ - -- What is the difference between the two following functions? - - :: - - let twice f = - let open Tzresult_syntax in - let* () = f () in - let* () = f () in - return_unit - - :: - - let twice f = - let open Tzresult_syntax in - let* () = f () - and* () = f () - in - return_unit - -The ``Lwt_tzresult_syntax`` module -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -In the same way ``result`` can be combined with Lwt, ``tzresult`` can -also be combined with Lwt. And in the same way that ``Tzresult_syntax`` -is a small variation of ``Result_syntax``, ``Lwt_tzresult_syntax`` is a -small variation of ``Lwt_result_syntax``. - -There are possibly too many parallels to keep track of, so the diagram -below might help. - -:: - - 'a -----------> ('a, 'e) result ------------> 'a tzresult - | | | - | | | - V V V - 'a Lwt.t ------> ('a, 'e) result Lwt.t ------> 'a tzresult Lwt.t - -Anyway, the ``Lwt_tzresult_syntax`` module is identical to the -``Lwt_result_syntax`` module but for the following differences. - -- ``fail: 'e -> ('a, 'e trace) result Lwt.t``: the expression - ``fail e`` wraps ``e`` in a ``trace`` inside an ``Error`` inside a - promise. When ``e`` is of type ``error`` as is the case throughout - Octez, ``fail e`` is of type ``'a tzresult Lwt.t``. - -- ``and*``: a binding operator alias for ``both``. You can use it with - ``let*`` the same way you use ``and`` with ``let``. - - :: - - let apply_triple f (x, y, z) = - let open Lwt_tzresult_syntax in - let* u = f x - and* v = f y - and* w = f z - in - return (u, v, w) - - When you use ``and*``, the bound promises (``f x``, ``f y``, and - ``f z``) are evaluated concurrently, and the expression which follows - the ``in`` (``return ..``) is evaluated once all the bound promises - have all resolved but only if all of them resolve successfully. - - Note how this ``and*`` binding operator inherits the properties of - both ``Lwt_syntax.( and* )`` and ``Tzresult_syntax.( and* )``. - Specifically, the promises are evaluated concurrently and the - expression which follows the ``in`` is evaluated only if all the - bound promises have successfully resolved. These two orthogonal - properties are combined. This remark also applies to ``both``, - ``all``, ``join`` and ``and+`` below. - -- ``both : ('a, 'e trace) result Lwt.t -> ('b, 'e trace) result Lwt.t -> ('a * 'b, 'e trace) result Lwt.t``: - the expression ``both p q`` is a promise that resolves once both - ``p`` and ``q`` have resolved. It resolves to ``Ok`` if both ``p`` - and ``q`` do, and to ``Error`` otherwise`. - - Note that unlike ``Lwt_result_syntax.both``, the type of errors - (``error trace``) is the same on both the argument and return side of - this function: the trace are combined automatically. This remark - applies to the ``all`` and ``join`` (see below) as well. - - The stability of the return type is what allows this syntax module to - include an ``and*`` binding operator. - -- ``all : ('a, 'e trace) result Lwt.t list -> ('a list, 'e trace) result Lwt.t``: - the function ``all`` is a generalisation of ``both`` from tuples to - lists. - -- ``join : (unit, 'e trace) result Lwt.t list -> (unit, 'e trace) result Lwt.t``: - the function ``join`` is a specialisation of ``all`` for lists of - unit-typed expressions (typically, for side-effects). - -- ``and+`` is a binding operator similar to ``and*`` but for use with - ``let+`` rather than ``let*``. - -.. _exercises-8: - -Exercises -^^^^^^^^^ - -- Rewrite this function to use the ``Lwt_tzresult_syntax`` module and - no other syntax module. - - :: - - let apply_tuple (f, g) (x, y) = - let open Lwt_syntax in - let* u = f x - and* v = g y - in - let r = Tzresult_syntax.both u v in - return r - -- Write the implementation for - - :: - - (** [map f [x1; x2; ..]] is [[y1; y2; ..]] where [y1] is the successful - result of [f x1], [y2] is the successful result of [f x2], etc. If [f] - fails on any of the inputs, returns an `Error` instead. Either way, all - the calls to [f] on all the inputs are evaluated concurrently and all - the calls to [f] have resolved before the whole promise resolves. *) - val map : ('a -> 'b tzresult Lwt.t) -> 'a list -> 'b list tzresult - -.. _lifting-1: - -Lifting -~~~~~~~ - -When you are working with promises of ``tzresult`` (i.e., within -Lwt-``tzresult``), you may occasionally need to call functions that -return a simple promise (i.e., within Lwt-only) or a simple ``tzresult`` -(i.e., within ``tzresult``-only). - -This situation is similar to that of ``Lwt_result_syntax`` and the -solutions are the same. Specifically, the additional binding operators provided -by ``Lwt_result_syntax`` are also available in ``Lwt_tzresult_syntax``. - -:: - - let*! x = plain_lwt_function foo bar in - let*? x = plain_result_function foo bar in - .. - - -Are you kidding me?! there is even more! what module am I supposed to open locally and what operators should I use? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You can also use simple guidelines to use these syntax modules -effectively. - -- If your function returns ``_ tzresult Lwt.t`` values, then you start - the function with ``let open Lwt_tzresult_syntax in``. Within the - function you use - - - ``let`` for vanilla expressions, - - ``let*`` for Lwt-``tzresult`` expressions, - - ``let*!`` for Lwt-only expressions, - - ``let*?`` for ``tzresult``-only expressions. - - And you end your function with a call to ``return``. - -- If your function returns ``_ tzresult`` values, then you start the - function with ``let open Tzresult_syntax in``. Within the function - you use - - - ``let`` for vanilla expressions, - - ``let*`` for ``tzresult`` expressions, - - And you end your function with a call to ``return``. - -The rest of the guidelines (for ``(_, _) result Lwt.t``, -``(_, _) result``, and ``_ Lwt.t``) remain valid. - -Tracing -~~~~~~~ - -Remember that a trace is a data structure specifically designed for -errors. - -Traces have two roles: - -- As a programmer you benefit from the traces' ability to combine - automatically. Indeed, this feature of traces makes the ``and*`` binding - operators possible which can simplify some tasks such as concurrent - evaluation of multiple ``tzresult`` promises. - -- For the user, traces combine multiple errors, allowing for high-level - errors (e.g., ``Cannot_bootstrap_node``) to be paired with low-level - errors (e.g., ``Unix_error EADDRINUSE``). When used correctly, this - can help create more informative error messages which, in turn, can - help debugging. - -Tracing primitives are declared in the ``Error_monad`` module. As such, -they are available almost everywhere in the code. They should be used -whenever an error passes from one component (say the p2p layer, or the -storage layer) into another (say the shell). - -- ``record_trace err r`` leaves ``r`` untouched if it evaluates to - ``Ok``. Otherwise, it adds the error ``err`` to the trace carried in - ``Error``. - - :: - - let check_hashes head block operation = - let open Tzresult_syntax in - let* () = - record_trace (Invalid_hash { kind: "head"; hash: head}) @@ - check_hash chain - in - let* () = - record_trace (Invalid_hash { kind: "block"; hash: block}) @@ - check_hash block - in - let* () = - record_trace (Invalid_hash { kind: "operation"; hash: operation}) @@ - check_hash operation - in - return_unit - - In this example a failure from any of the calls to ``check_hash`` - will be given context that helps with understanding the source of the - error. - -- ``record_trace_eval`` is a lazy version of ``record_trace`` in that - the error added to the trace is only evaluated if needed. More - formally ``record_trace_eval make_err r`` leaves ``r`` untouched if - it evaluates to ``Ok``. Otherwise it calls ``make_err`` and adds the - returned error onto the trace. - - You should use the strict ``record_trace`` version when the error you - are adding to the trace is an immediate value (e.g., ``Overflow``) or - a constructor with immediate values (e.g., ``Invalid_file name``). - You should use the lazy ``record_trace_eval`` version when the error - you are adding to the trace requires computation to generate (e.g., - if it requires formatting or querying). - -- ``trace`` is the Lwt-aware variant of ``record_trace``. More - formally, ``trace err p`` leaves ``p`` untouched if it resolves - successfully, otherwise it adds the error ``err`` to the trace - carried by the unsuccessful resolve. - - :: - - let get_data_and_gossip_it () = - let open Lwt_tzresult_syntax in - let* data = - trace Cannot_get_random_data_from_storage @@ - Storage.get_random_data () - in - let* number_of_peers = - trace Cannot_gossip_data @@ - P2p.gossip data - in - return (data, number_of_peers) - - In this example, low-level storage errors are given more context by - the ``Cannot_get_random_data_from_storage`` error. Similarly, - low-level p2p errors are given more context by the - ``Cannot_gossip_data`` error. This is important because both the - storage and the p2p layer may suffer from similar system issues (such - as file-descriptor exhaustion). - -- ``trace_eval`` is the lazy version of ``trace``, or, equivalently, - the Lwt-aware version of ``record_trace_eval``. - - You should use the strict ``trace`` version when the error you are - adding is immediate or a constructor with immediate values. You - should use the lazy ``trace_eval`` version when the error you are - adding requires computation to generate. - -Do not hesitate to use the tracing primitives. Too much context is -better than too little context. Think of ``trace`` (and variants) as a -way to document Octez. Specifically, as making the error messages of -Octez more informative. - -.. _meta-commentary-1: - -META COMMENTARY -~~~~~~~~~~~~~~~ - -The previous sections had a practical focus: how to handle errors? how -to mix different syntaxes? how?! By contrast, the following sections are -in-depth discussions of advanced or tangential topics which you should -feel free to skim or even to skip. - -| You should take this opportunity to take a break. -| Come back in a few minutes. - - -Part 3: Advanced topics ------------------------ - -Working with standard data-structures: Lwtreslib -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Handling values within the Lwt, ``result``, and Lwt-``result`` monads is -so common in Octez that you also have access to an extension of the -Stdlib dedicated to these monads: the ``Lwtreslib`` library. - -The ``tezos-lwt-result-stdlib`` package exports an ``Lwtreslib`` module -which is made available, through ``tezos-error-monad`` and -``tezos-base``, to the whole of the codebase. Specifically, within the -codebase of Octez the following modules of OCaml’s ``Stdlib`` are -shadowed by Lwtreslib’s: - -- ``List``, -- ``Result``, -- ``Option``, -- ``Seq``, -- ``Map``, -- ``Set``, and -- ``Hashtbl``. - -In all those modules, the underlying data structures are compatible with -those of the ``Stdlib`` and thus with the rest of the OCaml ecosystem. -However, the primitives in these modules are extended to support Lwt, -``result`` and the combination of the two. Specifically, for each -function that traverses the data structure, the module also contains -variants that perform the same traversal within each of the monad. E.g., -for ``List.map`` - -:: - - (* vanilla map *) - val map : ('a -> 'b) -> 'a list -> 'b list - - (* [result]-aware map: stops at the first error *) - val map_e : ('a -> ('b, 'trace) result) -> 'a list -> ('b list, 'trace) result - - (* sequential Lwt map: treats each element after the previous one *) - val map_s : ('a -> 'b Lwt.t) -> 'a list -> 'b list Lwt.t - - (* sequential Lwt-[result] map: - - treats each element after the previous one - - stops at the first error *) - val map_es : - ('a -> ('b, 'trace) result Lwt.t) -> - 'a list -> - ('b list, 'trace) result Lwt.t - - (* concurrent Lwt map: treats all the elements concurrently *) - val map_p : ('a -> 'b Lwt.t) -> 'a list -> 'b list Lwt.t - - (* concurrent Lwt-[result] map: - - treats all the elements concurrently - - treats the whole list no matter the success/errors *) - val map_ep : - ('a -> ('b, 'trace) result Lwt.t) -> - 'a list -> - ('b list, 'trace list) result Lwt.t - -Check out `the online documentation of -Lwtreslib <../api/odoc/_html/tezos-lwt-result-stdlib/Tezos_lwt_result_stdlib/Lwtreslib/index.html>`__ -for a description of the semantic and naming convention. - -In addition to shadowing existing modules, ``Lwtreslib`` also exports -new modules: - -- ``Seq_e`` for ``result``-aware variant of ``Seq``, -- ``Seq_s`` for Lwt-aware variant of ``Seq``, -- ``Seq_es`` for Lwt-``result``-aware variant of ``Seq``, and -- ``WithExceptions`` for unsafe accesses such as ``Option.get``. - -Whenever you need to traverse a standard data structure with some -``result`` or Lwt or Lwt-``result`` function, ``Lwtreslib`` should have -that function ready for you. **You should never fold over a data -structure with a promise or result accumulator.** E.g., you should -do - -:: - - List.rev_map_es fetch keys - -and you shouldn’t do - -:: - - let open Lwt_result_syntax in - List.fold_left - (fun resources key -> - let* resources = resources in - let* resource = fetch key in - return (resource :: resources)) - (return []) - keys - -If you do not find the traversal function you need, do not hesitate to -contribute to Lwtreslib. - -Working with traces and errors and such directly -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Occasionally, you may need more interaction with traces than the -primitives presented thus far. - -For error reporting or debugging purpose, you may need to show traces to -users. You can do so with the following values. - -- ``pp_print_trace``: a ``%a``-`compatible - formatter `__. Note that the trace - formatting is unspecified and subject to change. Also be aware that - it generally prints the trace over multiple lines. -- ``pp_print_top_error_of_trace``: a ``%a``-`compatible - formatter `__ that only shows the - most recent error in the trace (or one of the most recent errors if - there are several). This is useful to get shorter error messages. - Most often used for the declaration of logging events in - ``Internal_event.Simple``. -- ``trace_encoding``: an encoding for traces. Useful to combine into - encoding of data structures that contain traces. Most often used for - the declaration of logging events in ``Internal_event.Simple``. - -If you are working with non-standard data structures and if you need to -define monad-aware traversors for these data structures, you may need to -build some traces by hand. You can do so with the following values. - -- ``TzTrace.make : 'e -> 'e trace`` useful to convert an ``error`` into - an ``error trace``. By extension, this is useful to convert an - ``('a, error) result`` into an ``'a tzresult``. - -- ``TzTrace.cons : 'e -> 'e trace -> 'e trace`` is the low-level - combinators that builds-up traces. In most cases, you’ll want to use - ``trace`` or ``record_trace`` instead, but you might need it when you - are defining a low-level traversal function for some data structure. - - :: - - let iter_with_bounded_errors bound f xs = - (* we rely on syntax for Lwt, we handle results by hand *) - let open Lwt_syntax in - let rec aux_all_ok = function - | [] -> return_ok () - | x :: xs -> - let* r = f x in - match r with - | Ok () -> aux_all_ok xs - | Error e -> aux_some_error 1 (TzTrace.make e) xs - and aux_some_error num_errors trace xs = - if num_errors > bound then - return_error (TzTrace.cons (Exceeded_error_limit bound) trace) - else - match xs with - | [] -> return_ok () - | x :: xs -> - let* r = f x in - match r with - | Ok () -> aux_some_error num_errors trace xs - | Error e -> aux_some_error (num_errors + 1) (TzTrace.cons e trace) xs - in - aux_all_ok xs - -- ``TzTrace.conp : 'e trace -> 'e trace -> 'e trace`` is the parallel - composition of two traces. Unlike ``cons``, the traces composed by - ``conp`` are not organised hierarchically. The errors are presented - as having happened side-by-side. - - Note that currently there is little difference between cons and conp - traces. But the difference will be more marked in the future. - - You should use ``conp`` (rather than ``cons``) when you are gathering - errors and traces from two or more concurrent processes. - -Working within the protocol -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -If you are working on the protocol, things are slightly different for -you. This is because the protocol has a restricted access to external -resources and libraries. You can find more details in :doc:`the dedicated -documentation `. -This section focuses on the error-monad within the protocol. - -The protocol environment libraries evolve at a slightly different pace -than the underlying library. You need to check the ``mli`` files within -``src/lib_protocol_environment/sigs/``. - -Note that unlike in the shell, the traces in the protocol are already -abstract. As a result there is no matching of traces (and thus errors) -within the protocol: you can match ``Ok`` and ``Error``, but not the -payload of the ``Error``. This part of the legacy code has already been -removed. - -The main difference between the protocol and the shell is that the -``category`` parameter of the ``register_error_kind`` function is -meaningful. You must pass a category which is appropriate for the error -you are registering: - -- ``Branch``: is for branch-specific failures, i.e., failures that - happen in the current branch (of the chain) but maybe wouldn’t happen in a - different branch. E.g., a reference to an unknown block is invalid, but it - might become valid once the head block has changed. This category is - then used by the shell to retry after the branch changes. - -- ``Temporary``: is for transient failures, i.e., failures that happen - but may not always happen. This category is used by the shell to - retry at some later time. - -- ``Permanent``: is for irremediable failures, i.e., failures that - happen and will always happen whatever the context. E.g., - `originating a - contract `__ - that does not type-check is a permanent error. This is used by the - shell to mark the data as invalid. - -- ``Outdated``: is for failures that happen when some data is too old. - -Another thing to consider is that errors from the protocol can reach the -shell. However, because the ``error`` type of the protocol is distinct -from that of the shell, the protocol errors are wrapped inside a shell -error constructor. - -This has no impact within the protocol (where shell errors don’t exist) -nor within the shell (where protocol errors are automatically wrapped -inside a shell error). However, it can have an impact in the spaces in -between. Most typically, this matters in the unit-tests of the protocol -(``src/proto_alpha/lib_protocol/test/unit/``) where you call some -protocol functions directly. In this case, you need to wrap the errors -yourself, using the wrapping functions provided by the environment: -``Environment.wrap_tzresult``, ``Environment.wrap_tztrace``, and -``Environment.wrap_tzerror``. - -Working below the error-monad -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -If you are working on some low-level libraries (e.g., -``src/lib_stdlib``) or the external dependencies (e.g., -``data-encoding``) you don’t have access to the error monad at all. - -In this case, you can still use the ``result`` type but you need to -define your own ``let*`` binding operator: -``let ( let* ) = Result.bind``. - -You can also use Lwt which provides its own `Lwt.Syntax -module `__. - -Finally, the `Lwt_result -module `__ -(provided as part of Lwt) can help you deal with result-Lwt -combinations, including via its `Lwt_result.Syntax -module `__. - -Working with external libraries -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This tutorial covers error-management techniques in Octez. However, from -within Octez, you may need to call external libraries for cryptography -or RPCs or data-encoding or what have you. - -The first thing you do is to carefully read the documentation of the -external library you are using. You should check the overview -documentation with a look out for comments on error management. - -Then, you also need to read the documentation of each function that you -are calling. This documentation may explain how errors are handled: does -the function return a ``result``? does it raise and exception? is it -unspecified? - -If the function you are calling may raise exceptions, you should catch -these exceptions. You can either do so at the level of the call itself -or, if you are calling multiple functions that can all raise similar -exceptions, around a whole block of calls. - -When you catch an exception, the most common thing to do is to translate -it or wrap it into a ``result`` or a ``tzresult``. - -:: - - try - let v1 = Data_encoding.Json.destruct e1 j1 in - let v2 = Data_encoding.Json.destruct e2 j2 in - Ok (v1, v2) - with - | exc -> Error (Cannot_destruct_json_value exc) - -Note that if you are calling an Lwt function, you have to use ``Lwt.catch`` or -``Lwt.try_bind`` rather than ``try``-``with``. - -:: - - Lwt.catch - (fun () -> - let open Lwt_syntax in - let* () = Lwt_unix.mkdir d1 perm in - let* () = Lwt_unix.mkdir d2 perm in - Lwt_result_syntax.return_unit) - (function - | exc -> Lwt_result_syntax.fail (Cannot_destruct_json_value exc)) - -The error monad provides `several helpers functions for catching exceptions -`__. - -:: - - val catch : ?catch_only:(exn -> bool) -> (unit -> 'a) -> 'a tzresult - -If the function you are calling may raise exceptions only under -well-defined conditions on the parameters, then you can also check those -conditions yourself and ignore the exceptions. When doing so, please add -a comment to explain it. - -:: - - let get_or_defaults low_default high_default array offset = - if offset < 0 then - low_default - else if offset >= Array.length array then - high_default - else - (* This cannot raise because of checks on offset above *) - Array.get array offset - -If the function may fail with ``result``, you can map the error directly -or simply continue with it. If it may fail with ``option``, you can -translate ``None`` into an appropriate error. - -:: - - match find k kvs with - | None -> Error "cannot find key" - | Some v -> Ok v - -If the function’s documentation specifies some pre-conditions but -doesn’t explain what happens if those aren’t met, then you must check -those pre-conditions. - - -Appendices ----------- - -Legacy code -~~~~~~~~~~~ - -(This section will be removed once the whole code-base has been updated -to use the binding operators as recommended. In the meantime, you need -to learn some legacy constructs so you can read code that hasn’t been -upgraded yet. You should not use the operators introduced in this -section to write new code.) - -The legacy code is written with infix bindings instead of ``let``-style -binding operators. The binding ``>>?`` for ``result`` and ``tzresult``, -``>>=`` for Lwt, and ``>>=?`` for Lwt-``result`` and Lwt-``tzresult``. A -full equivalence table follows. - -+--------------------------------------+-------------------------------+ -| Modern | Legacy | -+--------------------------------------+-------------------------------+ -| :: | :: | -| | | -| let open Result_syntax in | e >>? fun x -> | -| let* x = e in | e' | -| e' | | -+--------------------------------------+-------------------------------+ -| :: | :: | -| | | -| let open Result_syntax in | e >|? fun x -> | -| let+ x = e in | e' | -| e' | | -+--------------------------------------+-------------------------------+ -| :: | :: | -| | | -| let open Lwt_syntax in | e >>= fun x -> | -| let* x = e in | e' | -| e' | | -+--------------------------------------+-------------------------------+ -| :: | :: | -| | | -| let open Lwt_syntax in | e >|= fun x -> | -| let+ x = e in | e' | -| e' | | -+--------------------------------------+-------------------------------+ -| :: | :: | -| | | -| let open Lwt_result_syntax in | e >>=? fun x -> | -| let* x = e in | e' | -| e' | | -+--------------------------------------+-------------------------------+ -| :: | :: | -| | | -| let open Lwt_result_syntax in | e >|=? fun x -> | -| let+ x = e in | e' | -| e' | | -+--------------------------------------+-------------------------------+ -| ``and*``, ``and+`` (any syntax | No equivalent, uses | -| module) | ``both_e``, ``both_p``, or | -| | ``both_ep`` | -+--------------------------------------+-------------------------------+ -| :: | :: | -| | | -| let open Lwt_result_syntax in | (e >>= ok) >>=? fun x -> | -| let*! x = e in | e' | -| e' | | -+--------------------------------------+-------------------------------+ -| :: | :: | -| | | -| let open Lwt_result_syntax in | e >>?= fun x -> | -| let*? x = e in | e' | -| e' | | -+--------------------------------------+-------------------------------+ - -In addition, instead of dedicated ``return`` and ``fail`` functions from -a given syntax module, the legacy code relied on global values. - -+--------------------------------------+-------------------------------+ -| Modern | Legacy | -+--------------------------------------+-------------------------------+ -| :: | :: | -| | | -| let open Result_syntax in | ok x | -| return x | | -+--------------------------------------+-------------------------------+ -| :: | No equivalent, uses | -| | ``Error e`` | -| let open Result_syntax in | | -| fail e | | -+--------------------------------------+-------------------------------+ -| :: | No equivalent, uses | -| | ``Lwt.return x`` | -| let open Lwt_syntax in | | -| return x | | -+--------------------------------------+-------------------------------+ -| :: | :: | -| | | -| let open Lwt_result_syntax in | return x | -| return x | | -+--------------------------------------+-------------------------------+ -| :: | No equivalent, uses | -| | ``Lwt.return_ok x`` | -| let open Lwt_result_syntax in | | -| fail e | | -+--------------------------------------+-------------------------------+ -| :: | :: | -| | | -| let open Tzresult_syntax in | ok x | -| return x | | -+--------------------------------------+-------------------------------+ -| :: | :: | -| | | -| let open Tzresult_syntax in | error e | -| fail e | | -+--------------------------------------+-------------------------------+ -| :: | :: | -| | | -| let open Lwt_tzresult_syntax in | return x | -| return x | | -+--------------------------------------+-------------------------------+ -| :: | :: | -| | | -| let open Lwt_tzresult_syntax in | fail e | -| fail e | | -+--------------------------------------+-------------------------------+ - -In addition to these syntactic differences, there are also usage -differences. You might encounter the following patterns which you should -not repeat: - -- Matching against a trace: - - :: - - match f () with - | Ok .. -> .. - | Error (Timeout :: _) -> .. - | Error trace -> .. - - This is discouraged because the compiler is unable to warn you if the - matching is affected by a change in the code. E.g., if you add - context to an error in one place in the code, you may change the - result of the matching somewhere else in the code. - - -In depth discussion: what even is a monad? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This tutorial has been pretty loose with the word monad. It has focused -on usage with very little explanations of fundamental concepts. It is -focused on the surface syntax instead of the underlying mathematical -model. This section goes into a bit more details about the general -principles of monads and such. It does not claim to even attempt to -give a complete description of monads, it simply gives more details than -the previous sections. - -For coding purposes, a monad is a parametric type equipped with a set of -specific operators. - -:: - - type 'a t - val bind : 'a t -> ('a -> 'b t) -> 'b t - val return : 'a -> 'a t - -The ``return`` operator injects a value into the monad and the ``bind`` -operator continues within the monad. - -The set of operators must also follow the monad laws. For example -``bind (return x) f`` must be equivalent to ``f x``. - -Monads are used as a generic way to encode different abstractions within -a programming language: I/O, errors, collections, etc. For example, the -``option`` monad is defined as - -:: - - module OptionMonad = struct - type 'a t = 'a option - let bind x f = match x with | None -> None | Some x -> f x - let return x = Some x - end - -And it is useful when dealing with queries that may have no answer. This -can be used as a lighter form of error management than the ``result`` -monad. - -Some programming languages also offer syntactic sugar for monads. This -is to avoid having to write ``bind`` within ``bind`` within ``bind``. -E.g., Haskell relies heavily on monads and has the dedicated -``do``-notation. In OCaml, you can use one of the following methods: - -- `binding operators `__ - (since OCaml 4.08.0) - - :: - - let add x y = - let ( let* ) = OptionMonad.bind in - let* x = int_of_string_opt x in - let* y = int_of_string_opt y in - Some (string_of_int (x + y)) - -- `infix - operators `__ - - :: - - let add x y = - let ( >>= ) = OptionMonad.bind in - int_of_string_opt x >>= fun x -> - int_of_string_opt y >>= fun y -> - Some (string_of_int (x + y)) - - Note that mixing multiple infix operators is not always easy because - of precedence and associativity. - -- partial application and infix ``@@`` - - :: - - let add x y = - OptionMonad.bind (int_of_string_opt x) @@ fun x -> - OptionMonad.bind (int_of_string_opt y) @@ fun y -> - Some (string_of_int (x + y)) - - This is useful for the occasional application: you do not need to - declare a dedicated operator nor open a dedicated syntax module. - -Monads can have additional operators beside the required core. E.g., you -can add ``OptionMonad.join : 'a option option -> 'a option``. - -In depth discussion: ``Error_monad``, ``src/lib_error_monad/``, ``Tezos_base__TzPervasives``, etc. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The different parts of the error monad (syntax modules, extended stdlib, -tracing primitives, etc.) are defined in separate files. Yet, they are -all available to you directly. This section explains where each part is -defined and how it reaches the scope of your code. - -**From your code, working back to the definitions.** - -In most of Octez, the ``Error_monad`` module is available. Specifically, it is -available in all the packages that depend on ``tezos-base``. This covers -everything except the protocols and a handful of low-level libraries. - -In those part of Octez, the build files include -``-open Tezos_base__TzPervasives``. - -The module ``Tezos_base__TzPervasives`` is defined by the compilation -unit ``src/lib_base/TzPervasives.ml``. - -This compilation unit gathers multiple low-level modules together. Of -interest to us is ``include Tezos_error_monad.Error_monad`` (left -untouched in the ``mli``) and ``include Tezos_error_monad.TzLwtreslib`` -(not present in the ``mli``, used to shadow the Stdlib modules ``List``, -``Option``, ``Result``, etc.). - -The ``Error_monad`` module exports: - -- the ``error`` type along with the ``register_error_kind`` function, -- the ``'a tzresult`` type, -- the ``TzTrace`` module, -- the ``Tzresult_syntax`` and ``Lwt_tzresult_syntax`` modules - (from a different, more generic name), -- and exports a few more functions. - -The rest of the ``tezos-error-monad`` package: - -- defines the ``'a trace`` type (in ``TzTrace.ml``), and -- instantiates ``TzLwtreslib`` by applying ``Lwtreslib``\ ’s ``Traced`` - functor to ``TzTrace``. - -The ``Lwtreslib`` module exports a ``Traced (T: TRACE)`` functor. This -functor takes a definition of traces and returns a group of modules -intended to shadow the Stdlib. - -**From the underlying definitions, working all the way up to your -code.** - -At the low-level is Lwtreslib. - -- ``src/lib_lwt_result_stdlib/bare/sigs``: defines interfaces for - basic, non-traced syntax modules and Stdlib-replacement modules. -- ``src/lib_lwt_result_stdlib/bare/structs``: defines implementations - basic, non-traced syntax modules and Stdlib-replacement modules. -- ``src/lib_lwt_result_stdlib/traced/sigs``: defines interfaces for - traced syntax modules and Stdlib-replacement modules. These - interfaces are built on top of the non-traced interfaces, mostly by - addition and occasionally by shadowing. -- ``src/lib_lwt_result_stdlib/traced/structs``: defines implementations - for traced syntax modules and Stdlib-replacement modules. These - implementations are built on top of the non-traced implementations, - mostly by addition and occasionally by shadowing. These are defined - as functors over some abstract tracing primitives. -- ``src/lib_lwt_result_stdlib/lwtreslib.mli``: puts together the traced - implementations into a single functor ``Traced`` that takes a trace - definition and returns fully instantiated modules to shadow the - Stdlib. - -Above Lwtreslib is the Error monad. - -- ``src/lib_error_monad/TzTrace.ml``: defines the ``'a trace`` type - along with the low-level trace-construction primitives. -- ``src/lib_error_monad/TzLwtreslib.ml``: instantiates - ``Lwtreslib.Traced`` with ``TzTrace``. -- ``src/lib_error_monad/monad_extension_maker.ml``: provides a functor - which, given a tracing module, provides some higher level functions - for tracing as well as a few other functions. -- ``src/lib_error_monad/core_maker.ml``: provides a functor which, - given a name, provides an ``error`` type, a ``register_error_kind`` - function, and a few other related functions. This is a functor so we - can instantiate it separately for the shell and for each of the - protocols. -- ``src/lib_error_monad/TzCore.ml``: instantiates the ``core_maker`` - functor for the shell. -- ``src/lib_error_monad/error_monad.ml``: puts together all of the - above into a single module. - -Above the Error monad is lib-base: - -- ``src/lib_base/TzPervasives.ml``: exports the ``Error_monad`` module, - includes the ``Error_monad`` module, exports each of the - ``TzLwtreslib`` module. - -In depth discussion: ``result`` as data and ``result`` as control-flow -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Note that ``result`` (and similarly, ``tzresult``) is a data type. -Specifically - -:: - - type ('a, 'b) result = - | Ok of 'a - | Error of 'b - -You can treat values of type ``result`` as data of that data-type. In -this case, you construct and match the values, you pass them around, -etc. - -Note however that, in Octez, we also use the ``result`` type as a -control-flow mechanism. Specifically, in conjunction with the ``let*`` -binding operator, the ``result`` type has a continue/abort meaning. - -Within your code, you can go from one use to the other. E.g., - -:: - - let xs = - List.rev_map - (fun x -> - (* [result] as control-flow *) - let open Result_syntax in - let* .. = .. in - let* .. = .. in - return ..) - ys - in - let successes xs = - (* [result] as data *) - List.length (List.rev_filter_ok xs) - in - .. - -Using ``result`` as sometimes data and sometimes control-flow is the -main reason to bend the guidelines about which syntax module to -open. E.g., if your function returns ``(_, _) result Lwt.t`` but the -``result`` is data returned by the function rather than control-flow -used within the function, then you should open ``Lwt_syntax`` (rather -then ``Lwt_result_syntax``). - -As a significant aside, note that in OCaml you can also use exceptions -for control-flow (with ``raise`` and ``try``-``with`` and -``match``-``with``-``exception``) and as data (the type ``exn`` is an -extensible variant data-type). - -:: - - (** [iter_no_raise f xs] applies [f] to all the elements of [xs]. If [f] raises - an exception, the iteration continues and [f] is still applies to other - elements. The function returns pairs of the exceptions raised by [f] along - the elements of [xs] that triggered these exceptions. *) - let iter_no_raise f xs = - List.fold_left - (fun excs x -> - match f x with - | exception exc -> exc :: excs - | () -> excs) - [] - xs - -You can find uses of exception as data within the error monad itself. -First, the generic failure functions (``error_with``, -``error_with_exn``, ``failwith``, and ``fail_with_exn``) are just -wrapper around an ``error`` which carries an exception (as data). - -Second, Lwtreslib provides helpers to catch exceptions. E.g., -``Result.catch : (unit -> 'a) -> ('a, exn) result`` calls a function and -wraps any raised exception inside an ``Error`` constructor. - -In depth discussion: pros and cons of ``result`` compared to other error management techniques -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -In Octez, we use ``result`` and the specialised ``tzresult``. For this -reason, this tutorial is focused on ``result``/``tzresult``. However, -there are other techniques for handling errors. This section compares -them briefly. - -In general you should use ``result`` and ``tzresult`` but in some -specific cases you can deviate from that. The comparisons below may help -you decide. - -**Exceptions** - -In exception-based error handling, you raise an exception (via -``raise``) when an error occurs and you catch it (via ``try``-``with``) -to recover. Exceptions are fast because the OCaml compiler and runtime -provide the necessary mechanisms directly. - -Whether a function can raise an exception or not cannot be determined by -its type. This means that it is easy to forget to recover from an -exception. An external library may change the set of exceptions that a -function raises and you need to update calls to this function, but the -type-checker cannot warn you about it. This places a heavy burden on the -developer who is responsible for checking the documentation of all the -functions they call. - -Exception-raising functions should be documented as such using the -``@raise`` documentation keyword. - -| Pros: performance is good, used widely in the larger ecosystem. -| Cons: you cannot rely on the type-checker to help you at all, you - depend on the quality of the documentation of your external and - internal dependencies. - -Note that within the protocol, you should not use exceptions at all. - -**tzresult** - -With ``tzresult``, errors are carried by the ``Error`` constructor of a -``result``. In this way an ``'a tzresult`` represents the result of a -computation that normally returns an ``'a`` but may fail. - -Because the type of errors is an abstract wrapper (``trace``) around an -extensible variant (``error``), you can only recover from these errors -in a generic way. - -| Pros: the type of a function indicates if it can fail or not, you - cannot forget to check for success/failure. -| Cons: you cannot check which error was raised, registration is heavy - and complicated. - -**result** - -With ``result``, errors are carried by the ``Error`` constructor. Each -function defines its own type of errors. - -| Pros: the type of a function indicates if and how it can fail, you - cannot forget to check for success/failure, you can check the payload - of failures. -| Cons: different errors from different functions cannot be used - together (need conversions), ``and*`` is unusable. - -**option** - -With ``option``, errors are represented by the ``None`` constructor. -Errors are completely void of payload. - -Because there are no payloads attached to an error, you should generally -treat the error directly at the call site. Otherwise you might lose -track of the origin of the failure. E.g., what was not found in the -following code fragment? - -:: - - match - let ( let* ) = Option.bind in - let* z = find "zero" in - let* o = find "one" in - Some (z, o) - with - | None -> .. - | Some (z, o) -> .. - -| Pros: the type of a function indicates if it can fail, you cannot - forget to check for success/failure. -| Cons: a single kind of errors means it cannot be very informative. - -**fallback** - -Another approach to errors is to have a default or fallback value. In -that case, the function returns a default sensible value when it would -raise and exception or return an error. Alternatively, it can take this -fallback value as parameter. - -:: - - (** @raise Not_found if argument is [None] *) - val get : 'a option -> 'a - - (** returns [default] if argument is [None] *) - val value : default:'a -> 'a option -> 'a - -| Pros: there is no error. -| Cons: doesn’t work for every function, works differently on different - functions. +.. toctree:: + :maxdepth: 2 + error_monad_p4_appendices diff --git a/docs/developer/error_monad_p1_result.rst b/docs/developer/error_monad_p1_result.rst new file mode 100644 index 0000000000..2994f8fc1e --- /dev/null +++ b/docs/developer/error_monad_p1_result.rst @@ -0,0 +1,997 @@ +Part 1: ``result``, Lwt, and Lwt-``result`` +-------------------------------------------- + +This is Part 1 of 4 of the :doc:`./error_monad` tutorial. + +The ``result`` type +~~~~~~~~~~~~~~~~~~~ + +The type ``result`` is part of the standard library of OCaml. It is +defined as + +:: + + type ('a, 'b) result = + | Ok of 'a + | Error of 'b + +(See `reference +manual `__.) + +The constructors of the ``result`` type have meaning: ``Ok`` is for +normal, successful cases that carry a value that is somewhat expected. +``Error`` is for abnormal, failure cases that carry information about +what went wrong. E.g., + +:: + + let get a index = + if index < 0 then + Error "negative index in array access" + else if index >= Array.length a then + Error "index beyond length in array access" + else + Ok a.(index) + +You can see the ``result`` type as an opinionated ``either``: a +left-or-right sum type where the left and right side have distinct +roles. Or you can see the ``result`` type as a buffed-up ``option`` +type: a type that either carries a value or doesn’t (but in this case it +carries an error instead). + +Exercises +^^^^^^^^^ + +- Write the implementation for + + :: + + (** [to_option r] is [Some x] if [r] is [Ok x]. Otherwise it is [None]. *) + val to_option : ('a, unit) result -> 'a option + +- Write the implementation for + + :: + + (** [to_option ?log r] is [Some x] if [r] is [Ok x]. Otherwise it calls + [log e] and returns [None] if [r] is [Error e]. By default [log] is + [ignore]. *) + val to_option : ?log:('e -> unit) -> ('a, 'e) result -> 'a option + +- Write the implementation for + + :: + + (** [catch f] is [Ok (f ())] except if [f] raises an exception [exc] in + which case it is [Error exc]. *) + val catch : (unit -> 'a) -> ('a, exn) result + +The binding operator +~~~~~~~~~~~~~~~~~~~~ + +Working directly with the ``result`` type can quickly become cumbersome. +Consider, for example the following code. + +:: + + (** [compose3 f g h x] is [f (g (h x))] except that it handles errors. *) + let compose3 f g h x + match h x with + | Error e -> Error e + | Ok y -> + match g y with + | Error e -> Error e + | Ok z -> + f z + +The nested ``match``-``with`` constructs lead to further and further +indentation. The ``Error`` cases are all identical and simply add noise. + +To circumvent this, in Octez we use a `binding +operator `__: a user-defined +``let``-binding. Specifically, you can open the ``Result_syntax`` module +which includes the binding operator ``let*`` dedicated to ``result``. + +:: + + (** [compose3 f g h x] is [f (g (h x))] except that it handles errors. *) + let compose3 f g h x + let open Result_syntax in (* adds [let*] in scope *) + let* y = h x in + let* z = g y in + f z + +An expression ``let* x = e in e'`` is equivalent to +``Result.bind e (fun x -> e')`` and also to +``match e with | Error err -> Error err | Ok x -> e'``. In all of these forms, +the expression ``e'`` is evaluated if and only if the expression ``e`` is +successful (i.e., evaluates to ``Ok``). + +.. _exercises-1: + +Exercises +^^^^^^^^^ + +- Rewrite the following code without ``match``-``with`` + + :: + + let apply2 (f, g) (x, y) = + match f x with + | Error e -> Error e + | Ok u -> + match g y with + | Error e -> Error e + | Ok v -> Ok (u, v) + + Did you remember to open the syntax module? + +- Write the implementation for + + :: + + (** [map f [x1; x2; x3; ..]] is a list [[y1; y2; y3; ..]] where [y1 = f x1], + [y2 = f x2], etc. except if [f] is fails on one of the inputs, in which + case it is an [Error] carrying the same error as [f]'s. *) + val map : ('a -> ('b, 'err) result) -> 'a list -> ('a list, 'err) result + + Note that this exercise is for learning only. You won’t need to write + this function in Octez. Indeed, a helper function which does exactly + that is provided in the extended standard library of Octez. + +Aside: the ``Error_monad`` module is opened everywhere +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In Octez, the ``Error_monad`` module provides types and values for error +management. It is part of the ``tezos-error-monad`` package. And it is +opened in most of the source code. Apart from some specific libraries +(discussed later), the content of this module is already in scope. + +The ``Error_monad`` module contains the ``Result_syntax`` module. This +is why you can use ``let open Result_syntax in`` directly in your own +functions. + +The ``Error_monad`` module contains other modules and functions and +types which you will learn about later. + +Recovering from errors +~~~~~~~~~~~~~~~~~~~~~~ + +When given a value of type ``result``, you can inspect its content to +determine if it is an ``Ok`` or an ``Error``. You can use this feature +to recover from the failures. + +:: + + match e with + | Ok x -> do_something x + | Error e -> do_something_else e + +Recovering can mean different things depending on the task that failed +and the error with which it failed. Sometimes you just want to retry, +sometimes you want to retry with a different input, sometimes you want +to propagate the error, sometimes you want to log the error and continue +as if it hadn’t happened, etc. + +:: + + let rec write data = + match write_to_disk data with + | Ok () -> () + | Error EAGAIN -> write data (* again: try again *) + | Error ENOSPC -> Stdlib.exit 1 (* no space left on device: escalate to exit *) + +There is a correspondence between a ``match``-``with`` around a +``result`` and a ``try``-``with``. Both are for recovering from +failures. However, in Octez, you will mostly use a ``match``-``with`` +around a ``result``, because we favour ``result`` over exceptions. You +may use the ``try``-``with`` construct when interfacing with an external +library which uses exceptions. + +There are several ways to use the ``match``-``with`` recovery with the +binding operator from ``Result_syntax``. Depending on the size of the +expression you are recovering from, one may be more readable than the +other. Choose accordingly. + +You can simply place the expression directly inside the +``match``-``with``. + +:: + + match + let* x = get_horizontal point in + let* y = get_vertical point in + Ok (x, y) + with + | Ok (x, y) -> .. + | Error e -> .. + +Alternatively, if the expression grows too much in size or in +complexity, you can move the expression inside a vanilla +``let``-binding: ``let r = .. in match r with ..``. + +Alternatively, if the expression grows even more, or if the expression +may be re-used in other parts of the code, you may move the expression +inside a vanilla function which you can call inside the ``match``-``with``. + +You can also use the functions from `the standard library’s Result +module `__. Note however, that some +of these functions are shadowed in the extended library of Octez, which +you will learn more about later. + +Mixing different kinds of errors +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Occasionally, you may have to call a function which returns a value of +type, say, ``(_, unit) result`` and one, say, ``(_, string) result``. In +this case, you cannot simply bind the two expressions as is. +Specifically, the type checker will complain. You can see the constraint +you would be breaking in the type of ``let*`` where the two error types +are the same (``'e``): + +:: + + val ( let* ) : ('a, 'e) result -> ('a -> ('b, 'e) result) -> ('b, 'e) result + +When you need to mix those function, you have to either handle the +errors of each independently (see the section above about recovering from +errors) or you need to convert the errors so they have the same type. +You should use ``Result.map_error`` to do that. + +:: + + let* cfg = + Result.map_error (fun () -> "Error whilst reading configuration") + @@ read_configuration () + in + .. + +The ``Result_syntax`` module +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You have already learned about the ``let*`` binding operator from the +``Result_syntax``. But there are other values you can use from this +module. + +The following functions form the core of the ``Result_syntax`` module. + +- ``let*``: a binding operator to continue with the value in the ``Ok`` + constructor or interrupt with the error in the ``Error`` constructor. + + ``let* x = e in e'`` is equivalent to + ``match e with Error err -> Error err | Ok x -> e'``. + + (See above for examples and more details.) + +- ``return : 'a -> ('a, 'e) result``: the expression ``return x`` is + equivalent to ``Ok x``. The function is included for consistency with + other syntax modules presented later. You can use either form. + +- ``fail : 'e -> ('a, 'e) result``: the expression ``fail e`` is + equivalent to ``Error e``. The function is included for consistency + with other syntax modules presented later. You can use either form. + +The following functions offer additional, less often used +functionalities. + +- ``both : ('a, 'e) result -> ('b, 'e) result -> ('a * 'b, 'e list) result``: + the expression ``both e1 e2`` is ``Ok`` if both expressions + evaluate to ``Ok`` and ``Error`` otherwise. + + Note that the expression ``both e1 e2`` is different from the + expression ``let* x = e1 in let* y = e2 in return (x, y)``. In the + former (``both``) version, both ``e1`` and ``e2`` are evaluated, + regardless of success/failure of ``e1`` and ``e2``. In the latter + (``let*``-``let*``) version, ``e2`` is evaluated if and only if + ``e1`` is successful. + + This distinction is important when the expressions ``e1`` and ``e2`` + have side effects: ``both (f ()) (g ())``. + +- ``all : ('a, 'e) result list -> ('a list, 'e list) result``: the + function ``all`` is a generalisation of ``both`` from tuples to + lists. + + Note that, as a generalisation of ``both``, in a call to the function + ``all``, all the elements of the list are evaluated, regardless of + success/failure of the elements: ``all (List.map f xs)``. + +- ``join : (unit, 'e) result list -> (unit, 'e list) result``: the + function ``join`` is a specialisation of ``all`` for lists of + unit-typed expressions (typically, for side-effects). + + Note that, as a specialisation of ``all``, in a call to the function + ``join``, all the elements of the list are evaluated, regardless of + success/failure of the elements: ``join (List.map f xs)``. + +The following functions do not provide new functionalities but they are +useful for small performance gains or for shorter syntax. + +- ``return_unit`` is equivalent to ``return ()`` but it avoids one + allocation. This is important in parts of the code that are + performance critical, and it is a good habit to take otherwise. + + | ``return_nil`` is equivalent to ``return []`` but it avoids one + allocation. + | ``return_true`` is equivalent to ``return true`` but it avoids one + allocation. + | ``return_false`` is equivalent to ``return false`` but it avoids + one allocation. + + | ``return_none`` is equivalent to ``return None`` but it avoids one + allocation. + | ``return_some x`` is equivalent to ``return (Some x)`` and it is + provided for completeness with ``return_none``. + +- ``let+`` is a binding operator similar to ``let*`` but when the + expression which follows the ``in`` returns a non-result value. In + other words, ``let+ x = e in e'`` is equivalent to + ``let* x = e in return (e')``. + + The ``let+`` is purely for syntactic conciseness (compared to the ``*`` + variant), use it if it makes + your code more readable. + +Lwt +~~~ + +In Octez, I/O and concurrency are handled using the Lwt library. With +Lwt you use *promises* to handle I/O and concurrency. You can think of +promises as data structures that are empty until they *resolve*, at +which point they hold a value. + +A promise for a value of type ``'a`` has type ``'a Lwt.t``. The function +``Lwt.bind : 'a t -> ('a -> 'b t) -> 'b t`` waits for the promise to +resolve (i.e., to carry a value of type ``'a``) before applying the +provided function. The expression ``bind p f`` is a promise which +resolves only once the promise ``p`` has resolved *and then* the promise +returned by ``f`` has resolved too. + +If you are not familiar with Lwt, you should check out `the official manual +`__ and `this +introduction `__ +before continuing. This is important. Do it. + +Unlike is mentioned in those separate resources on Lwt, in Octez, we +do not in general use the success/failure mechanism of Lwt. Instead, we +mostly rely on ``result`` (as mentioned above). + +Thus, in the rest of this tutorial we only consider the subset of Lwt +without failures. In practice, you might need to take care of exceptions +in some cases, but this is discussed in the later, more advanced parts of the +tutorial. + +The ``Lwt_syntax`` module +~~~~~~~~~~~~~~~~~~~~~~~~~ + +In Octez, because Lwt is pervasive, you need to bind promises often. To +make it easier, you can use the ``Lwt_syntax`` module. The +``Lwt_syntax`` module is made available everywhere by the +``Error_monad`` module. The ``Lwt_syntax`` module is similar to the +``Result_syntax`` module but for the Lwt monad (more about monads +later). + +- ``let*``: a binding operator to wait for the promise to resolve + before continuing. + + ``let* x = e in e'`` is a promise that resolves after ``e`` has + resolved to a given value and then ``e'`` has resolved with that + value carried by ``x``. + + Note that ``Lwt_syntax`` and ``Result_syntax`` (see above) both use + ``let*`` for their main binding operator. Consequently, the specific + meaning of ``let*`` depends on which module is open. This extends to + other syntax modules introduced later in this tutorial. + + (What if you need to use both Lwt and ``result``? Which syntax module + should you use? You will learn about that in the next section!) + +- ``return : 'a -> 'a Lwt.t``: the expression ``return x`` is equivalent to + ``Lwt.return x``. It is a promise that is already resolved with the value of + ``x``. + +- ``and*``: a binding operator alias for ``both`` (see below). You can + use it with ``let*`` the same way you use ``and`` with ``let``. + + :: + + let apply_triple f (x, y, z) = + let open Lwt_syntax in + let* u = f x + and* v = f y + and* w = f z + in + return (u, v, w) + + When you use ``and*``, the bound promises (``f x``, ``f y``, and + ``f z``) are evaluated concurrently, and the expression which follows + the ``in`` (``return ..``) is evaluated once all the bound promises + have all resolved. + +The following functions offer additional, less often used +functionalities. + +- ``both: 'a Lwt.t -> 'b Lwt.t -> ('a * 'b) Lwt.t``: the expression + ``both p q`` is a promise that resolves only once both promises + ``p`` and ``q`` (which make progress concurrently) have resolved. + + In practice, you will most likely use ``and*`` instead of both. + +- ``all: 'a Lwt.t list -> 'a list Lwt.t``: the function ``all`` is a + generalisation of ``both`` from tuples to lists. + + Note that, as a generalisation of ``both``, in a call to the function + ``all``, all the promises in the provided list make progress towards + resolution concurrently. + +- ``join : unit Lwt.t list -> unit Lwt.t``: the function ``join`` is a + specialisation of ``all`` to lists of units (i.e., side-effects). + +The following functions do not provide new functionalities but they are +useful for small performance gains or for shorter syntax. + +- ``return_unit`` is equivalent to ``return ()`` but it avoids one + allocation. This is important in parts of the code that are + performance critical, and it is a good habit to take otherwise. + + | ``return_nil`` is equivalent to ``return []`` but it avoids one + allocation. + | ``return_true`` is equivalent to ``return true`` but it avoids one + allocation. + | ``return_false`` is equivalent to ``return false`` but it avoids + one allocation. + + | ``return_none`` is equivalent to ``return None`` but it avoids one + allocation. + | ``return_some x`` is equivalent to ``return (Some x)`` and it is + provided for completeness. + + | ``return_ok x`` is equivalent to ``return (Ok x)`` and it is + provided for completeness. + | ``return_error x`` is equivalent to ``return (Error x)`` and it is + provided for completeness. + +- ``let+`` and ``and+`` are binding operators similar to ``let*`` and + ``and*`` but when the expression which follows the ``in`` returns a + non-promise value. In other words, ``let+ x = e1 and+ y = e2 in e`` is + equivalent to ``let* x = e1 and* y = e2 in return e``. + + The ``let+`` and ``and+`` are purely for syntactic conciseness (compared to + the ``*`` variants), use them if it makes your code more readable. + +Promises of results: Lwt and ``result`` together +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In Octez, we have functions that perform I/O and also may fail. In this +case, the function returns a promise of a ``result``. This is the topic +of this section. + +Note that Lwt and ``result`` are orthogonal concerns. On the one hand, +Lwt is for concurrency, for automatically scheduling code around I/O, +for making progress on different parts of the program side-by-side. On +the other hand, ``result`` is for aborting computations, for handling +success/failures. It is because Lwt and ``result`` are orthogonal that +we can use them together. + +:: + + 'a --------------> ('a, 'e) result + | | + | | + V V + 'a Lwt.t ---------> ('a, 'e) result Lwt.t + +When we combine Lwt and ``result`` for control-flow purpose we combine +both of the orthogonal behaviours. We can achieve this combined +behaviour “by hand”. However, doing so requires mixing +``Lwt_syntax.( let* )`` and regular ``match``-``with``: + +:: + + let apply2 (f, g) (x, y) = + let open Lwt_syntax in + let* r = f x in + match r with + | Error e -> return (Error e) + | Ok u -> + let* r = g y in + match r with + | Error e -> return (Error e) + | Ok v -> return (Ok (u, v)) + +This is interesting to consider because it shows the two orthogonal +features of control-flow separately: wait for the promise to resolve, +and check for errors. However, in practice, this becomes cumbersome even +faster than when working with plain ``result`` values. + +To make this easier, in Octez we use a binding operator. Specifically, +you can open the ``Lwt_result_syntax`` (instead of the other syntax +modules) which includes a binding operator dedicated to promises of +``result``. + +:: + + let apply2 (f, g) (x, y) = + let open Lwt_result_syntax in + let* u = f x in + let* v = g y in + return (u, v) + +When a promise resolves to ``Ok`` we say that it resolves successfully. +When it resolves to ``Error`` we say that it resolves unsuccessfully or +that it fails. + +.. _exercises-2: + +Exercises +^^^^^^^^^ + +- Rewrite the following code without ``match``-``with`` + + :: + + let compose3 f g h x + let open Lwt_syntax in + let* r = h x in + match r with + | Error e -> return (Error e) + | Ok y -> + let* s = g y in + match s with + | Error e -> return (Error e) + | Ok z -> + f z + + Did you remember to change the opened syntax module? + +The ``Lwt_result_syntax`` module +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Octez provides the ``Lwt_result_syntax`` module to help handle promises +of results. + +- ``let*``: a binding operator to wait for the promise to resolve + before continuing with the value in the ``Ok`` constructor or + interrupting with the error in the ``Error`` constructor. + + Note how the ``let*`` binding operator combines the behaviour of + ``Lwt_syntax.( let* )`` and ``Result_syntax.( let* )``. Also note + that the different ``let*``\ s are differentiated by context; + specifically by what syntax module has been opened. + +- ``return: 'a -> ('a, 'e) result Lwt.t``: the expression ``return x`` + is a promise already successfully resolved to ``x``. More formally, + ``return x`` is equivalent to + ``Lwt_syntax.return (Result_syntax.return x)``. + +- ``fail: 'e -> ('a, 'e) result Lwt.t``: the expression ``fail e`` is a + promise already unsuccessfully resolved with the error ``e``. More + formally, ``fail e`` is equivalent to + ``Lwt_syntax.return (Result_syntax.fail e)``. + +The following functions offer additional, less often used +functionalities. + +- ``both : ('a, 'e) result Lwt.t -> ('b, 'e) result Lwt.t -> ('a * 'b, 'e list) result Lwt.t``: + the expression ``both p1 p2`` is a promise that resolves + successfully if both ``p1`` and ``p2`` resolve successfully. It + resolves unsuccessfully if either ``p1`` or ``p2`` resolve + unsuccessfully. + + Note that in the expression ``both p1 p2``, both promises ``p1`` and + ``p2`` are evaluated concurrently. Moreover, the returned promise + only resolves once both promises have resolved, even if one resolves + unsuccessfully. + + Note that this syntax module does not offer ``and*`` as a binding + operator alias for ``both``. This is because, as with + ``Result_syntax``, the type for errors in ``both`` is not stable (it + is ``'e`` on the argument side and ``'e list`` on the return side). + This hinders practical uses of ``and*``. + +- ``all : ('a, 'e) result Lwt.t list -> ('a list, 'e list) result Lwt.t``: + the function ``all`` is a generalisation of ``both`` from tuples to + lists. + + Note that, as a generalisation of ``both``, in a call to the function + ``all``, all the promises in the provided list make progress towards + resolution concurrently and continue to evaluate until resolution + regardless of successes and failures. + +- ``join : (unit, 'e) result Lwt.t list -> (unit, 'e list) result Lwt.t``: + the function ``join`` is a specialisation of ``all`` for lists of + unit-type expressions (typically, for side-effects). + +The following functions do not provide new functionalities but they are +useful for small performance gains or for shorter syntax. + +- ``return_unit`` is equivalent to ``return ()`` but it avoids one + allocation. This is important in parts of the code that are + performance critical, and it is a good habit to take otherwise. + + | ``return_nil`` is equivalent to ``return []`` but it avoids one + allocation. + | ``return_true`` is equivalent to ``return true`` but it avoids one + allocation. + | ``return_false`` is equivalent to ``return false`` but it avoids + one allocation. + + | ``return_none`` is equivalent to ``return None`` but it avoids one + allocation. + | ``return_some x`` is equivalent to ``return (Some x)`` and it is + provided for completeness. + + Note that, like with ``Result_syntax``, this syntax module does not + provide ``return_ok`` and ``return_error``. This is to avoid nested + ``result`` types. If you need to nest ``result``\ s you can do so by + hand. + +- ``let+`` is a binding operator similar to ``let*`` but when the + expression which follows the ``in`` returns a non-promise value. In + other words, ``let+ x = e in e'`` is equivalent to + ``let* x = e in return (e')``. + + The ``let+`` is purely for syntactic conciseness (compared to the ``*`` + variant), use it if it makes your code more readable. + +.. _exercises-3: + +Exercises +^^^^^^^^^ + +- Write the implementation for + + :: + + (** [map f [x1; x2; ..]] is a promise for a list [[y1; y2; .. ]] where [y1] + is the value that [f x1] successfully resolves to, etc. except if [f] + resolves unsuccessfully on one of the input in which case it also + resolves unsuccessfully with the same error as [f]. *) + map : ('a -> ('b, 'e) result Lwt.t) -> 'a list -> ('b list, 'e) result Lwt.t + + How does your code compare to the one in the ``result``-only variant + of this exercise? + + Note that this exercise is for learning only. You won’t need to write + this function in Octez. Indeed, a helper function which does exactly + that is provided in the extended standard library of Octez. + +- Make your ``map`` function tail-recursive. + +- What type error is triggered by the following code? + + :: + + open Lwt_result_syntax ;; + let ( and* ) = both ;; + let _ = + let* x = return 0 and* y = return 1 in + let* z = return 2 in + return (x + y + z) ;; + +- Rewrite the following function without ``match``-``with`` + + :: + + let compose3 f g h x = + let open Lwt_syntax in + let* y_result = f x in + match y_result with + | Error e -> return (Error e) + | Ok y -> + let* z_result = g y in + match z_result with + | Error e -> return (Error e) + | Ok z -> + h z + +Converting errors of promises +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Remember that, with ``Result_syntax``, you cannot mix different types of +errors in a single sequence of ``let*``. This also applies to +``Lwt_result_syntax``. Indeed, the type checker will prevent you from +doing so. + +You can use the same ``Result.map_error`` function as for plain +``result``\ s. But when you are working with promises of ``result``, the +syntactic cost of doing so is high: + +:: + + let open Lwt_result_syntax in + let* config = + let open Lwt_syntax in + let* config_result = read_configuration () in + Lwt.return (Result.map_error (fun () -> ..) config_result) + in + .. + +To avoid this syntactic weight, the ``Lwt_result_module`` provides a +dedicated function: + +:: + + lwt_map_error : ('e -> 'f) -> ('a, 'e) result Lwt.t -> ('a, 'f) result Lwt.t + +Lifting +~~~~~~~ + +Occasionally, whilst you are working with promises of ``result`` (i.e., +working with values of the type ``(_, _) result Lwt.t``), you will need +to call a function that returns a simple promise (a promise that cannot +fail, a promise of a value that’s not a ``result``, i.e., a value of +type ``_ Lwt.t``) or a simple result (an immediate value of a +``result``, i.e., a value of type ``(_, _) result``). This is common +enough that the module ``Lwt_result_syntax`` provides helpers dedicated +to this. + +From ``result``-only into Lwt-``result`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The module ``Lwt_result_syntax`` includes the binding operator ``let*?``. It is +dedicated to binding Result-only expressions. + +:: + + let*? x = check foo bar in (* Result-only: checking doesn't yield *) + .. + + +.. sidebar:: Mnemonic + + The ``let*?`` binding operator uses the question mark (``?``) to represent + the uncertainty of the ``result``. Is it a success? Is it a failure? + + +From Lwt-only into Lwt-``result`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The module ``Lwt_result_syntax`` includes the binding operator ``let*!``. It is +dedicated to binding Lwt-only expressions. + +:: + + let*! x = Events.emit foo bar in (* Lwt-only: logs can't fail *) + .. + + +.. sidebar:: Mnemonic + + The ``let*!`` binding operator uses the exclamation mark (``!``) to represent + the impossibility of errors: Thou shall not fail! + + +Wait! There is too much! What module am I supposed to open locally and what operators should I use? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you are feeling overwhelmed by the different syntax modules, here are +some simple guidelines. + +- If your function returns ``(_, _) result Lwt.t`` values, then you + start the function with ``let open Lwt_result_syntax in``. Within the + function you use + + - ``let`` for vanilla expressions, + - ``let*`` for Lwt-``result`` expressions, + - ``let*!`` for Lwt-only expressions, + - ``let*?`` for ``result``-only expressions. + + And you end your function with a call to ``return``. + +- If your function returns ``(_, _) result`` values, then you start the + function with ``let open Result_syntax in``. Within the function you + use + + - ``let`` for vanilla expressions, + - ``let*`` for ``result`` expressions, + + And you end your function with a call to ``return``. + +- If your function returns ``_ Lwt.t`` values, then you start the + function with ``let open Lwt_syntax in``. + + - ``let`` for vanilla expressions, + - ``let*`` for Lwt expressions, + + And you end your function with a call to ``return``. + +These are rules of thumb and there are exceptions to them. Still, they +should cover most of your uses and, as such, they are a good starting +point. + +What’s an error? +~~~~~~~~~~~~~~~~ + +So far, this tutorial has considered errors in an abstract way. Most of +the types carried by the ``Error`` constructors have been parameters +(``'e``). This is a common pattern for higher-order functions that +compose multiple ``result`` and Lwt-``result`` functions together. But, +in practice, not every function is a higher-order abstract combinator +and you sometimes need to choose a concrete error. This section explores +common choices. + +**A dedicated algebraic data type** + +Often, a dedicated algebraic data type is appropriate. A sum type +represents the different kinds of failures that might occur. E.g., +``type hashing_error = Not_enough_data | Invalid_escape_sequence``. A +product type (typically a record) carries multiple bits of information +about a failure. E.g., +``type parsing_error = { source: string; location: int; token: token; }`` + +This approach works best when a set of functions (say, all the functions +of a module) have similar ways to fail. Indeed, when that is the case, +you can simply define the error type once and all calls to these +functions can match on that error type if need be. + +E.g., `binary encoding and decoding errors in +data-encoding `__. + +**Polymorphic variants** + +In some cases, the different functions of a module may each fail with +different subsets of a common set of errors. In such a case, you can use +`polymorphic variants `__ to +represent errors. E.g., + +:: + + val connect_to_peer: + address -> (connection, [ `timeout | `connection_refused ]) result Lwt.t + val send_message: + connection -> signing_key -> string -> + (unit, [ `timeout | `connection_closed ]) result Lwt.t + val read_message: + connection -> + (string, [ `timeout | `unknown_signing_key | `invalid_signature | `connection_closed ]) result Lwt.t + val close_connection: connection -> (unit, [ `unread_messages of string list ]) result + +The benefit of this approach is that the caller can compose the +different functions together easily and match only on the union of +errors that may actually happen. The type checker keeps track of the +variants that can reach any program point. + +:: + + let handshake conn = + let open Lwt_result_syntax in + let* () = send_message conn "ping" in + let* m = read_message conn in + if m = "pong" then + return () + else + `unrecognised_message m + + let handshake conn = + let open Lwt_syntax in + let* r = handshake conn in + match r with + | Ok () -> return_unit + | Error (`unknown_signing_key | `invalid_signature) -> + (* we ignore unread messages if the peer had signature issues *) + let _ = close_connection conn in + return_unit + | Error (`timeout | `connection_closed) -> + match close_connection with + | Ok () -> return_unit + | Error (`unread_messages msgs) -> + let* () = log_unread_messages msgs in + return_unit + +**A human-readable string** + +In some cases, there is nothing to be done about an error but to inform +the user. In this case, the error may just as well be the message. + +It is important to note that these messages are not generally meant to +be matched against. Indeed, such messages may not be stable and even if +they are, they probably don’t carry precise enough information to be +acted upon. + +You should only use ``string`` as an error type when the error is not +recoverable and you should not try to recover from ``string`` errors (or +more precisely, your recovery should not depend on the content of the +string). + +**An abstract type** + +If the error is not meant to be recovered from, it is sometimes ok to use an +abstract type. This is generally useful at the interface of a module, +specifically when the functions within the module are meant to inspect +the errors and possibly attempt recovery, but the callers outside of the +modules are not. + +If you do use an abstract type for errors, you should also provide a +pretty-printing function. + +**A wrapper around one of the above** + +Sometimes you want to add context or information to an error. E.g., + +:: + + type 'a with_debug_info = { + payload: 'a; + timestamp: Time.System.t; + position: string * int * int * int; + } + + let with_debug_info ~position f = + match f () with + | Ok _ as ok -> ok + | Error e -> Error { payload = e; timestamp = Time.System.now (); position } + +This specific example can be useful for debugging, but other wrappers +can be useful in other contexts. + +**Mixing error types** + +It is difficult to work with different types of errors within the same +function. This most commonly happens if you are calling functions from +different libraries, which use different types of errors. + +This is difficult because the errors on both sides of the binding +operator are the same. + +:: + + val ( let* ) : ('a, 'e) result -> ('a -> ('b, 'e) result) -> ('b, 'e) result + +The error monad provides some support to deal with multiple types of +errors at once. But this support is limited. It is not generally an +issue because error-mixing is somewhat rare: it tends to happen at the +boundary between different levels of abstractions. + +If you encounter one of these situations, you will need to convert all +the errors to a common type. + +:: + + type error = Configuration_error | Command_line_error + + let* config = + match Config.parse_file config_file with + | Ok _ as ok -> ok + | Error Config.File_not_found -> Ok Config.default + | Error Config.Invalid_file -> Error Configuration_error + in + let* cli_parameters = + match Cli.parse_parameters () with + | Ok _ as ok -> ok + | Error Cli.Invalid_parameter -> Error Command_line_error + in + .. + +You can also use the ``Result.map_error`` and ``lwt_map_error`` +functions introduced in previous sections. + +Wait! It was supposed to be “one single uniform way of dealing with errors”! What is this? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The error management in Octez is a unified way (syntax modules +with regular, predictable interfaces) of handling different types of +errors. + +The variety of errors is a boon in that it lets you use whatever is the +most appropriate for the part of the code that you are working on. +However, the variety of errors is also a curse in that stitching +together functions which return different errors requires boilerplate +conversion functions. + +That’s where the global ``error`` type comes in: a unified type for +errors. And that’s for the next section to introduce. + +META COMMENTARY +~~~~~~~~~~~~~~~ + +The previous sections are not Octez-specific. True, the syntax modules +are defined within the Octez source tree, but they could be released +separately (and they will be) or they could easily be replicated in a +separate project. + +The next sections are Octez-specific. They introduce types and values +that are used within the whole of Octez. + +| You should take this opportunity to take a break. +| Come back in a few minutes. diff --git a/docs/developer/error_monad_p2_tzresult.rst b/docs/developer/error_monad_p2_tzresult.rst new file mode 100644 index 0000000000..261df8aa08 --- /dev/null +++ b/docs/developer/error_monad_p2_tzresult.rst @@ -0,0 +1,587 @@ +Part 2: ``tzresult`` and Lwt-``tzresult`` +------------------------------------------ + +This is Part 2 of 4 of the :doc:`./error_monad` tutorial. + +``error``, ``trace``, and ``tzresult`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``error`` type is an `extensible variant +type `__ defined in +the ``Error_monad`` module. + +Each part of the Octez source code can extend it to include some errors +relevant to that part. E.g., the p2p layer adds +``type error += Connection_refused`` whilst the store layer adds +``type error += Snapshot_file_not_found of string``. More information on +errors is presented later. + +The ``'error trace`` type is a data structure dedicated to holding +``error``\ s. It is exported by the ``Error_monad`` module. It is only +ever instantiated as ``error trace``. It can accumulate multiple errors, +which helps present information about the context in which an error +occurs. More information on traces is presented later. + +The ``'a tzresult`` type is an alias for ``('a, error trace) result``. +It is used in Octez to represent the possibility of failure in a generic +way. Using ``tzresult`` is a trade-off. You should only use it in +situations where the pros outweigh the cons. + +Pros: + +- A generic error that is the same everywhere means that the + binding operator ``let*`` can be used everywhere without having to + convert errors to a common type. +- Traces allow you to easily add + context to an existing error (see how later). + +Cons: + +- A generic wrapper around generic errors that cannot be + meaningfully matched against (although the pattern exists in legacy + code). +- Type information about errors is coarse-grained to the point of + being meaningless (e.g., there is no exhaustiveness check when + matching). +- Registration is syntactically heavy and requires care (see + below). + +In general, the type ``tzresult`` is mostly useful at a high-enough +level of abstraction and in the outermost interface of a module or even +package (i.e., when exposing errors to callers that do not have access +to internal implementation details). + +Generic failing +~~~~~~~~~~~~~~~ + +The easiest way to return a ``tzresult`` is via functions provided by +the ``Error_monad``. These functions are located at the top-level of the +module, as such they are available, unqualified, everywhere in the code. +They do not even require the syntax modules to be open. + +- ``error_with`` is for formatting a string and wrapping it inside an + ``error`` inside a ``trace`` inside an ``Error``. E.g., + + :: + + let retry original_limit (f : unit -> unit tzresult) = + let rec retry limit f + if limit < 0 then + error_with "retried %d times" original_limit + else + match f () with + | Error _ -> retry (limit - 1) f + | Ok () -> Ok () + in + retry original_limit f + + You can use all the formatting percent-escapes from the `Format + module `__. However, you should + generally keep the message on a single line so that it can be printed + nicely in logs. + + Formally, ``error_with`` has type + ``('a, Format.formatter, unit, 'b tzresult) format4 -> 'a``. This is + somewhat inscrutable. Suffice to say: it is used with a format string + and returns an ``Error``. + +- ``error_with_exn : exn -> 'a tzresult`` is for wrapping an exception + inside an ``error`` inside a ``trace`` inside an ``Error``. + + :: + + let media_type_kind s = + match s with + | "json" | "bson" -> Ok `Json + | "octet-stream" -> Ok `Binary + | _ -> error_with_exn Not_found + +- ``failwith`` is for formatting a string and wrapping it inside an + ``error`` inside a ``trace`` inside an ``Error`` inside a promise. + E.g., + + :: + + failwith "Cannot read file %s (ot %s)" file_name (Unix.error_message error) + + ``failwith`` is similar to ``error_with`` but for the combined + Lwt-``tzresult`` monad. Again the type + (``('a, Format.formatter, unit, 'b tzresult Lwt.t) format4 -> 'a``) + is inscrutable, but again usage is as simple as a formatting. + +- ``fail_with_exn`` is for wrapping an exception inside an ``error`` + inside a ``trace`` inside an ``Error`` inside a promise. E.g., + + :: + + fail_with_exn Not_found + + ``fail_with_exn`` is similar to ``error_with_exn`` but for the + combined Lwt-``tzresult`` monad. + +These functions are useful as a way to fail with generic errors that +carry a simple payload. The next section is about using custom errors +with more content. + +.. _exercises-5: + +Exercises +^^^^^^^^^ + +- Write a function ``tzresult_of_option : 'a option -> 'a tzresult`` + which replaces ``None`` with a generic failure of your choosing. + +- Write a function ``catch : (unit -> 'a) -> 'a tzresult`` which wraps + any exception raised during the evaluation of the function call. + +Declaring and registering ``error``\ s +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +On many occasions, ``error_with`` and friends (see above) are not +sufficient: you may want your error to carry more information than can +be conveyed in a simple string or a simple exception. When you do, you +need a custom error. You must first *declare* and then *register* an +``error``. + +To declare a new error you simply extend the ``error`` type. Remember +that the ``error`` type is defined and exported to the rest of the code +by the ``Error_monad`` module. You extend it with the ``+=`` syntax: + +:: + + type error += + Invalid_configuration of { expected: string; got: string; line: int } + +The registration function ``register_error_kind`` is also part of the +``Error_monad`` module. You *register* a new error by calling this +function. + +:: + + let () = + register_error_kind + `Temporary + ~id:"invalid_configuration" + ~title:"Invalid configuration" + ~description:"The configuration is invalid." + ~pp:(fun f (expected, got, line) -> + Format.fprintf f + "When parsing configuration expected %s but got %s (at line %d)" + expected got line + ) + Data_encoding.( + obj3 + (req "expected" string) + (req "got" string) + (req "line" int31)) + (function + | Invalid_configuration {expected; got; line} -> + Some (expected, got, line) + | _ -> None) + (fun (expected, got, line) -> Invalid_configuration {expected; got; line}) + +Note that you **MUST** register the errors you declare. Failure to do so +can lead to serious issues. + +The arguments for the ``register_error_kind`` function are as follows: - +category (:literal:`\`Temporary`): the category argument is meaningless +in the shell, just use :literal:`\`Temporary`. + +- ``id``: a short string containing only characters that do not need escaping + (``[a-zA-Z0-9._-]``), must be unique across the whole program. +- ``title``: a short human readable string. +- ``description``: a longer human readable string. +- ``pp``: a pretty-printing function carrying enough information for a full + error message for the user. Note that the function does not receive the error, + instead it receives the *projected payload of the error* (here a 3-tuple + ``(expected, got, line)``. +- encoding: an encoding for the projected payload of the error. +- projection: a partial function that matches the specific error + (out of all of them) and return its projected payload. This function always + has the form + ``function | -> Some | _ -> None``. +- injection: a function that takes the projected payload and constructs + the error out of it. + +For errors that do not carry information (e.g., +``type error += Size_limit_exceeded``), the projected payload of the +error is unit. + +It is customary to either register the error immediately after the error +is declared or to register multiple errors immediately after declaring +them all. In some cases, the registration happens in a separate module. +Either way, registration of declared error is compulsory. + +.. _exercises-6: + +Exercises +^^^^^^^^^ + +- Register the following error + + :: + + (** [Size_limit_exceeded {limit; current_size; attempted_insertion}] is used + when an insertion into the global table of known blocks would cause the + size of the table to exceed the limit. The field [limit] holds the + maximum allowed size, the field [current_size] holds the current size of + the table and [attempted_insertion] holds the size of the element that + was passed to the insertion function. *) + type error += Size_limit_exceeded { + limit: int; + current_size: int; + attempted_insertion: int + } + +The ``Tzresult_syntax`` module +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Remember that ``'a tzresult`` is a special case of ``('a, 'e) result``. +Specifically, a special case where ``'e`` is ``error trace``. +Consequently, you can handle ``tzresult`` values using the +``Result_syntax`` module. However, a more specialised module +``Tzresult_syntax`` is available. + +The ``Tzresult_syntax`` module is identical to the ``Result_syntax`` +module but for the following differences. + +- ``fail: 'e -> ('a, 'e trace) result``: the expression ``fail e`` + wraps ``e`` in a ``trace`` inside an ``Error``. When ``e`` is of type + ``error`` as is the case throughout Octez, ``fail e`` is of type + ``'a tzresult``. + +- ``and*``: a binding operator alias for ``both`` (see below). You can + use it with ``let*`` the same way you use ``and`` with ``let``. + + :: + + let apply_triple f (x, y, z) = + let open Tzresult_syntax in + let* u = f x + and* v = f y + and* w = f z + in + return (u, v, w) + + When you use ``and*``, the bound results (``f x``, ``f y``, and + ``f z``) are all evaluated fully, regardless of the success/failure + of the others. The expression which follows the ``in`` + (``return ..``) is evaluated if all the bound results are successful. + +- ``both : ('a, 'e trace) result -> ('b, 'e trace) result -> ('a * 'b, 'e trace) result``: + the expression ``both a b`` is ``Ok`` if both ``a`` and ``b`` are + ``Ok`` and ``Error`` otherwise`. + + Note that unlike ``Result_syntax.both``, the type of errors + (``error trace``) is the same on both the argument and return side of + this function: the traces are combined automatically. This remark + applies to the ``all`` and ``join`` (see below) as well. + + The stability of the return type is what allows this syntax module to + include an ``and*`` binding operator. + +- ``all : ('a, 'e trace) result list -> ('a list, 'e trace) result``: + the function ``all`` is a generalisation of ``both`` from tuples to + lists. + +- ``join : (unit, 'e trace) result list -> (unit, 'e trace) result``: + the function ``join`` is a specialisation of ``all`` for list of + unit-typed expressions (typically, for side-effects). + +- ``and+`` is a binding operator similar to ``and*`` but for use with + ``let+`` rather than ``let*``. + +.. _exercises-7: + +Exercises +^^^^^^^^^ + +- What is the difference between the two following functions? + + :: + + let twice f = + let open Tzresult_syntax in + let* () = f () in + let* () = f () in + return_unit + + :: + + let twice f = + let open Tzresult_syntax in + let* () = f () + and* () = f () + in + return_unit + +The ``Lwt_tzresult_syntax`` module +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In the same way ``result`` can be combined with Lwt, ``tzresult`` can +also be combined with Lwt. And in the same way that ``Tzresult_syntax`` +is a small variation of ``Result_syntax``, ``Lwt_tzresult_syntax`` is a +small variation of ``Lwt_result_syntax``. + +There are possibly too many parallels to keep track of, so the diagram +below might help. + +:: + + 'a -----------> ('a, 'e) result ------------> 'a tzresult + | | | + | | | + V V V + 'a Lwt.t ------> ('a, 'e) result Lwt.t ------> 'a tzresult Lwt.t + +Anyway, the ``Lwt_tzresult_syntax`` module is identical to the +``Lwt_result_syntax`` module but for the following differences. + +- ``fail: 'e -> ('a, 'e trace) result Lwt.t``: the expression + ``fail e`` wraps ``e`` in a ``trace`` inside an ``Error`` inside a + promise. When ``e`` is of type ``error`` as is the case throughout + Octez, ``fail e`` is of type ``'a tzresult Lwt.t``. + +- ``and*``: a binding operator alias for ``both``. You can use it with + ``let*`` the same way you use ``and`` with ``let``. + + :: + + let apply_triple f (x, y, z) = + let open Lwt_tzresult_syntax in + let* u = f x + and* v = f y + and* w = f z + in + return (u, v, w) + + When you use ``and*``, the bound promises (``f x``, ``f y``, and + ``f z``) are evaluated concurrently, and the expression which follows + the ``in`` (``return ..``) is evaluated once all the bound promises + have all resolved but only if all of them resolve successfully. + + Note how this ``and*`` binding operator inherits the properties of + both ``Lwt_syntax.( and* )`` and ``Tzresult_syntax.( and* )``. + Specifically, the promises are evaluated concurrently and the + expression which follows the ``in`` is evaluated only if all the + bound promises have successfully resolved. These two orthogonal + properties are combined. This remark also applies to ``both``, + ``all``, ``join`` and ``and+`` below. + +- ``both : ('a, 'e trace) result Lwt.t -> ('b, 'e trace) result Lwt.t -> ('a * 'b, 'e trace) result Lwt.t``: + the expression ``both p q`` is a promise that resolves once both + ``p`` and ``q`` have resolved. It resolves to ``Ok`` if both ``p`` + and ``q`` do, and to ``Error`` otherwise`. + + Note that unlike ``Lwt_result_syntax.both``, the type of errors + (``error trace``) is the same on both the argument and return side of + this function: the trace are combined automatically. This remark + applies to the ``all`` and ``join`` (see below) as well. + + The stability of the return type is what allows this syntax module to + include an ``and*`` binding operator. + +- ``all : ('a, 'e trace) result Lwt.t list -> ('a list, 'e trace) result Lwt.t``: + the function ``all`` is a generalisation of ``both`` from tuples to + lists. + +- ``join : (unit, 'e trace) result Lwt.t list -> (unit, 'e trace) result Lwt.t``: + the function ``join`` is a specialisation of ``all`` for lists of + unit-typed expressions (typically, for side-effects). + +- ``and+`` is a binding operator similar to ``and*`` but for use with + ``let+`` rather than ``let*``. + +.. _exercises-8: + +Exercises +^^^^^^^^^ + +- Rewrite this function to use the ``Lwt_tzresult_syntax`` module and + no other syntax module. + + :: + + let apply_tuple (f, g) (x, y) = + let open Lwt_syntax in + let* u = f x + and* v = g y + in + let r = Tzresult_syntax.both u v in + return r + +- Write the implementation for + + :: + + (** [map f [x1; x2; ..]] is [[y1; y2; ..]] where [y1] is the successful + result of [f x1], [y2] is the successful result of [f x2], etc. If [f] + fails on any of the inputs, returns an `Error` instead. Either way, all + the calls to [f] on all the inputs are evaluated concurrently and all + the calls to [f] have resolved before the whole promise resolves. *) + val map : ('a -> 'b tzresult Lwt.t) -> 'a list -> 'b list tzresult + +.. _lifting-1: + +Lifting +~~~~~~~ + +When you are working with promises of ``tzresult`` (i.e., within +Lwt-``tzresult``), you may occasionally need to call functions that +return a simple promise (i.e., within Lwt-only) or a simple ``tzresult`` +(i.e., within ``tzresult``-only). + +This situation is similar to that of ``Lwt_result_syntax`` and the +solutions are the same. Specifically, the additional binding operators provided +by ``Lwt_result_syntax`` are also available in ``Lwt_tzresult_syntax``. + +:: + + let*! x = plain_lwt_function foo bar in + let*? x = plain_result_function foo bar in + .. + + +Are you kidding me?! there is even more! what module am I supposed to open locally and what operators should I use? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can also use simple guidelines to use these syntax modules +effectively. + +- If your function returns ``_ tzresult Lwt.t`` values, then you start + the function with ``let open Lwt_tzresult_syntax in``. Within the + function you use + + - ``let`` for vanilla expressions, + - ``let*`` for Lwt-``tzresult`` expressions, + - ``let*!`` for Lwt-only expressions, + - ``let*?`` for ``tzresult``-only expressions. + + And you end your function with a call to ``return``. + +- If your function returns ``_ tzresult`` values, then you start the + function with ``let open Tzresult_syntax in``. Within the function + you use + + - ``let`` for vanilla expressions, + - ``let*`` for ``tzresult`` expressions, + + And you end your function with a call to ``return``. + +The rest of the guidelines (for ``(_, _) result Lwt.t``, +``(_, _) result``, and ``_ Lwt.t``) remain valid. + +Tracing +~~~~~~~ + +Remember that a trace is a data structure specifically designed for +errors. + +Traces have two roles: + +- As a programmer you benefit from the traces' ability to combine + automatically. Indeed, this feature of traces makes the ``and*`` binding + operators possible which can simplify some tasks such as concurrent + evaluation of multiple ``tzresult`` promises. + +- For the user, traces combine multiple errors, allowing for high-level + errors (e.g., ``Cannot_bootstrap_node``) to be paired with low-level + errors (e.g., ``Unix_error EADDRINUSE``). When used correctly, this + can help create more informative error messages which, in turn, can + help debugging. + +Tracing primitives are declared in the ``Error_monad`` module. As such, +they are available almost everywhere in the code. They should be used +whenever an error passes from one component (say the p2p layer, or the +storage layer) into another (say the shell). + +- ``record_trace err r`` leaves ``r`` untouched if it evaluates to + ``Ok``. Otherwise, it adds the error ``err`` to the trace carried in + ``Error``. + + :: + + let check_hashes head block operation = + let open Tzresult_syntax in + let* () = + record_trace (Invalid_hash { kind: "head"; hash: head}) @@ + check_hash chain + in + let* () = + record_trace (Invalid_hash { kind: "block"; hash: block}) @@ + check_hash block + in + let* () = + record_trace (Invalid_hash { kind: "operation"; hash: operation}) @@ + check_hash operation + in + return_unit + + In this example a failure from any of the calls to ``check_hash`` + will be given context that helps with understanding the source of the + error. + +- ``record_trace_eval`` is a lazy version of ``record_trace`` in that + the error added to the trace is only evaluated if needed. More + formally ``record_trace_eval make_err r`` leaves ``r`` untouched if + it evaluates to ``Ok``. Otherwise it calls ``make_err`` and adds the + returned error onto the trace. + + You should use the strict ``record_trace`` version when the error you + are adding to the trace is an immediate value (e.g., ``Overflow``) or + a constructor with immediate values (e.g., ``Invalid_file name``). + You should use the lazy ``record_trace_eval`` version when the error + you are adding to the trace requires computation to generate (e.g., + if it requires formatting or querying). + +- ``trace`` is the Lwt-aware variant of ``record_trace``. More + formally, ``trace err p`` leaves ``p`` untouched if it resolves + successfully, otherwise it adds the error ``err`` to the trace + carried by the unsuccessful resolve. + + :: + + let get_data_and_gossip_it () = + let open Lwt_tzresult_syntax in + let* data = + trace Cannot_get_random_data_from_storage @@ + Storage.get_random_data () + in + let* number_of_peers = + trace Cannot_gossip_data @@ + P2p.gossip data + in + return (data, number_of_peers) + + In this example, low-level storage errors are given more context by + the ``Cannot_get_random_data_from_storage`` error. Similarly, + low-level p2p errors are given more context by the + ``Cannot_gossip_data`` error. This is important because both the + storage and the p2p layer may suffer from similar system issues (such + as file-descriptor exhaustion). + +- ``trace_eval`` is the lazy version of ``trace``, or, equivalently, + the Lwt-aware version of ``record_trace_eval``. + + You should use the strict ``trace`` version when the error you are + adding is immediate or a constructor with immediate values. You + should use the lazy ``trace_eval`` version when the error you are + adding requires computation to generate. + +Do not hesitate to use the tracing primitives. Too much context is +better than too little context. Think of ``trace`` (and variants) as a +way to document Octez. Specifically, as making the error messages of +Octez more informative. + +.. _meta-commentary-1: + +META COMMENTARY +~~~~~~~~~~~~~~~ + +The previous sections had a practical focus: how to handle errors? how +to mix different syntaxes? how?! By contrast, the following sections are +in-depth discussions of advanced or tangential topics which you should +feel free to skim or even to skip. + +| You should take this opportunity to take a break. +| Come back in a few minutes. diff --git a/docs/developer/error_monad_p3_advanced.rst b/docs/developer/error_monad_p3_advanced.rst new file mode 100644 index 0000000000..004bc1a453 --- /dev/null +++ b/docs/developer/error_monad_p3_advanced.rst @@ -0,0 +1,340 @@ +Part 3: Advanced topics +------------------------ + +This is Part 3 of 4 of the :doc:`./error_monad` tutorial. + +Working with standard data-structures: Lwtreslib +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Handling values within the Lwt, ``result``, and Lwt-``result`` monads is +so common in Octez that you also have access to an extension of the +Stdlib dedicated to these monads: the ``Lwtreslib`` library. + +The ``tezos-lwt-result-stdlib`` package exports an ``Lwtreslib`` module +which is made available, through ``tezos-error-monad`` and +``tezos-base``, to the whole of the codebase. Specifically, within the +codebase of Octez the following modules of OCaml’s ``Stdlib`` are +shadowed by Lwtreslib’s: + +- ``List``, +- ``Result``, +- ``Option``, +- ``Seq``, +- ``Map``, +- ``Set``, and +- ``Hashtbl``. + +In all those modules, the underlying data structures are compatible with +those of the ``Stdlib`` and thus with the rest of the OCaml ecosystem. +However, the primitives in these modules are extended to support Lwt, +``result`` and the combination of the two. Specifically, for each +function that traverses the data structure, the module also contains +variants that perform the same traversal within each of the monad. E.g., +for ``List.map`` + +:: + + (* vanilla map *) + val map : ('a -> 'b) -> 'a list -> 'b list + + (* [result]-aware map: stops at the first error *) + val map_e : ('a -> ('b, 'trace) result) -> 'a list -> ('b list, 'trace) result + + (* sequential Lwt map: treats each element after the previous one *) + val map_s : ('a -> 'b Lwt.t) -> 'a list -> 'b list Lwt.t + + (* sequential Lwt-[result] map: + - treats each element after the previous one + - stops at the first error *) + val map_es : + ('a -> ('b, 'trace) result Lwt.t) -> + 'a list -> + ('b list, 'trace) result Lwt.t + + (* concurrent Lwt map: treats all the elements concurrently *) + val map_p : ('a -> 'b Lwt.t) -> 'a list -> 'b list Lwt.t + + (* concurrent Lwt-[result] map: + - treats all the elements concurrently + - treats the whole list no matter the success/errors *) + val map_ep : + ('a -> ('b, 'trace) result Lwt.t) -> + 'a list -> + ('b list, 'trace list) result Lwt.t + +Check out `the online documentation of +Lwtreslib <../api/odoc/_html/tezos-lwt-result-stdlib/Tezos_lwt_result_stdlib/Lwtreslib/index.html>`__ +for a description of the semantic and naming convention. + +In addition to shadowing existing modules, ``Lwtreslib`` also exports +new modules: + +- ``Seq_e`` for ``result``-aware variant of ``Seq``, +- ``Seq_s`` for Lwt-aware variant of ``Seq``, +- ``Seq_es`` for Lwt-``result``-aware variant of ``Seq``, and +- ``WithExceptions`` for unsafe accesses such as ``Option.get``. + +Whenever you need to traverse a standard data structure with some +``result`` or Lwt or Lwt-``result`` function, ``Lwtreslib`` should have +that function ready for you. **You should never fold over a data +structure with a promise or result accumulator.** E.g., you should +do + +:: + + List.rev_map_es fetch keys + +and you shouldn’t do + +:: + + let open Lwt_result_syntax in + List.fold_left + (fun resources key -> + let* resources = resources in + let* resource = fetch key in + return (resource :: resources)) + (return []) + keys + +If you do not find the traversal function you need, do not hesitate to +contribute to Lwtreslib. + +Working with traces and errors and such directly +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Occasionally, you may need more interaction with traces than the +primitives presented thus far. + +For error reporting or debugging purpose, you may need to show traces to +users. You can do so with the following values. + +- ``pp_print_trace``: a ``%a``-`compatible + formatter `__. Note that the trace + formatting is unspecified and subject to change. Also be aware that + it generally prints the trace over multiple lines. +- ``pp_print_top_error_of_trace``: a ``%a``-`compatible + formatter `__ that only shows the + most recent error in the trace (or one of the most recent errors if + there are several). This is useful to get shorter error messages. + Most often used for the declaration of logging events in + ``Internal_event.Simple``. +- ``trace_encoding``: an encoding for traces. Useful to combine into + encoding of data structures that contain traces. Most often used for + the declaration of logging events in ``Internal_event.Simple``. + +If you are working with non-standard data structures and if you need to +define monad-aware traversors for these data structures, you may need to +build some traces by hand. You can do so with the following values. + +- ``TzTrace.make : 'e -> 'e trace`` useful to convert an ``error`` into + an ``error trace``. By extension, this is useful to convert an + ``('a, error) result`` into an ``'a tzresult``. + +- ``TzTrace.cons : 'e -> 'e trace -> 'e trace`` is the low-level + combinators that builds-up traces. In most cases, you’ll want to use + ``trace`` or ``record_trace`` instead, but you might need it when you + are defining a low-level traversal function for some data structure. + + :: + + let iter_with_bounded_errors bound f xs = + (* we rely on syntax for Lwt, we handle results by hand *) + let open Lwt_syntax in + let rec aux_all_ok = function + | [] -> return_ok () + | x :: xs -> + let* r = f x in + match r with + | Ok () -> aux_all_ok xs + | Error e -> aux_some_error 1 (TzTrace.make e) xs + and aux_some_error num_errors trace xs = + if num_errors > bound then + return_error (TzTrace.cons (Exceeded_error_limit bound) trace) + else + match xs with + | [] -> return_ok () + | x :: xs -> + let* r = f x in + match r with + | Ok () -> aux_some_error num_errors trace xs + | Error e -> aux_some_error (num_errors + 1) (TzTrace.cons e trace) xs + in + aux_all_ok xs + +- ``TzTrace.conp : 'e trace -> 'e trace -> 'e trace`` is the parallel + composition of two traces. Unlike ``cons``, the traces composed by + ``conp`` are not organised hierarchically. The errors are presented + as having happened side-by-side. + + Note that currently there is little difference between cons and conp + traces. But the difference will be more marked in the future. + + You should use ``conp`` (rather than ``cons``) when you are gathering + errors and traces from two or more concurrent processes. + + + +.. _error_monad_within_protocol: + +Working within the protocol +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you are working on the protocol, things are slightly different for +you. This is because the protocol has a restricted access to external +resources and libraries. You can find more details in :doc:`the dedicated +documentation `. +This section focuses on the error-monad within the protocol. + +The protocol environment libraries evolve at a slightly different pace +than the underlying library. You need to check the ``mli`` files within +``src/lib_protocol_environment/sigs/``. + +Note that unlike in the shell, the traces in the protocol are already +abstract. As a result there is no matching of traces (and thus errors) +within the protocol: you can match ``Ok`` and ``Error``, but not the +payload of the ``Error``. This part of the legacy code has already been +removed. + +The main difference between the protocol and the shell is that the +``category`` parameter of the ``register_error_kind`` function is +meaningful. You must pass a category which is appropriate for the error +you are registering: + +- ``Branch``: is for branch-specific failures, i.e., failures that + happen in the current branch (of the chain) but maybe wouldn’t happen in a + different branch. E.g., a reference to an unknown block is invalid, but it + might become valid once the head block has changed. This category is + then used by the shell to retry after the branch changes. + +- ``Temporary``: is for transient failures, i.e., failures that happen + but may not always happen. This category is used by the shell to + retry at some later time. + +- ``Permanent``: is for irremediable failures, i.e., failures that + happen and will always happen whatever the context. E.g., + `originating a + contract `__ + that does not type-check is a permanent error. This is used by the + shell to mark the data as invalid. + +- ``Outdated``: is for failures that happen when some data is too old. + +Another thing to consider is that errors from the protocol can reach the +shell. However, because the ``error`` type of the protocol is distinct +from that of the shell, the protocol errors are wrapped inside a shell +error constructor. + +This has no impact within the protocol (where shell errors don’t exist) +nor within the shell (where protocol errors are automatically wrapped +inside a shell error). However, it can have an impact in the spaces in +between. Most typically, this matters in the unit-tests of the protocol +(``src/proto_alpha/lib_protocol/test/unit/``) where you call some +protocol functions directly. In this case, you need to wrap the errors +yourself, using the wrapping functions provided by the environment: +``Environment.wrap_tzresult``, ``Environment.wrap_tztrace``, and +``Environment.wrap_tzerror``. + +Working below the error-monad +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you are working on some low-level libraries (e.g., +``src/lib_stdlib``) or the external dependencies (e.g., +``data-encoding``) you don’t have access to the error monad at all. + +In this case, you can still use the ``result`` type but you need to +define your own ``let*`` binding operator: +``let ( let* ) = Result.bind``. + +You can also use Lwt which provides its own `Lwt.Syntax +module `__. + +Finally, the `Lwt_result +module `__ +(provided as part of Lwt) can help you deal with result-Lwt +combinations, including via its `Lwt_result.Syntax +module `__. + +Working with external libraries +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This tutorial covers error-management techniques in Octez. However, from +within Octez, you may need to call external libraries for cryptography +or RPCs or data-encoding or what have you. + +The first thing you do is to carefully read the documentation of the +external library you are using. You should check the overview +documentation with a look out for comments on error management. + +Then, you also need to read the documentation of each function that you +are calling. This documentation may explain how errors are handled: does +the function return a ``result``? does it raise and exception? is it +unspecified? + +If the function you are calling may raise exceptions, you should catch +these exceptions. You can either do so at the level of the call itself +or, if you are calling multiple functions that can all raise similar +exceptions, around a whole block of calls. + +When you catch an exception, the most common thing to do is to translate +it or wrap it into a ``result`` or a ``tzresult``. + +:: + + try + let v1 = Data_encoding.Json.destruct e1 j1 in + let v2 = Data_encoding.Json.destruct e2 j2 in + Ok (v1, v2) + with + | exc -> Error (Cannot_destruct_json_value exc) + +Note that if you are calling an Lwt function, you have to use ``Lwt.catch`` or +``Lwt.try_bind`` rather than ``try``-``with``. + +:: + + Lwt.catch + (fun () -> + let open Lwt_syntax in + let* () = Lwt_unix.mkdir d1 perm in + let* () = Lwt_unix.mkdir d2 perm in + Lwt_result_syntax.return_unit) + (function + | exc -> Lwt_result_syntax.fail (Cannot_destruct_json_value exc)) + +The error monad provides `several helpers functions for catching exceptions +`__. + +:: + + val catch : ?catch_only:(exn -> bool) -> (unit -> 'a) -> 'a tzresult + +If the function you are calling may raise exceptions only under +well-defined conditions on the parameters, then you can also check those +conditions yourself and ignore the exceptions. When doing so, please add +a comment to explain it. + +:: + + let get_or_defaults low_default high_default array offset = + if offset < 0 then + low_default + else if offset >= Array.length array then + high_default + else + (* This cannot raise because of checks on offset above *) + Array.get array offset + +If the function may fail with ``result``, you can map the error directly +or simply continue with it. If it may fail with ``option``, you can +translate ``None`` into an appropriate error. + +:: + + match find k kvs with + | None -> Error "cannot find key" + | Some v -> Ok v + +If the function’s documentation specifies some pre-conditions but +doesn’t explain what happens if those aren’t met, then you must check +those pre-conditions. diff --git a/docs/developer/error_monad_p4_appendices.rst b/docs/developer/error_monad_p4_appendices.rst new file mode 100644 index 0000000000..675b51ca19 --- /dev/null +++ b/docs/developer/error_monad_p4_appendices.rst @@ -0,0 +1,508 @@ +Part 4: Appendices +------------------- + +These appendices are Part 4 of 4 of the :doc:`./error_monad` tutorial. + +Legacy code +~~~~~~~~~~~ + +(This section will be removed once the whole code-base has been updated +to use the binding operators as recommended. In the meantime, you need +to learn some legacy constructs so you can read code that hasn’t been +upgraded yet. You should not use the operators introduced in this +section to write new code.) + +The legacy code is written with infix bindings instead of ``let``-style +binding operators. The binding ``>>?`` for ``result`` and ``tzresult``, +``>>=`` for Lwt, and ``>>=?`` for Lwt-``result`` and Lwt-``tzresult``. A +full equivalence table follows. + ++--------------------------------------+-------------------------------+ +| Modern | Legacy | ++--------------------------------------+-------------------------------+ +| :: | :: | +| | | +| let open Result_syntax in | e >>? fun x -> | +| let* x = e in | e' | +| e' | | ++--------------------------------------+-------------------------------+ +| :: | :: | +| | | +| let open Result_syntax in | e >|? fun x -> | +| let+ x = e in | e' | +| e' | | ++--------------------------------------+-------------------------------+ +| :: | :: | +| | | +| let open Lwt_syntax in | e >>= fun x -> | +| let* x = e in | e' | +| e' | | ++--------------------------------------+-------------------------------+ +| :: | :: | +| | | +| let open Lwt_syntax in | e >|= fun x -> | +| let+ x = e in | e' | +| e' | | ++--------------------------------------+-------------------------------+ +| :: | :: | +| | | +| let open Lwt_result_syntax in | e >>=? fun x -> | +| let* x = e in | e' | +| e' | | ++--------------------------------------+-------------------------------+ +| :: | :: | +| | | +| let open Lwt_result_syntax in | e >|=? fun x -> | +| let+ x = e in | e' | +| e' | | ++--------------------------------------+-------------------------------+ +| ``and*``, ``and+`` (any syntax | No equivalent, uses | +| module) | ``both_e``, ``both_p``, or | +| | ``both_ep`` | ++--------------------------------------+-------------------------------+ +| :: | :: | +| | | +| let open Lwt_result_syntax in | (e >>= ok) >>=? fun x -> | +| let*! x = e in | e' | +| e' | | ++--------------------------------------+-------------------------------+ +| :: | :: | +| | | +| let open Lwt_result_syntax in | e >>?= fun x -> | +| let*? x = e in | e' | +| e' | | ++--------------------------------------+-------------------------------+ + +In addition, instead of dedicated ``return`` and ``fail`` functions from +a given syntax module, the legacy code relied on global values. + ++--------------------------------------+-------------------------------+ +| Modern | Legacy | ++--------------------------------------+-------------------------------+ +| :: | :: | +| | | +| let open Result_syntax in | ok x | +| return x | | ++--------------------------------------+-------------------------------+ +| :: | No equivalent, uses | +| | ``Error e`` | +| let open Result_syntax in | | +| fail e | | ++--------------------------------------+-------------------------------+ +| :: | No equivalent, uses | +| | ``Lwt.return x`` | +| let open Lwt_syntax in | | +| return x | | ++--------------------------------------+-------------------------------+ +| :: | :: | +| | | +| let open Lwt_result_syntax in | return x | +| return x | | ++--------------------------------------+-------------------------------+ +| :: | No equivalent, uses | +| | ``Lwt.return_ok x`` | +| let open Lwt_result_syntax in | | +| fail e | | ++--------------------------------------+-------------------------------+ +| :: | :: | +| | | +| let open Tzresult_syntax in | ok x | +| return x | | ++--------------------------------------+-------------------------------+ +| :: | :: | +| | | +| let open Tzresult_syntax in | error e | +| fail e | | ++--------------------------------------+-------------------------------+ +| :: | :: | +| | | +| let open Lwt_tzresult_syntax in | return x | +| return x | | ++--------------------------------------+-------------------------------+ +| :: | :: | +| | | +| let open Lwt_tzresult_syntax in | fail e | +| fail e | | ++--------------------------------------+-------------------------------+ + +In addition to these syntactic differences, there are also usage +differences. You might encounter the following patterns which you should +not repeat: + +- Matching against a trace: + + :: + + match f () with + | Ok .. -> .. + | Error (Timeout :: _) -> .. + | Error trace -> .. + + This is discouraged because the compiler is unable to warn you if the + matching is affected by a change in the code. E.g., if you add + context to an error in one place in the code, you may change the + result of the matching somewhere else in the code. + + +In depth discussion: what even is a monad? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This tutorial has been pretty loose with the word monad. It has focused +on usage with very little explanations of fundamental concepts. It is +focused on the surface syntax instead of the underlying mathematical +model. This section goes into a bit more details about the general +principles of monads and such. It does not claim to even attempt to +give a complete description of monads, it simply gives more details than +the previous sections. + +For coding purposes, a monad is a parametric type equipped with a set of +specific operators. + +:: + + type 'a t + val bind : 'a t -> ('a -> 'b t) -> 'b t + val return : 'a -> 'a t + +The ``return`` operator injects a value into the monad and the ``bind`` +operator continues within the monad. + +The set of operators must also follow the monad laws. For example +``bind (return x) f`` must be equivalent to ``f x``. + +Monads are used as a generic way to encode different abstractions within +a programming language: I/O, errors, collections, etc. For example, the +``option`` monad is defined as + +:: + + module OptionMonad = struct + type 'a t = 'a option + let bind x f = match x with | None -> None | Some x -> f x + let return x = Some x + end + +And it is useful when dealing with queries that may have no answer. This +can be used as a lighter form of error management than the ``result`` +monad. + +Some programming languages also offer syntactic sugar for monads. This +is to avoid having to write ``bind`` within ``bind`` within ``bind``. +E.g., Haskell relies heavily on monads and has the dedicated +``do``-notation. In OCaml, you can use one of the following methods: + +- `binding operators `__ + (since OCaml 4.08.0) + + :: + + let add x y = + let ( let* ) = OptionMonad.bind in + let* x = int_of_string_opt x in + let* y = int_of_string_opt y in + Some (string_of_int (x + y)) + +- `infix + operators `__ + + :: + + let add x y = + let ( >>= ) = OptionMonad.bind in + int_of_string_opt x >>= fun x -> + int_of_string_opt y >>= fun y -> + Some (string_of_int (x + y)) + + Note that mixing multiple infix operators is not always easy because + of precedence and associativity. + +- partial application and infix ``@@`` + + :: + + let add x y = + OptionMonad.bind (int_of_string_opt x) @@ fun x -> + OptionMonad.bind (int_of_string_opt y) @@ fun y -> + Some (string_of_int (x + y)) + + This is useful for the occasional application: you do not need to + declare a dedicated operator nor open a dedicated syntax module. + +Monads can have additional operators beside the required core. E.g., you +can add ``OptionMonad.join : 'a option option -> 'a option``. + +In depth discussion: ``Error_monad``, ``src/lib_error_monad/``, ``Tezos_base__TzPervasives``, etc. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The different parts of the error monad (syntax modules, extended stdlib, +tracing primitives, etc.) are defined in separate files. Yet, they are +all available to you directly. This section explains where each part is +defined and how it reaches the scope of your code. + +**From your code, working back to the definitions.** + +In most of Octez, the ``Error_monad`` module is available. Specifically, it is +available in all the packages that depend on ``tezos-base``. This covers +everything except the protocols and a handful of low-level libraries. + +In those part of Octez, the build files include +``-open Tezos_base__TzPervasives``. + +The module ``Tezos_base__TzPervasives`` is defined by the compilation +unit ``src/lib_base/TzPervasives.ml``. + +This compilation unit gathers multiple low-level modules together. Of +interest to us is ``include Tezos_error_monad.Error_monad`` (left +untouched in the ``mli``) and ``include Tezos_error_monad.TzLwtreslib`` +(not present in the ``mli``, used to shadow the Stdlib modules ``List``, +``Option``, ``Result``, etc.). + +The ``Error_monad`` module exports: + +- the ``error`` type along with the ``register_error_kind`` function, +- the ``'a tzresult`` type, +- the ``TzTrace`` module, +- the ``Tzresult_syntax`` and ``Lwt_tzresult_syntax`` modules + (from a different, more generic name), +- and exports a few more functions. + +The rest of the ``tezos-error-monad`` package: + +- defines the ``'a trace`` type (in ``TzTrace.ml``), and +- instantiates ``TzLwtreslib`` by applying ``Lwtreslib``\ ’s ``Traced`` + functor to ``TzTrace``. + +The ``Lwtreslib`` module exports a ``Traced (T: TRACE)`` functor. This +functor takes a definition of traces and returns a group of modules +intended to shadow the Stdlib. + +**From the underlying definitions, working all the way up to your +code.** + +At the low-level is Lwtreslib. + +- ``src/lib_lwt_result_stdlib/bare/sigs``: defines interfaces for + basic, non-traced syntax modules and Stdlib-replacement modules. +- ``src/lib_lwt_result_stdlib/bare/structs``: defines implementations + basic, non-traced syntax modules and Stdlib-replacement modules. +- ``src/lib_lwt_result_stdlib/traced/sigs``: defines interfaces for + traced syntax modules and Stdlib-replacement modules. These + interfaces are built on top of the non-traced interfaces, mostly by + addition and occasionally by shadowing. +- ``src/lib_lwt_result_stdlib/traced/structs``: defines implementations + for traced syntax modules and Stdlib-replacement modules. These + implementations are built on top of the non-traced implementations, + mostly by addition and occasionally by shadowing. These are defined + as functors over some abstract tracing primitives. +- ``src/lib_lwt_result_stdlib/lwtreslib.mli``: puts together the traced + implementations into a single functor ``Traced`` that takes a trace + definition and returns fully instantiated modules to shadow the + Stdlib. + +Above Lwtreslib is the Error monad. + +- ``src/lib_error_monad/TzTrace.ml``: defines the ``'a trace`` type + along with the low-level trace-construction primitives. +- ``src/lib_error_monad/TzLwtreslib.ml``: instantiates + ``Lwtreslib.Traced`` with ``TzTrace``. +- ``src/lib_error_monad/monad_extension_maker.ml``: provides a functor + which, given a tracing module, provides some higher level functions + for tracing as well as a few other functions. +- ``src/lib_error_monad/core_maker.ml``: provides a functor which, + given a name, provides an ``error`` type, a ``register_error_kind`` + function, and a few other related functions. This is a functor so we + can instantiate it separately for the shell and for each of the + protocols. +- ``src/lib_error_monad/TzCore.ml``: instantiates the ``core_maker`` + functor for the shell. +- ``src/lib_error_monad/error_monad.ml``: puts together all of the + above into a single module. + +Above the Error monad is lib-base: + +- ``src/lib_base/TzPervasives.ml``: exports the ``Error_monad`` module, + includes the ``Error_monad`` module, exports each of the + ``TzLwtreslib`` module. + +In depth discussion: ``result`` as data and ``result`` as control-flow +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Note that ``result`` (and similarly, ``tzresult``) is a data type. +Specifically + +:: + + type ('a, 'b) result = + | Ok of 'a + | Error of 'b + +You can treat values of type ``result`` as data of that data-type. In +this case, you construct and match the values, you pass them around, +etc. + +Note however that, in Octez, we also use the ``result`` type as a +control-flow mechanism. Specifically, in conjunction with the ``let*`` +binding operator, the ``result`` type has a continue/abort meaning. + +Within your code, you can go from one use to the other. E.g., + +:: + + let xs = + List.rev_map + (fun x -> + (* [result] as control-flow *) + let open Result_syntax in + let* .. = .. in + let* .. = .. in + return ..) + ys + in + let successes xs = + (* [result] as data *) + List.length (List.rev_filter_ok xs) + in + .. + +Using ``result`` as sometimes data and sometimes control-flow is the +main reason to bend the guidelines about which syntax module to +open. E.g., if your function returns ``(_, _) result Lwt.t`` but the +``result`` is data returned by the function rather than control-flow +used within the function, then you should open ``Lwt_syntax`` (rather +then ``Lwt_result_syntax``). + +As a significant aside, note that in OCaml you can also use exceptions +for control-flow (with ``raise`` and ``try``-``with`` and +``match``-``with``-``exception``) and as data (the type ``exn`` is an +extensible variant data-type). + +:: + + (** [iter_no_raise f xs] applies [f] to all the elements of [xs]. If [f] raises + an exception, the iteration continues and [f] is still applies to other + elements. The function returns pairs of the exceptions raised by [f] along + the elements of [xs] that triggered these exceptions. *) + let iter_no_raise f xs = + List.fold_left + (fun excs x -> + match f x with + | exception exc -> exc :: excs + | () -> excs) + [] + xs + +You can find uses of exception as data within the error monad itself. +First, the generic failure functions (``error_with``, +``error_with_exn``, ``failwith``, and ``fail_with_exn``) are just +wrapper around an ``error`` which carries an exception (as data). + +Second, Lwtreslib provides helpers to catch exceptions. E.g., +``Result.catch : (unit -> 'a) -> ('a, exn) result`` calls a function and +wraps any raised exception inside an ``Error`` constructor. + +In depth discussion: pros and cons of ``result`` compared to other error management techniques +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In Octez, we use ``result`` and the specialised ``tzresult``. For this +reason, this tutorial is focused on ``result``/``tzresult``. However, +there are other techniques for handling errors. This section compares +them briefly. + +In general you should use ``result`` and ``tzresult`` but in some +specific cases you can deviate from that. The comparisons below may help +you decide. + +**Exceptions** + +In exception-based error handling, you raise an exception (via +``raise``) when an error occurs and you catch it (via ``try``-``with``) +to recover. Exceptions are fast because the OCaml compiler and runtime +provide the necessary mechanisms directly. + +Whether a function can raise an exception or not cannot be determined by +its type. This means that it is easy to forget to recover from an +exception. An external library may change the set of exceptions that a +function raises and you need to update calls to this function, but the +type-checker cannot warn you about it. This places a heavy burden on the +developer who is responsible for checking the documentation of all the +functions they call. + +Exception-raising functions should be documented as such using the +``@raise`` documentation keyword. + +| Pros: performance is good, used widely in the larger ecosystem. +| Cons: you cannot rely on the type-checker to help you at all, you + depend on the quality of the documentation of your external and + internal dependencies. + +Note that within the protocol, you should not use exceptions at all. + +**tzresult** + +With ``tzresult``, errors are carried by the ``Error`` constructor of a +``result``. In this way an ``'a tzresult`` represents the result of a +computation that normally returns an ``'a`` but may fail. + +Because the type of errors is an abstract wrapper (``trace``) around an +extensible variant (``error``), you can only recover from these errors +in a generic way. + +| Pros: the type of a function indicates if it can fail or not, you + cannot forget to check for success/failure. +| Cons: you cannot check which error was raised, registration is heavy + and complicated. + +**result** + +With ``result``, errors are carried by the ``Error`` constructor. Each +function defines its own type of errors. + +| Pros: the type of a function indicates if and how it can fail, you + cannot forget to check for success/failure, you can check the payload + of failures. +| Cons: different errors from different functions cannot be used + together (need conversions), ``and*`` is unusable. + +**option** + +With ``option``, errors are represented by the ``None`` constructor. +Errors are completely void of payload. + +Because there are no payloads attached to an error, you should generally +treat the error directly at the call site. Otherwise you might lose +track of the origin of the failure. E.g., what was not found in the +following code fragment? + +:: + + match + let ( let* ) = Option.bind in + let* z = find "zero" in + let* o = find "one" in + Some (z, o) + with + | None -> .. + | Some (z, o) -> .. + +| Pros: the type of a function indicates if it can fail, you cannot + forget to check for success/failure. +| Cons: a single kind of errors means it cannot be very informative. + +**fallback** + +Another approach to errors is to have a default or fallback value. In +that case, the function returns a default sensible value when it would +raise and exception or return an error. Alternatively, it can take this +fallback value as parameter. + +:: + + (** @raise Not_found if argument is [None] *) + val get : 'a option -> 'a + + (** returns [default] if argument is [None] *) + val value : default:'a -> 'a option -> 'a + +| Pros: there is no error. +| Cons: doesn’t work for every function, works differently on different + functions. From 670fdd602f55ce292115c66ef5203a0b5a897bc5 Mon Sep 17 00:00:00 2001 From: Hans Hoglund Date: Mon, 14 Mar 2022 11:06:32 +0000 Subject: [PATCH 028/100] Proto: SCORU: Add test for double free --- .../test/unit/test_sc_rollup_storage.ml | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/src/proto_alpha/lib_protocol/test/unit/test_sc_rollup_storage.ml b/src/proto_alpha/lib_protocol/test/unit/test_sc_rollup_storage.ml index 02319d06bd..429157f666 100644 --- a/src/proto_alpha/lib_protocol/test/unit/test_sc_rollup_storage.ml +++ b/src/proto_alpha/lib_protocol/test/unit/test_sc_rollup_storage.ml @@ -55,6 +55,16 @@ let new_sc_rollup ctxt = in (rollup, ctxt) +(** Originate a rollup with one staker and make a deposit to the initial LCC *) +let originate_rollup_and_deposit_with_one_staker () = + let* ctxt = new_context () in + let* (rollup, ctxt) = lift @@ new_sc_rollup ctxt in + let staker = + Sc_rollup_repr.Staker.of_b58check_exn "tz1SdKt9kjPp1HRQFkBmXtBhgMfvdgFhSjmG" + in + let+ ctxt = lift @@ Sc_rollup_storage.deposit_stake ctxt rollup staker in + (ctxt, rollup, staker) + (** Originate a rollup with two stakers and make a deposit to the initial LCC *) let originate_rollup_and_deposit_with_two_stakers () = let* ctxt = new_context () in @@ -302,6 +312,67 @@ let test_cement () = let* ctxt = Sc_rollup_storage.cement_commitment ctxt rollup c1 in assert_true ctxt +(* Create and cement three commitments: + + [c3 -> c2 -> c1 -> Commitment_hash.zero] + + This is useful to catch potential issues with de-allocation of [c2], + as we deallocate the old LCC when a new LCC is cemented. + *) +let test_cement_three_commitments () = + let* (ctxt, rollup, staker) = + originate_rollup_and_deposit_with_one_staker () + in + let challenge_window = + Constants_storage.sc_rollup_challenge_window_in_blocks ctxt + in + lift + @@ + let commitment = + Sc_rollup_repr.Commitment. + { + predecessor = Sc_rollup_repr.Commitment_hash.zero; + inbox_level = Raw_level_repr.of_int32_exn 21l; + number_of_messages = number_of_messages_exn 3l; + number_of_ticks = number_of_ticks_exn 1232909l; + compressed_state = Sc_rollup_repr.State_hash.zero; + } + in + let* (c1, ctxt) = + Sc_rollup_storage.refine_stake ctxt rollup staker commitment + in + let commitment = + Sc_rollup_repr.Commitment. + { + predecessor = c1; + inbox_level = Raw_level_repr.of_int32_exn 41l; + number_of_messages = number_of_messages_exn 3l; + number_of_ticks = number_of_ticks_exn 1232909l; + compressed_state = Sc_rollup_repr.State_hash.zero; + } + in + let* (c2, ctxt) = + Sc_rollup_storage.refine_stake ctxt rollup staker commitment + in + let commitment = + Sc_rollup_repr.Commitment. + { + predecessor = c2; + inbox_level = Raw_level_repr.of_int32_exn 61l; + number_of_messages = number_of_messages_exn 3l; + number_of_ticks = number_of_ticks_exn 1232909l; + compressed_state = Sc_rollup_repr.State_hash.zero; + } + in + let* (c3, ctxt) = + Sc_rollup_storage.refine_stake ctxt rollup staker commitment + in + let ctxt = Raw_context.Internal_for_tests.add_level ctxt challenge_window in + let* ctxt = Sc_rollup_storage.cement_commitment ctxt rollup c1 in + let* ctxt = Sc_rollup_storage.cement_commitment ctxt rollup c2 in + let* ctxt = Sc_rollup_storage.cement_commitment ctxt rollup c3 in + assert_true ctxt + let test_cement_then_remove () = let* ctxt = new_context () in let challenge_window = @@ -1364,6 +1435,10 @@ let tests = `Quick test_initial_state_is_pre_boot; Tztest.tztest "cement" `Quick test_cement; + Tztest.tztest + "cement three commitments" + `Quick + test_cement_three_commitments; Tztest.tztest "cannot unstake staker at LCC" `Quick test_cement_then_remove; Tztest.tztest "cement consumes available messages" From 6fbec911ff177b34ff7fad91a72240157b30b75e Mon Sep 17 00:00:00 2001 From: Hans Hoglund Date: Mon, 14 Mar 2022 11:06:48 +0000 Subject: [PATCH 029/100] Proto: SCORU: Fix double free --- .../lib_protocol/sc_rollup_storage.ml | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/proto_alpha/lib_protocol/sc_rollup_storage.ml b/src/proto_alpha/lib_protocol/sc_rollup_storage.ml index 047625eb9c..5fe839433a 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_storage.ml +++ b/src/proto_alpha/lib_protocol/sc_rollup_storage.ml @@ -583,18 +583,12 @@ let cement_commitment ctxt rollup new_lcc = can safely deallocate the old LCC. *) let* ctxt = deallocate ctxt rollup old_lcc in - let* ctxt = - consume_n_messages - ctxt - rollup - (Int32.to_int - @@ Sc_rollup_repr.Number_of_messages.to_int32 - new_lcc_commitment.number_of_messages) - in - let* (ctxt, _size) = - Store.Commitments.remove_existing (ctxt, rollup) new_lcc - in - return ctxt + consume_n_messages + ctxt + rollup + (Int32.to_int + @@ Sc_rollup_repr.Number_of_messages.to_int32 + new_lcc_commitment.number_of_messages) type conflict_point = Commitment_hash.t * Commitment_hash.t From 9941941b2aedd64647fce5e4928ecdbee74425a8 Mon Sep 17 00:00:00 2001 From: vbot Date: Wed, 16 Mar 2022 11:55:12 +0100 Subject: [PATCH 030/100] Docs: update incorrect consensus documentation --- docs/alpha/consensus.rst | 8 +++----- docs/ithaca/consensus.rst | 8 +++----- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/docs/alpha/consensus.rst b/docs/alpha/consensus.rst index e67ae29907..2e445a475e 100644 --- a/docs/alpha/consensus.rst +++ b/docs/alpha/consensus.rst @@ -145,16 +145,14 @@ Validator selection: staking balance, active stake, and frozen deposits Validator selection is based on the stake, as in Emmy*, with the exception that it is based on the delegate's *active stake* instead of its *staking -balance* (or rather the corresponding rolls. -**NB**: rolls do not play a -role anymore, except for establishing a minimum required staking -balance). Let us first (re)define these and related concepts. +balance*. Let us first (re)define these and related concepts. - The *(maximal) staking balance* of a delegate is its full balance (i.e. all the tokens owned by the delegate) plus the balances of all accounts that have delegated to it. + It must be at least ``TOKENS_PER_ROLL`` tez, otherwise the delegate cannot be selected as a validator. - The *active stake* of a delegate is the amount of tez with which it participates in consensus. It is at most its - staking balance. It must be at least ``TOKEN_PER_ROLL`` tez. We explain below how it is computed. + staking balance. We explain below how it is computed. - The *frozen deposit* represents a percentage ``FROZEN_DEPOSIT_PERCENTAGE`` of the maximum active stake during the last ``PRESERVED_CYCLES + MAX_SLASHING_PERIOD``. This amount represents the delegate's skin in the game: in the case that the diff --git a/docs/ithaca/consensus.rst b/docs/ithaca/consensus.rst index 20625d33b8..4827155f3d 100644 --- a/docs/ithaca/consensus.rst +++ b/docs/ithaca/consensus.rst @@ -148,16 +148,14 @@ Validator selection: staking balance, active stake, and frozen deposits Validator selection is based on the stake, as in Emmy*, with the exception that it is based on the delegate's *active stake* instead of its *staking -balance* (or rather the corresponding rolls. -**NB**: rolls do not play a -role anymore, except for establishing a minimum required staking -balance). Let us first (re)define these and related concepts. +balance*. Let us first (re)define these and related concepts. - The *(maximal) staking balance* of a delegate is its full balance (i.e. all the tokens owned by the delegate) plus the balances of all accounts that have delegated to it. + It must be at least ``TOKENS_PER_ROLL`` tez, otherwise the delegate cannot be selected as a validator. - The *active stake* of a delegate is the amount of tez with which it participates in consensus. It is at most its - staking balance. It must be at least ``TOKEN_PER_ROLL`` tez. We explain below how it is computed. + staking balance. We explain below how it is computed. - The *frozen deposit* represents a percentage ``FROZEN_DEPOSIT_PERCENTAGE`` of the maximum active stake during the last ``PRESERVED_CYCLES + MAX_SLASHING_PERIOD``. This amount represents the delegate's skin in the game: in the case that the From 774830d8b11eab2374f803780c588fe6218575a2 Mon Sep 17 00:00:00 2001 From: ngoguey42 Date: Tue, 15 Mar 2022 14:07:47 +0100 Subject: [PATCH 031/100] protocol-env: Expose missing context config type equality --- src/lib_protocol_environment/environment_V5.ml | 1 + src/lib_protocol_environment/environment_V5.mli | 1 + 2 files changed, 2 insertions(+) diff --git a/src/lib_protocol_environment/environment_V5.ml b/src/lib_protocol_environment/environment_V5.ml index 3799a0340b..900aa7c69e 100644 --- a/src/lib_protocol_environment/environment_V5.ml +++ b/src/lib_protocol_environment/environment_V5.ml @@ -53,6 +53,7 @@ module type V5 = sig and type Context.cache_value = Environment_context.Context.cache_value and type Context_hash.t = Context_hash.t and type Context_hash.Version.t = Context_hash.Version.t + and type Context.config = Tezos_context_sigs.Config.t and module Context.Proof = Environment_context.Context.Proof and type Protocol_hash.t = Protocol_hash.t and type Time.t = Time.Protocol.t diff --git a/src/lib_protocol_environment/environment_V5.mli b/src/lib_protocol_environment/environment_V5.mli index c47db9b27f..a744f565a2 100644 --- a/src/lib_protocol_environment/environment_V5.mli +++ b/src/lib_protocol_environment/environment_V5.mli @@ -54,6 +54,7 @@ module type V5 = sig and type Context.cache_value = Environment_context.Context.cache_value and type Context_hash.t = Context_hash.t and type Context_hash.Version.t = Context_hash.Version.t + and type Context.config = Tezos_context_sigs.Config.t and module Context.Proof = Environment_context.Context.Proof and type Protocol_hash.t = Protocol_hash.t and type Time.t = Time.Protocol.t From f4caa1304565b901902bf7e0840d413c3e6e3b12 Mon Sep 17 00:00:00 2001 From: icristescu Date: Wed, 1 Dec 2021 16:08:45 +0100 Subject: [PATCH 032/100] lib_context: use the minimal indexing strategy --- src/lib_context/context.ml | 2 ++ src/proto_alpha/bin_tx_rollup_node/context.mli | 1 + 2 files changed, 3 insertions(+) diff --git a/src/lib_context/context.ml b/src/lib_context/context.ml index 9d59f4df85..c4bbd0dcb6 100644 --- a/src/lib_context/context.ml +++ b/src/lib_context/context.ml @@ -603,10 +603,12 @@ module Make (Encoding : module type of Tezos_context_encoding.Context) = struct let init ?patch_context ?(readonly = false) root = let open Lwt_syntax in + let indexing_strategy = Irmin_pack.Pack_store.Indexing_strategy.minimal in let+ repo = Store.Repo.v (Irmin_pack.config ~readonly + ~indexing_strategy ~index_log_size:!index_log_size ~lru_size:!lru_size root) diff --git a/src/proto_alpha/bin_tx_rollup_node/context.mli b/src/proto_alpha/bin_tx_rollup_node/context.mli index d9bb192c3a..5ea9234995 100644 --- a/src/proto_alpha/bin_tx_rollup_node/context.mli +++ b/src/proto_alpha/bin_tx_rollup_node/context.mli @@ -40,6 +40,7 @@ val index : context -> index val init : ?patch_context:(context -> context tzresult Lwt.t) -> ?readonly:bool -> + ?indexing_strategy:[`Always | `Minimal] -> string -> index Lwt.t From 18c30d408d874b1d017dfb506ef21dbc037d4b41 Mon Sep 17 00:00:00 2001 From: Craig Ferguson Date: Mon, 14 Mar 2022 15:34:59 +0000 Subject: [PATCH 033/100] lib_store: always index during snapshot import --- src/lib_context/context.ml | 8 +++- src/lib_context/context.mli | 10 ++++- src/lib_context/test/test_context.ml | 57 +++++++++++++++++----------- src/lib_store/snapshots.ml | 6 ++- 4 files changed, 55 insertions(+), 26 deletions(-) diff --git a/src/lib_context/context.ml b/src/lib_context/context.ml index c4bbd0dcb6..362f0d4ef8 100644 --- a/src/lib_context/context.ml +++ b/src/lib_context/context.ml @@ -601,9 +601,13 @@ module Make (Encoding : module type of Tezos_context_encoding.Context) = struct (*-- Initialisation ----------------------------------------------------------*) - let init ?patch_context ?(readonly = false) root = + let init ?patch_context ?(readonly = false) ?(indexing_strategy = `Minimal) + root = let open Lwt_syntax in - let indexing_strategy = Irmin_pack.Pack_store.Indexing_strategy.minimal in + let indexing_strategy = + let module I = Irmin_pack.Pack_store.Indexing_strategy in + match indexing_strategy with `Minimal -> I.minimal | `Always -> I.always + in let+ repo = Store.Repo.v (Irmin_pack.config diff --git a/src/lib_context/context.mli b/src/lib_context/context.mli index 21235e7abe..a08ef33707 100644 --- a/src/lib_context/context.mli +++ b/src/lib_context/context.mli @@ -50,10 +50,18 @@ module Make (Encoding : module type of Tezos_context_encoding.Context) : sig val index : context -> index - (** Open or initialize a versioned store at a given path. *) + (** Open or initialize a versioned store at a given path. + + @param indexing_strategy determines whether newly-exported objects by + this store handle should also be added to the store's index. [`Minimal] + (the default) only adds objects to the index when they are {i commits}, + whereas [`Always] indexes every object type. The indexing strategy used + for existing stores can be changed without issue (as only {i + newly}-exported objects are impacted). *) val init : ?patch_context:(context -> context tzresult Lwt.t) -> ?readonly:bool -> + ?indexing_strategy:[`Always | `Minimal] -> string -> index Lwt.t diff --git a/src/lib_context/test/test_context.ml b/src/lib_context/test/test_context.ml index f4c581a008..5dcbe9bb08 100644 --- a/src/lib_context/test/test_context.ml +++ b/src/lib_context/test/test_context.ml @@ -101,10 +101,16 @@ type t = { block3b : Context_hash.t; } -let wrap_context_init f _ () = +type init_config = {indexing_strategy : [`Always | `Minimal]} + +let wrap_context_init config f _ () = Lwt_utils_unix.with_tempdir "tezos_test_" (fun base_dir -> let root = base_dir // "context" in - let* idx = Context.init root in + let* idx = + match config with + | None -> Context.init root + | Some {indexing_strategy} -> Context.init ~indexing_strategy root + in let*!! genesis = Context.commit_genesis idx @@ -515,7 +521,9 @@ let test_dump {idx; block3b; _} = (fun () -> Lwt_unix.close context_fd) in let root = base_dir2 // "context" in - let*! idx2 = Context.init ?patch_context:None root in + let*! idx2 = + Context.init ~indexing_strategy:`Always ?patch_context:None root + in let*! context_fd = Lwt_unix.openfile dumpfile Lwt_unix.[O_RDONLY] 0o444 in @@ -672,28 +680,33 @@ let test_proof_exn ctxt = (******************************************************************************) -let tests : (string * (t -> unit Lwt.t)) list = +let tests : (string * (t -> unit Lwt.t) * init_config option) list = + let test ?config name f = (name, f, config) in [ - ("is_empty", test_is_empty); - ("simple", test_simple); - ("list", test_list); - ("continuation", test_continuation); - ("fork", test_fork); - ("replay", test_replay); - ("fold_keys_sorted", test_fold_keys_sorted); - ("fold_keys_undefined", test_fold_keys_undefined); - ("fold", test_fold); - ("trees", test_trees); - ("raw", test_raw); - ("dump", test_dump); - ("encoding", test_encoding); - ("get_hash_version", test_get_version_hash); - ("set_hash_version_tzresult", test_set_version_hash_tzresult); - ("to_memory_tree", test_to_memory_tree); - ("proof exn", test_proof_exn); + test "is_empty" test_is_empty; + test "simple" test_simple; + test "list" test_list; + test "continuation" test_continuation; + test "fork" test_fork; + test "replay" test_replay; + test "fold_keys_sorted" test_fold_keys_sorted; + test "fold_keys_undefined" test_fold_keys_undefined; + test "fold" test_fold; + test "trees" test_trees; + test "raw" test_raw; + (* NOTE: importing the context from a snapshot requires using an [`Always] + indexing strategy. See the docs for [Context.restore_context] for more + details. *) + test ~config:{indexing_strategy = `Always} "dump" test_dump; + test "encoding" test_encoding; + test "get_hash_version" test_get_version_hash; + test "set_hash_version_tzresult" test_set_version_hash_tzresult; + test "to_memory_tree" test_to_memory_tree; + test "proof exn" test_proof_exn; ] let tests = List.map - (fun (s, f) -> Alcotest_lwt.test_case s `Quick (wrap_context_init f)) + (fun (s, f, config) -> + Alcotest_lwt.test_case s `Quick (wrap_context_init config f)) tests diff --git a/src/lib_store/snapshots.ml b/src/lib_store/snapshots.ml index e2d1a8708d..813560b688 100644 --- a/src/lib_store/snapshots.ml +++ b/src/lib_store/snapshots.ml @@ -3544,7 +3544,11 @@ module Make_snapshot_importer (Importer : IMPORTER) : Snapshot_importer = struct user_expected_block in let*! context_index = - Context.init ~readonly:false ?patch_context dst_context_dir + Context.init + ~readonly:false + ~indexing_strategy:`Always + ?patch_context + dst_context_dir in (* Restore context *) let* (block_data, genesis_context_hash, block_validation_result) = From 40a488e637c6e79b268ab85e2e152473a314ef36 Mon Sep 17 00:00:00 2001 From: Craig Ferguson Date: Mon, 14 Mar 2022 16:28:05 +0000 Subject: [PATCH 034/100] lib_context: add an environment variable for the indexing strategy --- src/lib_context/context.ml | 59 +++++++++++++++++++++++++++++++++---- src/lib_context/context.mli | 6 ++++ 2 files changed, 59 insertions(+), 6 deletions(-) diff --git a/src/lib_context/context.ml b/src/lib_context/context.ml index 362f0d4ef8..98d9045ee6 100644 --- a/src/lib_context/context.ml +++ b/src/lib_context/context.ml @@ -125,6 +125,45 @@ let lru_size = ref 5_000 will have to be garbage collected later on to save space. *) let auto_flush = ref 10_000 +module Indexing_strategy : sig + (* Determines the policy used to determine whether to add new + objects to Irmin's index whenever they are exported to the + data file. *) + type t := + [ `Minimal (** only newly-exported commit objects are added to the index *) + | `Always (** all newly-exported objects are added to the index *) ] + + val parse : string -> (t, string) result + + val set : t -> unit + + val get : unit -> t + + type irmin_t := Irmin_pack.Pack_store.Indexing_strategy.t + + val to_irmin : t -> irmin_t +end = struct + module I = Irmin_pack.Pack_store.Indexing_strategy + + let singleton = ref `Minimal + + let set x = singleton := x + + let get () = !singleton + + let parse = function + | "always" -> Ok `Always + | "minimal" -> Ok `Minimal + | x -> + Error + (Fmt.str + "Unable to parse indexing strategy '%s'. Expected one of { \ + 'always', 'minimal' }." + x) + + let to_irmin = function `Always -> I.always | `Minimal -> I.minimal +end + let () = let verbose_info () = Logs.set_level (Some Logs.Info) ; @@ -137,6 +176,14 @@ let () = let index_log_size n = index_log_size := int_of_string n in let auto_flush n = auto_flush := int_of_string n in let lru_size n = lru_size := int_of_string n in + let indexing_strategy x = + match Indexing_strategy.parse x with + | Ok x -> Indexing_strategy.set x + | Error msg -> + Fmt.failwith + "Invalid value for TEZOS_CONTEXT environment variable: %s" + msg + in match Unix.getenv "TEZOS_CONTEXT" with | exception Not_found -> () | v -> @@ -150,6 +197,7 @@ let () = | ["index-log-size"; n] -> index_log_size n | ["auto-flush"; n] -> auto_flush n | ["lru-size"; n] -> lru_size n + | ["indexing-strategy"; x] -> indexing_strategy x | _ -> ())) args @@ -601,14 +649,13 @@ module Make (Encoding : module type of Tezos_context_encoding.Context) = struct (*-- Initialisation ----------------------------------------------------------*) - let init ?patch_context ?(readonly = false) ?(indexing_strategy = `Minimal) - root = + let init ?patch_context ?(readonly = false) ?indexing_strategy root = let open Lwt_syntax in - let indexing_strategy = - let module I = Irmin_pack.Pack_store.Indexing_strategy in - match indexing_strategy with `Minimal -> I.minimal | `Always -> I.always - in let+ repo = + let indexing_strategy = + Option.value indexing_strategy ~default:(Indexing_strategy.get ()) + |> Indexing_strategy.to_irmin + in Store.Repo.v (Irmin_pack.config ~readonly diff --git a/src/lib_context/context.mli b/src/lib_context/context.mli index a08ef33707..1e6862baca 100644 --- a/src/lib_context/context.mli +++ b/src/lib_context/context.mli @@ -172,6 +172,12 @@ module Make (Encoding : module type of Tezos_context_encoding.Context) : sig val dump_context : index -> Context_hash.t -> fd:Lwt_unix.file_descr -> int tzresult Lwt.t + (** Rebuild a context from a given snapshot. + + NOTE: the indexing strategy used by the [index] must be [`Always] (in + order to recover direct internal pointers between store objects during + the import). This limitation is likely to be removed in a future version + of [lib_context]. *) val restore_context : index -> expected_context_hash:Context_hash.t -> From b10e1b081ee7c74b72750e29bf913868cc476b6e Mon Sep 17 00:00:00 2001 From: Pierrick Couderc Date: Wed, 9 Mar 2022 10:15:58 +0100 Subject: [PATCH 035/100] Scoru/Client: introduce an instance of Client_context This will allow a better interfacing with keys related commands, and a better code sharing with tezos-client's lib. --- .../bin_sc_rollup_client/configuration.ml | 26 +++++++++++++++++++ .../bin_sc_rollup_client/configuration.mli | 21 +++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/src/proto_alpha/bin_sc_rollup_client/configuration.ml b/src/proto_alpha/bin_sc_rollup_client/configuration.ml index d4447e7eb0..e5cd10551c 100644 --- a/src/proto_alpha/bin_sc_rollup_client/configuration.ml +++ b/src/proto_alpha/bin_sc_rollup_client/configuration.ml @@ -25,6 +25,7 @@ open Clic open Lwt_result_syntax +module Base = Tezos_client_base type t = {base_dir : string; endpoint : Uri.t} @@ -85,3 +86,28 @@ let parse argv = Clic.parse_global_options (global_options ()) default argv in return (make opts, argv) + +class type sc_client_context = + object + inherit Base.Client_context.io_wallet + + inherit RPC_context.generic + end + +class unix_sc_client_context ~base_dir ~password_filename ~rpc_config : + sc_client_context = + object + inherit Client_context_unix.unix_io_wallet ~base_dir ~password_filename + + inherit + Tezos_rpc_http_client_unix.RPC_client_unix.http_ctxt + rpc_config + (Tezos_rpc_http.Media_type.Command_line.of_command_line + rpc_config.media_type) + end + +let make_unix_client_context {base_dir; endpoint} = + let rpc_config = + {Tezos_rpc_http_client_unix.RPC_client_unix.default_config with endpoint} + in + new unix_sc_client_context ~base_dir ~rpc_config ~password_filename:None diff --git a/src/proto_alpha/bin_sc_rollup_client/configuration.mli b/src/proto_alpha/bin_sc_rollup_client/configuration.mli index 683a7e9fb7..9aebfc3ba4 100644 --- a/src/proto_alpha/bin_sc_rollup_client/configuration.mli +++ b/src/proto_alpha/bin_sc_rollup_client/configuration.mli @@ -41,3 +41,24 @@ val parse : string list -> (t * string list) tzresult Lwt.t (** [global_options ()] returns the list of options that have an influence on the configuration. *) val global_options : unit -> (string option * Uri.t option, 'a) Clic.options + +(** Instance of [Tezos_client_base.Client_context] that only handles IOs and + RPCs. Can be used for keys and RPCs related commands. *) +class type sc_client_context = + object + inherit Tezos_client_base.Client_context.io_wallet + + inherit RPC_context.generic + end + +(** Instance of [sc_client_context] for linux systems. Relies on + [Tezos_rpc_http_client_unix]. *) +class unix_sc_client_context : + base_dir:string + -> password_filename:string option + -> rpc_config:Tezos_rpc_http_client_unix.RPC_client_unix.config + -> sc_client_context + +(** [make_unix_client_context config] generates a unix_sc_client_context from + the client configuration. *) +val make_unix_client_context : t -> unix_sc_client_context From 710f9ed02743302947bc8e4de6f3340754b316f8 Mon Sep 17 00:00:00 2001 From: Pierrick Couderc Date: Wed, 9 Mar 2022 10:17:33 +0100 Subject: [PATCH 036/100] Score/Client: use sc_client_context instead of the configuration --- src/proto_alpha/bin_sc_rollup_client/RPC.ml | 9 +++------ src/proto_alpha/bin_sc_rollup_client/commands.ml | 7 +++---- src/proto_alpha/bin_sc_rollup_client/commands.mli | 2 +- .../bin_sc_rollup_client/main_sc_rollup_client_alpha.ml | 3 ++- 4 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/proto_alpha/bin_sc_rollup_client/RPC.ml b/src/proto_alpha/bin_sc_rollup_client/RPC.ml index a30f120bfb..b61d72d2f0 100644 --- a/src/proto_alpha/bin_sc_rollup_client/RPC.ml +++ b/src/proto_alpha/bin_sc_rollup_client/RPC.ml @@ -25,10 +25,7 @@ open Configuration -let call configuration = - RPC_client_unix.call_service - [Tezos_rpc_http.Media_type.bson] - ~base:configuration.endpoint +let call (cctxt : #sc_client_context) = cctxt#call_service -let get_sc_rollup_addresses_command configuration = - call configuration (Sc_rollup_services.sc_rollup_address ()) () () () +let get_sc_rollup_addresses_command cctxt = + call cctxt (Sc_rollup_services.sc_rollup_address ()) () () () diff --git a/src/proto_alpha/bin_sc_rollup_client/commands.ml b/src/proto_alpha/bin_sc_rollup_client/commands.ml index 506c6a4392..a1b63e5bad 100644 --- a/src/proto_alpha/bin_sc_rollup_client/commands.ml +++ b/src/proto_alpha/bin_sc_rollup_client/commands.ml @@ -32,9 +32,8 @@ let get_sc_rollup_addresses_command () = "Retrieve the smart-contract rollup address the node is interacting with." no_options (fixed ["get"; "sc"; "rollup"; "address"]) - (fun () configuration -> - RPC.get_sc_rollup_addresses_command configuration >>=? fun addr -> - Format.printf "@[%a@]" Sc_rollup.Address.pp addr ; - return ()) + (fun () (cctxt : #Configuration.sc_client_context) -> + RPC.get_sc_rollup_addresses_command cctxt >>=? fun addr -> + cctxt#message "@[%a@]" Sc_rollup.Address.pp addr >>= fun () -> return_unit) let all () = [get_sc_rollup_addresses_command ()] diff --git a/src/proto_alpha/bin_sc_rollup_client/commands.mli b/src/proto_alpha/bin_sc_rollup_client/commands.mli index 1a9ff88b0f..32de9f752b 100644 --- a/src/proto_alpha/bin_sc_rollup_client/commands.mli +++ b/src/proto_alpha/bin_sc_rollup_client/commands.mli @@ -26,4 +26,4 @@ (** [all ()] is the list of commands recognized by the smart-contract rollup client. These commands may depend on the client configuration. *) -val all : unit -> Configuration.t Clic.command list +val all : unit -> Configuration.sc_client_context Clic.command list diff --git a/src/proto_alpha/bin_sc_rollup_client/main_sc_rollup_client_alpha.ml b/src/proto_alpha/bin_sc_rollup_client/main_sc_rollup_client_alpha.ml index ed5f31d8b9..d2f7da08c9 100644 --- a/src/proto_alpha/bin_sc_rollup_client/main_sc_rollup_client_alpha.ml +++ b/src/proto_alpha/bin_sc_rollup_client/main_sc_rollup_client_alpha.ml @@ -29,7 +29,8 @@ let argv () = Array.to_list Sys.argv |> List.tl |> Stdlib.Option.get let main () = Configuration.parse (argv ()) >>=? fun (configuration, argv) -> - Clic.dispatch (Commands.all ()) configuration argv + let cctxt = Configuration.make_unix_client_context configuration in + Clic.dispatch (Commands.all ()) cctxt argv let handle_error = function | Ok () -> Stdlib.exit 0 From c1299da071102ef12d715de4ee34d1bc5619fdbb Mon Sep 17 00:00:00 2001 From: Arvid Jakobsson Date: Wed, 16 Mar 2022 17:04:46 +0100 Subject: [PATCH 037/100] Tx_rollup: fix spelling of error Submit_batch_burn_exceeded --- src/proto_alpha/lib_protocol/alpha_context.mli | 2 +- .../test/integration/operations/test_tx_rollup.ml | 2 +- .../lib_protocol/tx_rollup_errors_repr.ml | 13 +++++++------ .../lib_protocol/tx_rollup_state_repr.ml | 2 +- .../lib_protocol/tx_rollup_state_repr.mli | 2 +- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index 7c13a83a6f..6c5bcbc8a8 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -1927,7 +1927,7 @@ module Tx_rollup_errors : sig type error += | Tx_rollup_already_exists of Tx_rollup.t | Tx_rollup_does_not_exist of Tx_rollup.t - | Submit_batch_burn_excedeed of {burn : Tez.t; limit : Tez.t} + | Submit_batch_burn_exceeded of {burn : Tez.t; limit : Tez.t} | Inbox_does_not_exist of Tx_rollup.t * Tx_rollup_level.t | Inbox_size_would_exceed_limit of Tx_rollup.t | Inbox_count_would_exceed_limit of Tx_rollup.t diff --git a/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml b/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml index 73ad78a4be..6c85083e12 100644 --- a/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml +++ b/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml @@ -503,7 +503,7 @@ let test_add_batch_with_limit () = op ~expect_failure: (check_proto_error_f (function - | Tx_rollup_errors.Submit_batch_burn_excedeed _ -> true + | Tx_rollup_errors.Submit_batch_burn_exceeded _ -> true | _ -> false)) >>=? fun _ -> return_unit diff --git a/src/proto_alpha/lib_protocol/tx_rollup_errors_repr.ml b/src/proto_alpha/lib_protocol/tx_rollup_errors_repr.ml index 1a157f8338..7ebf1530eb 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_errors_repr.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_errors_repr.ml @@ -28,7 +28,7 @@ type error += | Tx_rollup_already_exists of Tx_rollup_repr.t | Tx_rollup_does_not_exist of Tx_rollup_repr.t - | Submit_batch_burn_excedeed of {burn : Tez_repr.t; limit : Tez_repr.t} + | Submit_batch_burn_exceeded of {burn : Tez_repr.t; limit : Tez_repr.t} | Inbox_does_not_exist of Tx_rollup_repr.t * Tx_rollup_level_repr.t | Inbox_size_would_exceed_limit of Tx_rollup_repr.t | Inbox_count_would_exceed_limit of Tx_rollup_repr.t @@ -77,14 +77,15 @@ type error += computed : Tx_rollup_commitment_repr.Message_result_hash.t; expected : Tx_rollup_commitment_repr.Message_result_hash.t; } + | Ticket_content_size_limit_exceeded of {content_size : int; limit : int} let () = let open Data_encoding in - (* Tx_rollup_submit_batch_burn_excedeed *) + (* Tx_rollup_submit_batch_burn_exceeded *) register_error_kind `Temporary - ~id:"operation.tx_rollup_submit_batch_burn_excedeed" - ~title:"Submit batch excedeed burn limit" + ~id:"operation.tx_rollup_submit_batch_burn_exceeded" + ~title:"Submit batch exceeded burn limit" ~description: "The submit batch would exceed the burn limit, we withdraw the submit." ~pp:(fun ppf (burn, limit) -> @@ -99,9 +100,9 @@ let () = Data_encoding.( obj2 (req "burn" Tez_repr.encoding) (req "limit" Tez_repr.encoding)) (function - | Submit_batch_burn_excedeed {burn; limit} -> Some (burn, limit) + | Submit_batch_burn_exceeded {burn; limit} -> Some (burn, limit) | _ -> None) - (fun (burn, limit) -> Submit_batch_burn_excedeed {burn; limit}) ; + (fun (burn, limit) -> Submit_batch_burn_exceeded {burn; limit}) ; (* Tx_rollup_inbox_does_not_exist *) register_error_kind `Temporary diff --git a/src/proto_alpha/lib_protocol/tx_rollup_state_repr.ml b/src/proto_alpha/lib_protocol/tx_rollup_state_repr.ml index 35b1bf1b2d..063404eac6 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_state_repr.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_state_repr.ml @@ -491,7 +491,7 @@ let burn_cost ~limit state size = Tez_repr.(state.burn_per_byte *? Int64.of_int size) >>? fun burn -> match limit with | Some limit when Tez_repr.(limit >= burn) -> - error (Submit_batch_burn_excedeed {burn; limit}) + error (Submit_batch_burn_exceeded {burn; limit}) | _ -> ok burn let finalized_commitments_range state = diff --git a/src/proto_alpha/lib_protocol/tx_rollup_state_repr.mli b/src/proto_alpha/lib_protocol/tx_rollup_state_repr.mli index 6d23170141..784e58bf35 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_state_repr.mli +++ b/src/proto_alpha/lib_protocol/tx_rollup_state_repr.mli @@ -66,7 +66,7 @@ val update_burn_per_byte : (** [burn_cost ~limit state size] computes the burn to be paid to submit [size] bytes in the inbox of the transactional rollup. - Returns [Tx_rollup_submit_batch_burn_excedeed] if the (computed) burn + Returns [Tx_rollup_submit_batch_burn_exceeded] if the (computed) burn exceeds [limit]. *) val burn_cost : limit:Tez_repr.t option -> t -> int -> Tez_repr.t tzresult From cd1c8eaf5836013e11be8edc91c1bba69f84f84f Mon Sep 17 00:00:00 2001 From: Thomas Letan Date: Mon, 14 Mar 2022 13:53:36 +0100 Subject: [PATCH 038/100] Proto,tx_rollup: Freeze and unfreeze stakable bond --- src/proto_alpha/lib_protocol/apply.ml | 40 +++++++++---------- .../integration/operations/test_tx_rollup.ml | 34 ++++++++++------ ..._rollup_finalize_too_recent_commitment.out | 15 +++---- .../_regressions/tx_rollup_rpc_commitment.out | 15 +++---- ..._rollup_rpc_pending_bonded_commitments.out | 15 +++---- 5 files changed, 63 insertions(+), 56 deletions(-) diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index 0d578b6229..b97c1b68c6 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -1603,19 +1603,14 @@ let apply_external_manager_operation_content : Tx_rollup_state.get ctxt tx_rollup >>=? fun (ctxt, state) -> ( Tx_rollup_commitment.has_bond ctxt tx_rollup key >>=? fun (ctxt, pending) -> - let _ = pending in - (* TODO/TORU: https://gitlab.com/tezos/tezos/-/merge_requests/4437 - let bond_id = Bond_id.Tx_rollup_bond_id tx_rollup in - match pending with - | 0 -> - Token.transfer - ctxt - (`Contract source) - (`Frozen_bonds (source, bond_id)) - (Constants.tx_rollup_commitment_bond ctxt) - | _ -> return (ctxt, []) ) - *) - return (ctxt, []) ) + if not pending then + let bond_id = Bond_id.Tx_rollup_bond_id tx_rollup in + Token.transfer + ctxt + (`Contract source) + (`Frozen_bonds (source, bond_id)) + (Constants.tx_rollup_commitment_bond ctxt) + else return (ctxt, []) ) >>=? fun (ctxt, balance_updates) -> Tx_rollup_commitment.add_commitment ctxt @@ -1638,19 +1633,20 @@ let apply_external_manager_operation_content : | None -> fail Tx_rollup_operation_with_non_implicit_contract | Some key -> Tx_rollup_commitment.remove_bond ctxt tx_rollup key >>=? fun ctxt -> - (* TODO/TORU: This depends on https://gitlab.com/tezos/tezos/-/merge_requests/4437 - let bond_id = Rollup_bond_id.Tx_rollup_bond_id tx_rollup in - Token.transfer - ctxt - (`Frozen_rollup_bonds (source, bond_id)) - (`Contract source) - (Constants.tx_rollup_commitment_bond ctxt)) - *) + let bond_id = Bond_id.Tx_rollup_bond_id tx_rollup in + Token.balance ctxt (`Frozen_bonds (source, bond_id)) + >>=? fun (ctxt, bond) -> + Token.transfer + ctxt + (`Frozen_bonds (source, bond_id)) + (`Contract source) + bond + >>=? fun (ctxt, balance_updates) -> let result = Tx_rollup_return_bond_result { consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt; - balance_updates = []; + balance_updates; } in return (ctxt, result, [])) diff --git a/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml b/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml index 6c85083e12..e7c674fbf4 100644 --- a/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml +++ b/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml @@ -954,7 +954,7 @@ let test_commitment_duplication () = context_init2 () >>=? fun (b, contract1, contract2) -> let pkh1 = is_implicit_exn contract1 in originate b contract1 >>=? fun (b, tx_rollup) -> - Context.Contract.balance (B b) contract1 >>=? fun _balance -> + Context.Contract.balance (B b) contract1 >>=? fun balance -> Context.Contract.balance (B b) contract2 >>=? fun balance2 -> (* In order to have a permissible commitment, we need a transaction. *) let contents = "batch" in @@ -989,10 +989,9 @@ let test_commitment_duplication () = let submitted_level = (Level.current (Incremental.alpha_ctxt i)).level in Op.tx_rollup_commit (I i) contract1 tx_rollup commitment >>=? fun op -> Incremental.add_operation i op >>=? fun i -> - (* TODO/TORU: https://gitlab.com/tezos/tezos/-/merge_requests/4437 *) - (* let cost = Tez.of_mutez_exn 10_000_000_000L in *) - (* Assert.balance_was_debited ~loc:__LOC__ (I i) contract1 balance cost *) - (* >>=? fun () -> *) + let cost = Constants.tx_rollup_commitment_bond (Incremental.alpha_ctxt i) in + Assert.balance_was_debited ~loc:__LOC__ (I i) contract1 balance cost + >>=? fun () -> (* Successfully fail to submit a duplicate commitment *) Op.tx_rollup_commit (I i) contract2 tx_rollup commitment >>=? fun op -> (Incremental.add_operation i op >>= function @@ -1161,10 +1160,12 @@ let test_bond_finalization () = context_init1 () >>=? fun (b, contract1) -> let pkh1 = is_implicit_exn contract1 in originate b contract1 >>=? fun (b, tx_rollup) -> + Context.Contract.balance (B b) contract1 >>=? fun balance -> (* Transactions in block 2, 3, 4 *) make_transactions_in tx_rollup contract1 [2; 3; 4] b >>=? fun b -> (* Let’s try to remove the bond *) Incremental.begin_construction b >>=? fun i -> + let bond = Constants.tx_rollup_commitment_bond (Incremental.alpha_ctxt i) in Op.tx_rollup_return_bond (I i) contract1 tx_rollup >>=? fun op -> Incremental.add_operation i @@ -1188,20 +1189,27 @@ let test_bond_finalization () = | _ -> false) >>=? fun i -> Incremental.finalize_block i >>=? fun b -> + Assert.balance_was_debited ~loc:__LOC__ (B b) contract1 balance bond + >>=? fun () -> (* Finalize the commitment of level 0. *) - Op.tx_rollup_finalize (B b) contract1 tx_rollup >>=? fun operation -> - Block.bake b ~operation >>=? fun b -> + Incremental.begin_construction b >>=? fun i -> + Op.tx_rollup_finalize (I i) contract1 tx_rollup >>=? fun operation -> + Incremental.add_operation i operation >>=? fun i -> + Incremental.finalize_block i >>=? fun b -> (* Bake enough block, and remove the commitment of level 0. *) Block.bake b ~operations:[] >>=? fun b -> - Op.tx_rollup_remove_commitment (B b) contract1 tx_rollup >>=? fun operation -> - Block.bake b ~operation >>=? fun b -> + Incremental.begin_construction b >>=? fun i -> + Op.tx_rollup_remove_commitment (I i) contract1 tx_rollup >>=? fun operation -> + Incremental.add_operation i operation >>=? fun i -> + Incremental.finalize_block i >>=? fun b -> (* Try to return the bond *) + Context.Contract.balance (B b) contract1 >>=? fun balance -> Incremental.begin_construction b >>=? fun i -> Op.tx_rollup_return_bond (I i) contract1 tx_rollup >>=? fun op -> - Incremental.add_operation i op >>=? fun _ -> - (* TODO/TORU: https://gitlab.com/tezos/tezos/-/merge_requests/4437 - Once stakable bonds are merged, check the balances. *) - return () + Incremental.add_operation i op >>=? fun i -> + Incremental.finalize_block i >>=? fun b -> + (* Check the balance*) + Assert.balance_was_credited ~loc:__LOC__ (B b) contract1 balance bond (** [test_too_many_commitments] tests that you can't submit new commitments if there are too many finalized commitments. *) diff --git a/tezt/_regressions/tx_rollup_finalize_too_recent_commitment.out b/tezt/_regressions/tx_rollup_finalize_too_recent_commitment.out index daf32f6944..9674716175 100644 --- a/tezt/_regressions/tx_rollup_finalize_too_recent_commitment.out +++ b/tezt/_regressions/tx_rollup_finalize_too_recent_commitment.out @@ -34,7 +34,7 @@ This sequence of operations was run: ./tezos-client --wait none submit tx rollup commitment 0 '[TX_ROLLUP_INBOX_HASH]' '[TX_ROLLUP_MESSAGE_RESULT_HASH]' to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' Node is bootstrapped. -Estimated gas: 3280.956 units (will add 100 for safety) +Estimated gas: 3690.976 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -45,19 +45,20 @@ and/or an external block explorer to make sure that it has been included. This sequence of operations was run: Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.000656 + Fee to the baker: ꜩ0.000697 Expected counter: 3 - Gas limit: 3381 + Gas limit: 3791 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.000656 - payload fees(the block proposer) ....... +ꜩ0.000656 + [PUBLIC_KEY_HASH] ... -ꜩ0.000697 + payload fees(the block proposer) ....... +ꜩ0.000697 Tx rollup commitment:[TX_ROLLUP_HASH], commitment 0 : messages = [TX_ROLLUP_MESSAGE_RESULT_HASH] predecessor for inbox [TX_ROLLUP_INBOX_HASH] From: [PUBLIC_KEY_HASH] This tx rollup commit operation was successfully applied Balance updates: - - Consumed gas: 3280.956 + [PUBLIC_KEY_HASH] ....................................................... -ꜩ10000 + Frozen_bonds([PUBLIC_KEY_HASH],[TX_ROLLUP_HASH]) ... +ꜩ10000 + Consumed gas: 3690.976 ./tezos-client --wait none submit tx rollup finalize commitment to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' diff --git a/tezt/_regressions/tx_rollup_rpc_commitment.out b/tezt/_regressions/tx_rollup_rpc_commitment.out index 540c9a2b12..8e0775b3b7 100644 --- a/tezt/_regressions/tx_rollup_rpc_commitment.out +++ b/tezt/_regressions/tx_rollup_rpc_commitment.out @@ -29,7 +29,7 @@ This sequence of operations was run: ./tezos-client --wait none submit tx rollup commitment 0 '[TX_ROLLUP_INBOX_HASH]' '[TX_ROLLUP_MESSAGE_RESULT_HASH]' to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' Node is bootstrapped. -Estimated gas: 3280.956 units (will add 100 for safety) +Estimated gas: 3690.976 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -40,19 +40,20 @@ and/or an external block explorer to make sure that it has been included. This sequence of operations was run: Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.000656 + Fee to the baker: ꜩ0.000697 Expected counter: 3 - Gas limit: 3381 + Gas limit: 3791 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.000656 - payload fees(the block proposer) ....... +ꜩ0.000656 + [PUBLIC_KEY_HASH] ... -ꜩ0.000697 + payload fees(the block proposer) ....... +ꜩ0.000697 Tx rollup commitment:[TX_ROLLUP_HASH], commitment 0 : messages = [TX_ROLLUP_MESSAGE_RESULT_HASH] predecessor for inbox [TX_ROLLUP_INBOX_HASH] From: [PUBLIC_KEY_HASH] This tx rollup commit operation was successfully applied Balance updates: - - Consumed gas: 3280.956 + [PUBLIC_KEY_HASH] ....................................................... -ꜩ10000 + Frozen_bonds([PUBLIC_KEY_HASH],[TX_ROLLUP_HASH]) ... +ꜩ10000 + Consumed gas: 3690.976 ./tezos-client rpc get '/chains/main/blocks/head/context/tx_rollup/[TX_ROLLUP_HASH]/commitment/0' diff --git a/tezt/_regressions/tx_rollup_rpc_pending_bonded_commitments.out b/tezt/_regressions/tx_rollup_rpc_pending_bonded_commitments.out index add1ab0d3e..63fb69deb5 100644 --- a/tezt/_regressions/tx_rollup_rpc_pending_bonded_commitments.out +++ b/tezt/_regressions/tx_rollup_rpc_pending_bonded_commitments.out @@ -29,7 +29,7 @@ This sequence of operations was run: ./tezos-client --wait none submit tx rollup commitment 0 '[TX_ROLLUP_INBOX_HASH]' '[TX_ROLLUP_MESSAGE_RESULT_HASH]' to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' Node is bootstrapped. -Estimated gas: 3280.956 units (will add 100 for safety) +Estimated gas: 3690.976 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -40,19 +40,20 @@ and/or an external block explorer to make sure that it has been included. This sequence of operations was run: Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.000656 + Fee to the baker: ꜩ0.000697 Expected counter: 3 - Gas limit: 3381 + Gas limit: 3791 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.000656 - payload fees(the block proposer) ....... +ꜩ0.000656 + [PUBLIC_KEY_HASH] ... -ꜩ0.000697 + payload fees(the block proposer) ....... +ꜩ0.000697 Tx rollup commitment:[TX_ROLLUP_HASH], commitment 0 : messages = [TX_ROLLUP_MESSAGE_RESULT_HASH] predecessor for inbox [TX_ROLLUP_INBOX_HASH] From: [PUBLIC_KEY_HASH] This tx rollup commit operation was successfully applied Balance updates: - - Consumed gas: 3280.956 + [PUBLIC_KEY_HASH] ....................................................... -ꜩ10000 + Frozen_bonds([PUBLIC_KEY_HASH],[TX_ROLLUP_HASH]) ... +ꜩ10000 + Consumed gas: 3690.976 ./tezos-client rpc get '/chains/main/blocks/head/context/tx_rollup/[TX_ROLLUP_HASH]/pending_bonded_commitments/[PUBLIC_KEY_HASH]' From 1ed7b9c7fca4312f8c70a82c0bf4a138b7a0d89d Mon Sep 17 00:00:00 2001 From: Thomas Letan Date: Mon, 14 Mar 2022 15:44:58 +0100 Subject: [PATCH 039/100] Proto,tx_rollup: Slash bond of the committer and reward the accuser --- .../lib_client/operation_result.ml | 3 ++ .../lib_protocol/alpha_context.mli | 12 ++++++- src/proto_alpha/lib_protocol/apply.ml | 31 +++++++++++++++++-- src/proto_alpha/lib_protocol/receipt_repr.ml | 23 +++++++++++++- src/proto_alpha/lib_protocol/receipt_repr.mli | 2 ++ .../lib_protocol/test/unit/test_receipt.ml | 3 ++ src/proto_alpha/lib_protocol/token.ml | 6 +++- src/proto_alpha/lib_protocol/token.mli | 4 ++- .../tx_rollup_commitment_storage.ml | 25 ++++++++++----- .../tx_rollup_commitment_storage.mli | 26 ++++++++++------ 10 files changed, 113 insertions(+), 22 deletions(-) diff --git a/src/proto_alpha/lib_client/operation_result.ml b/src/proto_alpha/lib_client/operation_result.ml index 01cdd4384c..da1f96a610 100644 --- a/src/proto_alpha/lib_client/operation_result.ml +++ b/src/proto_alpha/lib_client/operation_result.ml @@ -355,6 +355,9 @@ let pp_balance_updates ppf = function contract Bond_id.pp bond_id + | Tx_rollup_rejection_rewards -> "tx rollup rejection rewards" + | Tx_rollup_rejection_punishments -> + "tx rollup rejection punishments" in let balance = match origin with diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index 6c5bcbc8a8..72dd3d8e63 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -1870,7 +1870,7 @@ module Tx_rollup_commitment : sig val get_before_and_after_results : context -> Tx_rollup.t -> - Tx_rollup_level.t -> + Submitted_commitment.t -> message_position:int -> Tx_rollup_state.t -> (context @@ -1915,6 +1915,12 @@ module Tx_rollup_commitment : sig Signature.public_key_hash -> context tzresult Lwt.t + val slash_bond : + context -> + Tx_rollup.t -> + Signature.public_key_hash -> + (context * bool) tzresult Lwt.t + val reject_commitment : context -> Tx_rollup.t -> @@ -2145,6 +2151,8 @@ module Receipt : sig | Initial_commitments | Minted | Frozen_bonds of Contract.t * Bond_id.t + | Tx_rollup_rejection_punishments + | Tx_rollup_rejection_rewards val compare_balance : balance -> balance -> int @@ -3276,6 +3284,7 @@ module Token : sig | `Baking_bonuses | `Minted | `Liquidity_baking_subsidies + | `Tx_rollup_rejection_rewards | container ] type sink = @@ -3283,6 +3292,7 @@ module Token : sig | `Double_signing_punishments | `Lost_endorsing_rewards of Signature.Public_key_hash.t * bool * bool | `Burned + | `Tx_rollup_rejection_punishments | container ] val allocated : context -> container -> (context * bool) tzresult Lwt.t diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index b97c1b68c6..aa21522186 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -1691,10 +1691,12 @@ let apply_external_manager_operation_content : (* Check [level] *) Tx_rollup_state.check_level_can_be_rejected state level >>?= fun () -> (* Check [previous_message_result] *) + Tx_rollup_commitment.get ctxt tx_rollup level + >>=? fun (ctxt, commitment) -> Tx_rollup_commitment.get_before_and_after_results ctxt tx_rollup - level + commitment state ~message_position >>=? fun (ctxt, agreed_hash, rejected) -> @@ -1729,12 +1731,37 @@ let apply_external_manager_operation_content : (* Proof is correct, removing *) Tx_rollup_commitment.reject_commitment ctxt tx_rollup state level >>=? fun (ctxt, state) -> + (* Bond slashing, and removing *) + Tx_rollup_commitment.slash_bond ctxt tx_rollup commitment.committer + >>=? fun (ctxt, slashed) -> + (if slashed then + let source = Contract.implicit_contract commitment.committer in + let bid = Bond_id.Tx_rollup_bond_id tx_rollup in + Token.balance ctxt (`Frozen_bonds (source, bid)) >>=? fun (ctxt, burn) -> + Tez.(burn /? 2L) >>?= fun reward -> + let accuser = Contract.implicit_contract payer in + Token.transfer + ctxt + (`Frozen_bonds (source, bid)) + `Tx_rollup_rejection_punishments + burn + >>=? fun (ctxt, burn_update) -> + Token.transfer + ctxt + `Tx_rollup_rejection_rewards + (`Contract accuser) + reward + >>=? fun (ctxt, reward_update) -> + return (ctxt, burn_update @ reward_update) + else return (ctxt, [])) + >>=? fun (ctxt, balance_updates) -> + (* Update state and conclude *) Tx_rollup_state.update ctxt tx_rollup state >>=? fun ctxt -> let result = Tx_rollup_rejection_result { consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt; - balance_updates = []; + balance_updates; } in return (ctxt, result, []) diff --git a/src/proto_alpha/lib_protocol/receipt_repr.ml b/src/proto_alpha/lib_protocol/receipt_repr.ml index 1d9b029bda..392bd5a99e 100644 --- a/src/proto_alpha/lib_protocol/receipt_repr.ml +++ b/src/proto_alpha/lib_protocol/receipt_repr.ml @@ -44,6 +44,8 @@ type balance = | Initial_commitments | Minted | Frozen_bonds of Contract_repr.t * Bond_id_repr.t + | Tx_rollup_rejection_punishments + | Tx_rollup_rejection_rewards let balance_encoding = let open Data_encoding in @@ -207,11 +209,28 @@ let balance_encoding = ~title:"Frozen_bonds" (obj4 (req "kind" (constant "freezer")) - (req "category" (constant "tx_rollup_bonds")) + (req "category" (constant "bonds")) (req "contract" Contract_repr.encoding) (req "bond_id" Bond_id_repr.encoding)) (function Frozen_bonds (c, r) -> Some ((), (), c, r) | _ -> None) (fun ((), (), c, r) -> Frozen_bonds (c, r)); + case + (Tag 22) + ~title:"Tx_rollup_rejection_rewards" + (obj2 + (req "kind" (constant "minted")) + (req "category" (constant "tx_rollup_rejection_rewards"))) + (function Tx_rollup_rejection_rewards -> Some ((), ()) | _ -> None) + (fun ((), ()) -> Tx_rollup_rejection_rewards); + case + (Tag 23) + ~title:"Tx_rollup_rejection_punishments" + (obj2 + (req "kind" (constant "burned")) + (req "category" (constant "tx_rollup_rejection_punishments"))) + (function + | Tx_rollup_rejection_punishments -> Some ((), ()) | _ -> None) + (fun ((), ()) -> Tx_rollup_rejection_punishments); ] let is_not_zero c = not (Compare.Int.equal c 0) @@ -255,6 +274,8 @@ let compare_balance ba bb = | Initial_commitments -> 16 | Minted -> 17 | Frozen_bonds _ -> 18 + | Tx_rollup_rejection_punishments -> 19 + | Tx_rollup_rejection_rewards -> 20 (* don't forget to add parameterized cases in the first part of the function *) in Compare.Int.compare (index ba) (index bb) diff --git a/src/proto_alpha/lib_protocol/receipt_repr.mli b/src/proto_alpha/lib_protocol/receipt_repr.mli index 5a2bfc29a7..b3aaa1adc8 100644 --- a/src/proto_alpha/lib_protocol/receipt_repr.mli +++ b/src/proto_alpha/lib_protocol/receipt_repr.mli @@ -45,6 +45,8 @@ type balance = | Initial_commitments | Minted | Frozen_bonds of Contract_repr.t * Bond_id_repr.t + | Tx_rollup_rejection_punishments + | Tx_rollup_rejection_rewards (** Compares two balances. *) val compare_balance : balance -> balance -> int diff --git a/src/proto_alpha/lib_protocol/test/unit/test_receipt.ml b/src/proto_alpha/lib_protocol/test/unit/test_receipt.ml index f6f3f564ec..f0282d307d 100644 --- a/src/proto_alpha/lib_protocol/test/unit/test_receipt.ml +++ b/src/proto_alpha/lib_protocol/test/unit/test_receipt.ml @@ -94,5 +94,8 @@ let test_encodings () = let tx_rollup = Tx_rollup.Internal_for_tests.originated_tx_rollup nonce in let bond_id = Bond_id.Tx_rollup_bond_id tx_rollup in test_encodings (Frozen_bonds (Contract.implicit_contract pkh, bond_id)) + >>=? fun () -> + test_encodings Tx_rollup_rejection_punishments >>=? fun () -> + test_encodings Tx_rollup_rejection_rewards let tests = Tztest.[tztest "receipt - encoding" `Quick test_encodings] diff --git a/src/proto_alpha/lib_protocol/token.ml b/src/proto_alpha/lib_protocol/token.ml index cd20fe9d4f..67f1083a00 100644 --- a/src/proto_alpha/lib_protocol/token.ml +++ b/src/proto_alpha/lib_protocol/token.ml @@ -41,7 +41,8 @@ type infinite_source = | `Baking_rewards | `Baking_bonuses | `Minted - | `Liquidity_baking_subsidies ] + | `Liquidity_baking_subsidies + | `Tx_rollup_rejection_rewards ] type source = [infinite_source | container] @@ -49,6 +50,7 @@ type infinite_sink = [ `Storage_fees | `Double_signing_punishments | `Lost_endorsing_rewards of Signature.Public_key_hash.t * bool * bool + | `Tx_rollup_rejection_punishments | `Burned ] type sink = [infinite_sink | container] @@ -109,6 +111,7 @@ let credit ctxt dest amount origin = | `Storage_fees -> Storage_fees | `Double_signing_punishments -> Double_signing_punishments | `Lost_endorsing_rewards (d, p, r) -> Lost_endorsing_rewards (d, p, r) + | `Tx_rollup_rejection_punishments -> Tx_rollup_rejection_punishments | `Burned -> Burned in return (ctxt, sink) @@ -168,6 +171,7 @@ let spend ctxt src amount origin = | `Endorsing_rewards -> Endorsing_rewards | `Baking_rewards -> Baking_rewards | `Baking_bonuses -> Baking_bonuses + | `Tx_rollup_rejection_rewards -> Tx_rollup_rejection_rewards in return (ctxt, src) | #container as container -> ( diff --git a/src/proto_alpha/lib_protocol/token.mli b/src/proto_alpha/lib_protocol/token.mli index b810191f8f..2fe5f2cb84 100644 --- a/src/proto_alpha/lib_protocol/token.mli +++ b/src/proto_alpha/lib_protocol/token.mli @@ -62,7 +62,8 @@ type infinite_source = | `Baking_rewards | `Baking_bonuses | `Minted - | `Liquidity_baking_subsidies ] + | `Liquidity_baking_subsidies + | `Tx_rollup_rejection_rewards ] (** [source] is the type of token providers. Token providers that are not containers are considered to have infinite capacity. *) @@ -72,6 +73,7 @@ type infinite_sink = [ `Storage_fees | `Double_signing_punishments | `Lost_endorsing_rewards of Signature.Public_key_hash.t * bool * bool + | `Tx_rollup_rejection_punishments | `Burned ] (** [sink] is the type of token receivers. Token receivers that are not diff --git a/src/proto_alpha/lib_protocol/tx_rollup_commitment_storage.ml b/src/proto_alpha/lib_protocol/tx_rollup_commitment_storage.ml index 3bfc386541..289870d423 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_commitment_storage.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_commitment_storage.ml @@ -57,6 +57,16 @@ let remove_bond : Storage.Tx_rollup.Commitment_bond.remove ctxt bond_key >|=? just_ctxt | Some _ -> fail (Bond_in_use contract) +let slash_bond ctxt tx_rollup contract = + let bond_key = (tx_rollup, contract) in + Storage.Tx_rollup.Commitment_bond.find ctxt bond_key + >>=? fun (ctxt, bond_counter) -> + match bond_counter with + | None -> return (ctxt, false) + | Some c -> + Storage.Tx_rollup.Commitment_bond.remove ctxt bond_key + >|=? fun (ctxt, _, _) -> (ctxt, Compare.Int.(0 < c)) + let find : Raw_context.t -> Tx_rollup_repr.t -> @@ -282,7 +292,8 @@ let remove_commitment ctxt rollup state = >>?= fun state -> return (ctxt, state, tail) | None -> fail No_commitment_to_remove -let get_nth_commitment level commitment message_position = +let get_nth_commitment commitment message_position = + let level = commitment.level in Option.value_e ~error: (Error_monad.trace_of_error @@ -294,11 +305,11 @@ let get_nth_commitment level commitment message_position = })) (List.nth_opt commitment.messages message_position) -let get_before_and_after_results ctxt tx_rollup level ~message_position state = - Storage.Tx_rollup.Commitment.get ctxt (level, tx_rollup) - >>=? fun (ctxt, submitted_commitment) -> +let get_before_and_after_results ctxt tx_rollup + (submitted_commitment : Submitted_commitment.t) ~message_position state = let commitment = submitted_commitment.commitment in - get_nth_commitment level commitment message_position >>?= fun after_hash -> + get_nth_commitment commitment message_position >>?= fun after_hash -> + let level = commitment.level in if Compare.Int.(message_position = 0) then match Tx_rollup_level_repr.pred level with | None -> @@ -347,8 +358,8 @@ let get_before_and_after_results ctxt tx_rollup level ~message_position state = Storage.Tx_rollup.Commitment.get ctxt (level, tx_rollup) >>=? fun (ctxt, submitted_commitment) -> let commitment = submitted_commitment.commitment in - get_nth_commitment level commitment (message_position - 1) - >>?= fun before_hash -> return (ctxt, before_hash, after_hash) + get_nth_commitment commitment (message_position - 1) >>?= fun before_hash -> + return (ctxt, before_hash, after_hash) let reject_commitment ctxt rollup state level = match diff --git a/src/proto_alpha/lib_protocol/tx_rollup_commitment_storage.mli b/src/proto_alpha/lib_protocol/tx_rollup_commitment_storage.mli index 7a0bdac40b..9f4eaf2c5f 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_commitment_storage.mli +++ b/src/proto_alpha/lib_protocol/tx_rollup_commitment_storage.mli @@ -57,15 +57,25 @@ val add_commitment : Tx_rollup_commitment_repr.t -> (Raw_context.t * Tx_rollup_state_repr.t) tzresult Lwt.t -(** [remove_bond context tx_rollup contract] removes the bond for an - implicit contract. This will fail if either the bond does not exist, - or the bond is currently in-use. *) +(** [remove_bond context tx_rollup contract] removes the bond counter + for an implicit contract. This will fail if either the bond does + not exist, or the bond is currently in-use ({i i.e.}, the counter + is strictly positive). *) val remove_bond : Raw_context.t -> Tx_rollup_repr.t -> Signature.public_key_hash -> Raw_context.t tzresult Lwt.t +(** [slash_bond ctxt tx_rollup contract] removes the bond counter for + an implicit contract if it exists. Besides, it returns a boolean + to determine if this counter was strictly superior to 0. *) +val slash_bond : + Raw_context.t -> + Tx_rollup_repr.t -> + Signature.public_key_hash -> + (Raw_context.t * bool) tzresult Lwt.t + (** [find context tx_rollup level] returns the commitment for a level, if any exists. If the rollup does not exist, the error [Tx_rollup_does_not_exist] is returned. *) @@ -155,15 +165,13 @@ val reject_commitment : Tx_rollup_level_repr.t -> (Raw_context.t * Tx_rollup_state_repr.t) tzresult Lwt.t -(** [get_before_and_after_results tx_rollup level ~message_position - state] returns the before and after roots for a given - [message_position], from the commitment on [tx_rollup] at [level]. - If there is no commitment at [level], [Storage_error.Missing_key] - is returned. *) +(** [get_before_and_after_results tx_rollup commitment + ~message_position state] returns the before and after roots for a + given [message_position], from [commitment] on [tx_rollup]. *) val get_before_and_after_results : Raw_context.t -> Tx_rollup_repr.t -> - Tx_rollup_level_repr.t -> + Tx_rollup_commitment_repr.Submitted_commitment.t -> message_position:int -> Tx_rollup_state_repr.t -> (Raw_context.t From c58fc7dc5960235242c89636b3f19ab19b419b15 Mon Sep 17 00:00:00 2001 From: Richard Davison Date: Mon, 14 Mar 2022 17:30:58 +0000 Subject: [PATCH 040/100] Manifest: bin_baker --- src/proto_011_PtHangz2/bin_baker/dune | 36 ++++++++++--------- src/proto_011_PtHangz2/bin_baker/dune-project | 1 - .../bin_baker/tezos-baker-011-PtHangz2.opam | 4 ++- src/proto_012_Psithaca/bin_baker/dune | 36 ++++++++++--------- src/proto_012_Psithaca/bin_baker/dune-project | 1 - .../bin_baker/tezos-baker-012-Psithaca.opam | 4 ++- src/proto_alpha/bin_baker/dune | 36 ++++++++++--------- src/proto_alpha/bin_baker/dune-project | 1 - .../bin_baker/tezos-baker-alpha.opam | 4 ++- 9 files changed, 69 insertions(+), 54 deletions(-) diff --git a/src/proto_011_PtHangz2/bin_baker/dune b/src/proto_011_PtHangz2/bin_baker/dune index cad6ae39df..4a8a5460e9 100644 --- a/src/proto_011_PtHangz2/bin_baker/dune +++ b/src/proto_011_PtHangz2/bin_baker/dune @@ -1,20 +1,24 @@ -; build static executable with --profile static -(env - (static - (flags (:standard - -ccopt -static)))) +(env (static (flags (:standard -ccopt -static)))) (executable (name main_baker_011_PtHangz2) - (instrumentation (backend bisect_ppx)) (public_name tezos-baker-011-PtHangz2) - (libraries tezos-client-base-unix - tezos-client-commands - tezos-baking-011-PtHangz2-commands) - (flags (:standard -open Tezos_base__TzPervasives - -open Tezos_protocol_011_PtHangz2 - -open Tezos_client_011_PtHangz2 - -open Tezos_client_commands - -open Tezos_baking_011_PtHangz2_commands - -open Tezos_stdlib_unix - -open Tezos_client_base_unix))) + (package tezos-baker-011-PtHangz2) + (instrumentation (backend bisect_ppx)) + (libraries + tezos-base + tezos-protocol-011-PtHangz2 + tezos-client-011-PtHangz2 + tezos-client-commands + tezos-baking-011-PtHangz2-commands + tezos-stdlib-unix + tezos-client-base-unix) + (flags + (:standard + -open Tezos_base.TzPervasives + -open Tezos_protocol_011_PtHangz2 + -open Tezos_client_011_PtHangz2 + -open Tezos_client_commands + -open Tezos_baking_011_PtHangz2_commands + -open Tezos_stdlib_unix + -open Tezos_client_base_unix))) diff --git a/src/proto_011_PtHangz2/bin_baker/dune-project b/src/proto_011_PtHangz2/bin_baker/dune-project index 5fab06455d..47aa0dd4c4 100644 --- a/src/proto_011_PtHangz2/bin_baker/dune-project +++ b/src/proto_011_PtHangz2/bin_baker/dune-project @@ -1,3 +1,2 @@ (lang dune 2.9) (formatting (enabled_for ocaml)) -(name tezos-baker-alpha) diff --git a/src/proto_011_PtHangz2/bin_baker/tezos-baker-011-PtHangz2.opam b/src/proto_011_PtHangz2/bin_baker/tezos-baker-011-PtHangz2.opam index 2b3198ce4c..757bf5ab70 100644 --- a/src/proto_011_PtHangz2/bin_baker/tezos-baker-011-PtHangz2.opam +++ b/src/proto_011_PtHangz2/bin_baker/tezos-baker-011-PtHangz2.opam @@ -1,6 +1,6 @@ opam-version: "2.0" maintainer: "contact@tezos.com" -authors: [ "Tezos devteam" ] +authors: ["Tezos devteam"] homepage: "https://www.tezos.com/" bug-reports: "https://gitlab.com/tezos/tezos/issues" dev-repo: "git+https://gitlab.com/tezos/tezos.git" @@ -8,9 +8,11 @@ license: "MIT" depends: [ "dune" { >= "2.9" } "tezos-base" + "tezos-protocol-011-PtHangz2" "tezos-client-011-PtHangz2" "tezos-client-commands" "tezos-baking-011-PtHangz2-commands" + "tezos-stdlib-unix" "tezos-client-base-unix" ] build: [ diff --git a/src/proto_012_Psithaca/bin_baker/dune b/src/proto_012_Psithaca/bin_baker/dune index dd7b9eadd9..b090de8714 100644 --- a/src/proto_012_Psithaca/bin_baker/dune +++ b/src/proto_012_Psithaca/bin_baker/dune @@ -1,20 +1,24 @@ -; build static executable with --profile static -(env - (static - (flags (:standard - -ccopt -static)))) +(env (static (flags (:standard -ccopt -static)))) (executable (name main_baker_012_Psithaca) - (instrumentation (backend bisect_ppx)) (public_name tezos-baker-012-Psithaca) - (libraries tezos-client-base-unix - tezos-client-commands - tezos-baking-012-Psithaca-commands) - (flags (:standard -open Tezos_base__TzPervasives - -open Tezos_protocol_012_Psithaca - -open Tezos_client_012_Psithaca - -open Tezos_client_commands - -open Tezos_baking_012_Psithaca_commands - -open Tezos_stdlib_unix - -open Tezos_client_base_unix))) + (package tezos-baker-012-Psithaca) + (instrumentation (backend bisect_ppx)) + (libraries + tezos-base + tezos-protocol-012-Psithaca + tezos-client-012-Psithaca + tezos-client-commands + tezos-baking-012-Psithaca-commands + tezos-stdlib-unix + tezos-client-base-unix) + (flags + (:standard + -open Tezos_base.TzPervasives + -open Tezos_protocol_012_Psithaca + -open Tezos_client_012_Psithaca + -open Tezos_client_commands + -open Tezos_baking_012_Psithaca_commands + -open Tezos_stdlib_unix + -open Tezos_client_base_unix))) diff --git a/src/proto_012_Psithaca/bin_baker/dune-project b/src/proto_012_Psithaca/bin_baker/dune-project index 5fab06455d..47aa0dd4c4 100644 --- a/src/proto_012_Psithaca/bin_baker/dune-project +++ b/src/proto_012_Psithaca/bin_baker/dune-project @@ -1,3 +1,2 @@ (lang dune 2.9) (formatting (enabled_for ocaml)) -(name tezos-baker-alpha) diff --git a/src/proto_012_Psithaca/bin_baker/tezos-baker-012-Psithaca.opam b/src/proto_012_Psithaca/bin_baker/tezos-baker-012-Psithaca.opam index 9613387a4a..9ef9243c95 100644 --- a/src/proto_012_Psithaca/bin_baker/tezos-baker-012-Psithaca.opam +++ b/src/proto_012_Psithaca/bin_baker/tezos-baker-012-Psithaca.opam @@ -1,6 +1,6 @@ opam-version: "2.0" maintainer: "contact@tezos.com" -authors: [ "Tezos devteam" ] +authors: ["Tezos devteam"] homepage: "https://www.tezos.com/" bug-reports: "https://gitlab.com/tezos/tezos/issues" dev-repo: "git+https://gitlab.com/tezos/tezos.git" @@ -8,9 +8,11 @@ license: "MIT" depends: [ "dune" { >= "2.9" } "tezos-base" + "tezos-protocol-012-Psithaca" "tezos-client-012-Psithaca" "tezos-client-commands" "tezos-baking-012-Psithaca-commands" + "tezos-stdlib-unix" "tezos-client-base-unix" ] build: [ diff --git a/src/proto_alpha/bin_baker/dune b/src/proto_alpha/bin_baker/dune index 51b3365bf8..b66dfcc02f 100644 --- a/src/proto_alpha/bin_baker/dune +++ b/src/proto_alpha/bin_baker/dune @@ -1,20 +1,24 @@ -; build static executable with --profile static -(env - (static - (flags (:standard - -ccopt -static)))) +(env (static (flags (:standard -ccopt -static)))) (executable (name main_baker_alpha) - (instrumentation (backend bisect_ppx)) (public_name tezos-baker-alpha) - (libraries tezos-client-base-unix - tezos-client-commands - tezos-baking-alpha-commands) - (flags (:standard -open Tezos_base__TzPervasives - -open Tezos_protocol_alpha - -open Tezos_client_alpha - -open Tezos_client_commands - -open Tezos_baking_alpha_commands - -open Tezos_stdlib_unix - -open Tezos_client_base_unix))) + (package tezos-baker-alpha) + (instrumentation (backend bisect_ppx)) + (libraries + tezos-base + tezos-protocol-alpha + tezos-client-alpha + tezos-client-commands + tezos-baking-alpha-commands + tezos-stdlib-unix + tezos-client-base-unix) + (flags + (:standard + -open Tezos_base.TzPervasives + -open Tezos_protocol_alpha + -open Tezos_client_alpha + -open Tezos_client_commands + -open Tezos_baking_alpha_commands + -open Tezos_stdlib_unix + -open Tezos_client_base_unix))) diff --git a/src/proto_alpha/bin_baker/dune-project b/src/proto_alpha/bin_baker/dune-project index 5fab06455d..47aa0dd4c4 100644 --- a/src/proto_alpha/bin_baker/dune-project +++ b/src/proto_alpha/bin_baker/dune-project @@ -1,3 +1,2 @@ (lang dune 2.9) (formatting (enabled_for ocaml)) -(name tezos-baker-alpha) diff --git a/src/proto_alpha/bin_baker/tezos-baker-alpha.opam b/src/proto_alpha/bin_baker/tezos-baker-alpha.opam index d0edad6ecd..4182def3ec 100644 --- a/src/proto_alpha/bin_baker/tezos-baker-alpha.opam +++ b/src/proto_alpha/bin_baker/tezos-baker-alpha.opam @@ -1,6 +1,6 @@ opam-version: "2.0" maintainer: "contact@tezos.com" -authors: [ "Tezos devteam" ] +authors: ["Tezos devteam"] homepage: "https://www.tezos.com/" bug-reports: "https://gitlab.com/tezos/tezos/issues" dev-repo: "git+https://gitlab.com/tezos/tezos.git" @@ -8,9 +8,11 @@ license: "MIT" depends: [ "dune" { >= "2.9" } "tezos-base" + "tezos-protocol-alpha" "tezos-client-alpha" "tezos-client-commands" "tezos-baking-alpha-commands" + "tezos-stdlib-unix" "tezos-client-base-unix" ] build: [ From 9f33b93889d6fe2190a167ba127b351c87505f45 Mon Sep 17 00:00:00 2001 From: Yann Regis-Gianas Date: Mon, 7 Mar 2022 20:02:08 +0100 Subject: [PATCH 041/100] Proto,SCORU: Add a concept of Tick to count exec steps Signed-off-by: Yann Regis-Gianas --- src/proto_alpha/lib_protocol/TEZOS_PROTOCOL | 1 + src/proto_alpha/lib_protocol/alpha_context.ml | 1 + .../lib_protocol/alpha_context.mli | 23 +++++ src/proto_alpha/lib_protocol/dune.inc | 5 + .../lib_protocol/sc_rollup_tick_repr.ml | 55 +++++++++++ .../lib_protocol/sc_rollup_tick_repr.mli | 55 +++++++++++ src/proto_alpha/lib_protocol/test/pbt/dune | 1 + .../test/pbt/test_sc_rollup_tick_repr.ml | 96 +++++++++++++++++++ 8 files changed, 237 insertions(+) create mode 100644 src/proto_alpha/lib_protocol/sc_rollup_tick_repr.ml create mode 100644 src/proto_alpha/lib_protocol/sc_rollup_tick_repr.mli create mode 100644 src/proto_alpha/lib_protocol/test/pbt/test_sc_rollup_tick_repr.ml diff --git a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL index aa3b2d503b..3ae67d7972 100644 --- a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL +++ b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL @@ -70,6 +70,7 @@ "Lazy_storage_kind", "Receipt_repr", "Migration_repr", + "Sc_rollup_tick_repr", "Raw_context_intf", "Raw_context", diff --git a/src/proto_alpha/lib_protocol/alpha_context.ml b/src/proto_alpha/lib_protocol/alpha_context.ml index 6647d91934..585aea7b0d 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.ml +++ b/src/proto_alpha/lib_protocol/alpha_context.ml @@ -53,6 +53,7 @@ end module Slot = Slot_repr module Sc_rollup = struct + module Tick = Sc_rollup_tick_repr include Sc_rollup_repr include Sc_rollup_storage module Inbox = Sc_rollup_inbox diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index 72dd3d8e63..312fcfe6f9 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -2396,6 +2396,29 @@ end (** See {!Sc_rollup_storage} and {!Sc_rollup_repr}. *) module Sc_rollup : sig + (** See {!Sc_rollup_tick_repr}. *) + module Tick : sig + type t + + val initial : t + + val next : t -> t + + val distance : t -> t -> Z.t + + val of_int : int -> t option + + val to_int : t -> int option + + val encoding : t Data_encoding.t + + val pp : Format.formatter -> t -> unit + + include Compare.S with type t := t + + module Map : Map.S with type key = t + end + module PVM : sig type boot_sector diff --git a/src/proto_alpha/lib_protocol/dune.inc b/src/proto_alpha/lib_protocol/dune.inc index 13b8a2b90b..2dd8c5ba6c 100644 --- a/src/proto_alpha/lib_protocol/dune.inc +++ b/src/proto_alpha/lib_protocol/dune.inc @@ -95,6 +95,7 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end lazy_storage_kind.mli lazy_storage_kind.ml receipt_repr.mli receipt_repr.ml migration_repr.mli migration_repr.ml + sc_rollup_tick_repr.mli sc_rollup_tick_repr.ml raw_context_intf.ml raw_context.mli raw_context.ml storage_costs.mli storage_costs.ml @@ -268,6 +269,7 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end lazy_storage_kind.mli lazy_storage_kind.ml receipt_repr.mli receipt_repr.ml migration_repr.mli migration_repr.ml + sc_rollup_tick_repr.mli sc_rollup_tick_repr.ml raw_context_intf.ml raw_context.mli raw_context.ml storage_costs.mli storage_costs.ml @@ -441,6 +443,7 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end lazy_storage_kind.mli lazy_storage_kind.ml receipt_repr.mli receipt_repr.ml migration_repr.mli migration_repr.ml + sc_rollup_tick_repr.mli sc_rollup_tick_repr.ml raw_context_intf.ml raw_context.mli raw_context.ml storage_costs.mli storage_costs.ml @@ -636,6 +639,7 @@ include Tezos_raw_protocol_alpha.Main Lazy_storage_kind Receipt_repr Migration_repr + Sc_rollup_tick_repr Raw_context_intf Raw_context Storage_costs @@ -850,6 +854,7 @@ include Tezos_raw_protocol_alpha.Main lazy_storage_kind.mli lazy_storage_kind.ml receipt_repr.mli receipt_repr.ml migration_repr.mli migration_repr.ml + sc_rollup_tick_repr.mli sc_rollup_tick_repr.ml raw_context_intf.ml raw_context.mli raw_context.ml storage_costs.mli storage_costs.ml diff --git a/src/proto_alpha/lib_protocol/sc_rollup_tick_repr.ml b/src/proto_alpha/lib_protocol/sc_rollup_tick_repr.ml new file mode 100644 index 0000000000..e16ac07c91 --- /dev/null +++ b/src/proto_alpha/lib_protocol/sc_rollup_tick_repr.ml @@ -0,0 +1,55 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* Copyright (c) 2022 Trili Tech, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +include Z + +let initial = zero + +let next = succ + +let pp = pp_print + +let encoding = Data_encoding.n + +let distance tick1 tick2 = Z.abs (Z.sub tick1 tick2) + +let of_int x = if Compare.Int.(x < 0) then None else Some (Z.of_int x) + +let to_int x = if Z.fits_int x then Some (Z.to_int x) else None + +let ( <= ) = leq + +let ( < ) = lt + +let ( >= ) = geq + +let ( > ) = gt + +let ( = ) = equal + +let ( <> ) x y = not (x = y) + +module Map = Map.Make (Z) diff --git a/src/proto_alpha/lib_protocol/sc_rollup_tick_repr.mli b/src/proto_alpha/lib_protocol/sc_rollup_tick_repr.mli new file mode 100644 index 0000000000..9a91554a65 --- /dev/null +++ b/src/proto_alpha/lib_protocol/sc_rollup_tick_repr.mli @@ -0,0 +1,55 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* Copyright (c) 2022 Trili Tech, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** This module defines [Tick.t], an execution step counter for + smart-contract rollups. *) + +(** A tick is a counter for the execution step of a smart-contract rollup. *) +type t + +(** The initial tick. *) +val initial : t + +(** [next tick] returns the counter successor of [tick]. No overflow can happen. *) +val next : t -> t + +(** [distance t1 t2] is the absolute value of the difference between [t1] and [t2]. *) +val distance : t -> t -> Z.t + +(** [of_int x] returns [Some tick] for the rollup [x]-th execution + step if [x] is non-negative. Returns [None] otherwise. *) +val of_int : int -> t option + +(** [to_int tick] converts the [tick] into an integer. *) +val to_int : t -> int option + +val encoding : t Data_encoding.t + +val pp : Format.formatter -> t -> unit + +include Compare.S with type t := t + +module Map : Map.S with type key = t diff --git a/src/proto_alpha/lib_protocol/test/pbt/dune b/src/proto_alpha/lib_protocol/test/pbt/dune index 908952ffec..dcdd85f2d2 100644 --- a/src/proto_alpha/lib_protocol/test/pbt/dune +++ b/src/proto_alpha/lib_protocol/test/pbt/dune @@ -8,6 +8,7 @@ test_tez_repr test_tx_rollup_l2_encoding test_tx_rollup_l2_withdraw_storage + test_sc_rollup_tick_repr test_carbonated_map) (libraries tezos-base tezos-micheline diff --git a/src/proto_alpha/lib_protocol/test/pbt/test_sc_rollup_tick_repr.ml b/src/proto_alpha/lib_protocol/test/pbt/test_sc_rollup_tick_repr.ml new file mode 100644 index 0000000000..b8a2c84b35 --- /dev/null +++ b/src/proto_alpha/lib_protocol/test/pbt/test_sc_rollup_tick_repr.ml @@ -0,0 +1,96 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol Library + Invocation: dune exec \ + src/proto_alpha/lib_protocol/test/pbt/test_sc_rollup_tick_repr.exe + Subject: Operations in Tick_repr +*) + +open Protocol.Alpha_context.Sc_rollup +open QCheck + +(** A generator for ticks *) +let tick : Tick.t QCheck.arbitrary = + QCheck.( + Gen.(make (Option.value ~default:Tick.initial <$> map Tick.of_int nat))) + +(** For all x, x = initial \/ x > initial. *) +let test_initial_is_bottom = + QCheck.Test.make ~name:"x = initial \\/ x > initial" tick @@ fun x -> + Tick.(x = initial || x > initial) + +(** For all x, next x > x. *) +let test_next_is_monotonic = + QCheck.Test.make ~name:"next x > x" tick @@ fun x -> Tick.(next x > x) + +(** distance is indeed a distance. *) +let test_distance_identity_of_indiscernibles = + QCheck.Test.make ~name:"distance is a distance (identity)" (pair tick tick) + @@ fun (x, y) -> + (Z.(equal (Tick.distance x y) zero) && Tick.(x = y)) + || Z.(not (equal (Tick.distance x y) zero)) + +let test_distance_symmetry = + QCheck.Test.make ~name:"distance is a distance (symmetry)" (pair tick tick) + @@ fun (x, y) -> Z.(equal (Tick.distance x y) (Tick.distance y x)) + +let test_distance_triangle_inequality = + QCheck.Test.make + ~name:"distance is a distance (triangle inequality)" + (triple tick tick tick) + @@ fun (x, y, z) -> + Tick.(Z.(geq (distance x y + distance y z) (distance x z))) + +(** [of_int x = Some t] iff [x >= 0] *) +let test_of_int = + QCheck.Test.make ~name:"of_int only accepts natural numbers" int @@ fun x -> + match Tick.of_int x with None -> x < 0 | Some _ -> x >= 0 + +(** [of_int (to_int x) = Some x]. *) +let test_of_int_to_int = + QCheck.Test.make ~name:"to_int o of_int = identity" tick @@ fun x -> + Tick.( + match to_int x with + | None -> (* by the tick generator definition. *) assert false + | Some i -> ( match of_int i with Some y -> y = x | None -> false)) + +let tests = + [ + test_next_is_monotonic; + test_initial_is_bottom; + test_distance_identity_of_indiscernibles; + test_distance_symmetry; + test_distance_triangle_inequality; + test_of_int; + test_of_int_to_int; + ] + +let () = + Alcotest.run + "Tick_repr" + [("Tick_repr", Lib_test.Qcheck_helpers.qcheck_wrap tests)] From b786a0036bbb07ce505b0ccd2b1071a97238bb98 Mon Sep 17 00:00:00 2001 From: Yann Regis-Gianas Date: Wed, 16 Feb 2022 10:27:55 +0100 Subject: [PATCH 042/100] Proto,SCORU: Define the semantics of PVM Signed-off-by: Yann Regis-Gianas --- src/proto_alpha/lib_protocol/TEZOS_PROTOCOL | 1 + src/proto_alpha/lib_protocol/dune.inc | 5 + .../lib_protocol/sc_rollup_PVM_sem.ml | 107 ++++++++++++++++++ .../lib_protocol/sc_rollup_arith.ml | 34 +++++- .../lib_protocol/sc_rollup_arith.mli | 2 + src/proto_alpha/lib_protocol/sc_rollups.ml | 2 + src/proto_alpha/lib_protocol/sc_rollups.mli | 2 + 7 files changed, 151 insertions(+), 2 deletions(-) create mode 100644 src/proto_alpha/lib_protocol/sc_rollup_PVM_sem.ml diff --git a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL index 3ae67d7972..f247802069 100644 --- a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL +++ b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL @@ -166,6 +166,7 @@ "Script_interpreter_defs", "Script_interpreter", "Sc_rollup_operations", + "Sc_rollup_PVM_sem", "Sc_rollup_arith", "Sc_rollups", diff --git a/src/proto_alpha/lib_protocol/dune.inc b/src/proto_alpha/lib_protocol/dune.inc index 2dd8c5ba6c..52d534e023 100644 --- a/src/proto_alpha/lib_protocol/dune.inc +++ b/src/proto_alpha/lib_protocol/dune.inc @@ -180,6 +180,7 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end script_interpreter_defs.ml script_interpreter.mli script_interpreter.ml sc_rollup_operations.mli sc_rollup_operations.ml + sc_rollup_PVM_sem.ml sc_rollup_arith.mli sc_rollup_arith.ml sc_rollups.mli sc_rollups.ml baking.mli baking.ml @@ -354,6 +355,7 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end script_interpreter_defs.ml script_interpreter.mli script_interpreter.ml sc_rollup_operations.mli sc_rollup_operations.ml + sc_rollup_PVM_sem.ml sc_rollup_arith.mli sc_rollup_arith.ml sc_rollups.mli sc_rollups.ml baking.mli baking.ml @@ -528,6 +530,7 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end script_interpreter_defs.ml script_interpreter.mli script_interpreter.ml sc_rollup_operations.mli sc_rollup_operations.ml + sc_rollup_PVM_sem.ml sc_rollup_arith.mli sc_rollup_arith.ml sc_rollups.mli sc_rollups.ml baking.mli baking.ml @@ -724,6 +727,7 @@ include Tezos_raw_protocol_alpha.Main Script_interpreter_defs Script_interpreter Sc_rollup_operations + Sc_rollup_PVM_sem Sc_rollup_arith Sc_rollups Baking @@ -939,6 +943,7 @@ include Tezos_raw_protocol_alpha.Main script_interpreter_defs.ml script_interpreter.mli script_interpreter.ml sc_rollup_operations.mli sc_rollup_operations.ml + sc_rollup_PVM_sem.ml sc_rollup_arith.mli sc_rollup_arith.ml sc_rollups.mli sc_rollups.ml baking.mli baking.ml diff --git a/src/proto_alpha/lib_protocol/sc_rollup_PVM_sem.ml b/src/proto_alpha/lib_protocol/sc_rollup_PVM_sem.ml new file mode 100644 index 0000000000..42d275b009 --- /dev/null +++ b/src/proto_alpha/lib_protocol/sc_rollup_PVM_sem.ml @@ -0,0 +1,107 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* Copyright (c) 2022 Trili Tech, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** This module introduces the semantics of Proof-generating Virtual Machines. + + A PVM defines an operational semantics for some computational + model. The specificity of PVMs, in comparison with standard virtual + machines, is their ability to generate and to validate a *compact* + proof that a given atomic execution step turned a given state into + another one. + + In the smart-contract rollups, PVMs are used for two purposes: + + - They allow for the externalization of rollup execution by + completely specifying the operational semantics of a given + rollup. This standardization of the semantics gives a unique and + executable source of truth about the interpretation of + smart-contract rollup inboxes, seen as a transformation of a rollup + state. + + - They allow for the validation or refutation of a claim that the + processing of some messages led to a given new rollup state (given + an actual source of truth about the nature of these messages). + +*) +open Alpha_context + +open Sc_rollup + +module type S = sig + (** + + The state of the PVM denotes a state of the rollup. + + *) + type state + + (** During interactive rejection games, a player may need to + provide a proof that a given execution step is valid. *) + type proof + + val proof_encoding : proof Data_encoding.t + + (** A state is initialized in a given context. *) + type context + + (** A commitment hash characterized the contents of the state. *) + type hash = State_hash.t + + (** [state_hash state] returns a compressed representation of [state]. *) + val state_hash : state -> hash Lwt.t + + (** [initial_state context] is the state of the PVM before booting. It must + be such that [state_hash state = Commitment_hash.zero]. Any [context] + should be enough to create an initial state. *) + val initial_state : context -> PVM.boot_sector -> state Lwt.t + + (** [is_input_state state] returns [Some (level, counter)] if [state] is + waiting for the input message that comes next to the message numbered + [counter] in the inbox of a given [level]. *) + val is_input_state : state -> (Raw_level.t * Z.t) option Lwt.t + + type input = { + inbox_level : Raw_level.t; + message_counter : Z.t; + payload : string; + } + + (** [set_input level n msg state] sets [msg] in [state] as + the next message to be processed. This input message is assumed + to be the number [n] in the inbox messages at the given + [level]. The input message must be the message next to the + previous message processed by the rollup. *) + val set_input : input -> state -> state Lwt.t + + (** [eval s0] returns a state [s1] resulting from the + execution of an atomic step of the rollup at state [s0]. *) + val eval : state -> state Lwt.t + + (** [verify_proof input proof] returns [true] iff the [proof] is valid. + If the state is an input state, [input] is the hash of the input + message externally provided to the evaluation function. *) + val verify_proof : input:input option -> proof -> bool Lwt.t +end diff --git a/src/proto_alpha/lib_protocol/sc_rollup_arith.ml b/src/proto_alpha/lib_protocol/sc_rollup_arith.ml index c6b131c0b0..77c164e6b5 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_arith.ml +++ b/src/proto_alpha/lib_protocol/sc_rollup_arith.ml @@ -23,9 +23,39 @@ (* *) (*****************************************************************************) +open Alpha_context +open Sc_rollup + let name = "arith" -let parse_boot_sector _ = - Some (Alpha_context.Sc_rollup.PVM.boot_sector_of_string "") +let parse_boot_sector _ = Some (PVM.boot_sector_of_string "") let pp_boot_sector _fmt _ = () + +type state = unit + +type context = unit + +type hash = State_hash.t + +let state_hash _ = assert false + +let initial_state _ _ = assert false + +let is_input_state _ = assert false + +type input = { + inbox_level : Raw_level.t; + message_counter : Z.t; + payload : string; +} + +let set_input _ _ = assert false + +let eval _ = assert false + +type proof = unit + +let proof_encoding = Data_encoding.unit + +let verify_proof ~input:_ _ = assert false diff --git a/src/proto_alpha/lib_protocol/sc_rollup_arith.mli b/src/proto_alpha/lib_protocol/sc_rollup_arith.mli index 4162b3598c..738120f8e3 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_arith.mli +++ b/src/proto_alpha/lib_protocol/sc_rollup_arith.mli @@ -32,3 +32,5 @@ val name : string val parse_boot_sector : string -> PVM.boot_sector option val pp_boot_sector : Format.formatter -> PVM.boot_sector -> unit + +include Sc_rollup_PVM_sem.S diff --git a/src/proto_alpha/lib_protocol/sc_rollups.ml b/src/proto_alpha/lib_protocol/sc_rollups.ml index ef115a9b95..8e4ed907fc 100644 --- a/src/proto_alpha/lib_protocol/sc_rollups.ml +++ b/src/proto_alpha/lib_protocol/sc_rollups.ml @@ -34,6 +34,8 @@ module PVM = struct val parse_boot_sector : string -> boot_sector option val pp_boot_sector : Format.formatter -> boot_sector -> unit + + include Sc_rollup_PVM_sem.S end type t = (module S) diff --git a/src/proto_alpha/lib_protocol/sc_rollups.mli b/src/proto_alpha/lib_protocol/sc_rollups.mli index 0c530f15e2..8daea3f013 100644 --- a/src/proto_alpha/lib_protocol/sc_rollups.mli +++ b/src/proto_alpha/lib_protocol/sc_rollups.mli @@ -35,6 +35,8 @@ module PVM : sig val parse_boot_sector : string -> boot_sector option val pp_boot_sector : Format.formatter -> boot_sector -> unit + + include Sc_rollup_PVM_sem.S end type t = (module S) From 4988978ad623e4c3a5c4a601f3a7a87cf32ab950 Mon Sep 17 00:00:00 2001 From: Yann Regis-Gianas Date: Thu, 10 Mar 2022 16:56:44 +0100 Subject: [PATCH 043/100] Proto,SCORU: Add encoding for sc rollup PVM boot sector Signed-off-by: Yann Regis-Gianas --- src/proto_alpha/lib_protocol/alpha_context.mli | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index 312fcfe6f9..87e01d754a 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -2422,6 +2422,8 @@ module Sc_rollup : sig module PVM : sig type boot_sector + val boot_sector_encoding : boot_sector Data_encoding.t + val boot_sector_of_string : string -> boot_sector end From d299b72df6a1bd960c0f262fd5c5d6b454d77fba Mon Sep 17 00:00:00 2001 From: Yann Regis-Gianas Date: Mon, 7 Mar 2022 20:11:28 +0100 Subject: [PATCH 044/100] Proto,SCORU: Add a conversion from boot_sector to string Signed-off-by: Yann Regis-Gianas --- src/proto_alpha/lib_protocol/alpha_context.mli | 2 ++ src/proto_alpha/lib_protocol/sc_rollup_repr.ml | 2 ++ src/proto_alpha/lib_protocol/sc_rollup_repr.mli | 2 ++ 3 files changed, 6 insertions(+) diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index 87e01d754a..1e237890d0 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -2425,6 +2425,8 @@ module Sc_rollup : sig val boot_sector_encoding : boot_sector Data_encoding.t val boot_sector_of_string : string -> boot_sector + + val boot_sector_to_string : boot_sector -> string end module Address : S.HASH diff --git a/src/proto_alpha/lib_protocol/sc_rollup_repr.ml b/src/proto_alpha/lib_protocol/sc_rollup_repr.ml index ec60c206b4..431d7474d0 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_repr.ml +++ b/src/proto_alpha/lib_protocol/sc_rollup_repr.ml @@ -30,6 +30,8 @@ module PVM = struct let boot_sector_encoding = Data_encoding.string let boot_sector_of_string s = s + + let boot_sector_to_string s = s end module Address = struct diff --git a/src/proto_alpha/lib_protocol/sc_rollup_repr.mli b/src/proto_alpha/lib_protocol/sc_rollup_repr.mli index da1b4c41a5..70b6f7caa2 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_repr.mli +++ b/src/proto_alpha/lib_protocol/sc_rollup_repr.mli @@ -46,6 +46,8 @@ module PVM : sig val boot_sector_encoding : boot_sector Data_encoding.t val boot_sector_of_string : string -> boot_sector + + val boot_sector_to_string : boot_sector -> string end (** A smart-contract rollup has an address starting with "scr1". *) From 2a4be8171437b24485d26436bf8074187e4515da Mon Sep 17 00:00:00 2001 From: Yann Regis-Gianas Date: Mon, 7 Mar 2022 20:12:04 +0100 Subject: [PATCH 045/100] Proto,SCORU: Assign a semantic to the example arith rollup Signed-off-by: Yann Regis-Gianas --- .../lib_protocol/sc_rollup_arith.ml | 839 +++++++++++++++++- .../lib_protocol/sc_rollup_arith.mli | 117 ++- src/proto_alpha/lib_protocol/sc_rollups.ml | 2 +- .../lib_protocol/test/unit/main.ml | 1 + .../test/unit/test_sc_rollup_arith.ml | 204 +++++ 5 files changed, 1137 insertions(+), 26 deletions(-) create mode 100644 src/proto_alpha/lib_protocol/test/unit/test_sc_rollup_arith.ml diff --git a/src/proto_alpha/lib_protocol/sc_rollup_arith.ml b/src/proto_alpha/lib_protocol/sc_rollup_arith.ml index 77c164e6b5..97c1194780 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_arith.ml +++ b/src/proto_alpha/lib_protocol/sc_rollup_arith.ml @@ -26,36 +26,837 @@ open Alpha_context open Sc_rollup -let name = "arith" +module type P = sig + module Tree : Context.TREE with type key = string list and type value = bytes -let parse_boot_sector _ = Some (PVM.boot_sector_of_string "") + type tree = Tree.tree -let pp_boot_sector _fmt _ = () + type proof -type state = unit + val proof_encoding : proof Data_encoding.t -type context = unit + val proof_start_state : proof -> State_hash.t -type hash = State_hash.t + val proof_stop_state : proof -> State_hash.t -let state_hash _ = assert false + val verify_proof : + proof -> + (tree -> (tree * 'a) Lwt.t) -> + ( tree * 'a, + [ `Proof_mismatch of string + | `Stream_too_long of string + | `Stream_too_short of string ] ) + result + Lwt.t +end -let initial_state _ _ = assert false +module type S = sig + include Sc_rollup_PVM_sem.S -let is_input_state _ = assert false + val name : string -type input = { - inbox_level : Raw_level.t; - message_counter : Z.t; - payload : string; -} + val parse_boot_sector : string -> Sc_rollup.PVM.boot_sector option -let set_input _ _ = assert false + val pp_boot_sector : Format.formatter -> Sc_rollup.PVM.boot_sector -> unit -let eval _ = assert false + val pp : state -> (Format.formatter -> unit -> unit) Lwt.t -type proof = unit + val get_tick : state -> Sc_rollup.Tick.t Lwt.t -let proof_encoding = Data_encoding.unit + type status = Halted | WaitingForInputMessage | Parsing | Evaluating -let verify_proof ~input:_ _ = assert false + val get_status : state -> status Lwt.t + + type instruction = IPush : int -> instruction | IAdd : instruction + + val equal_instruction : instruction -> instruction -> bool + + val pp_instruction : Format.formatter -> instruction -> unit + + val get_parsing_result : state -> bool option Lwt.t + + val get_code : state -> instruction list Lwt.t + + val get_stack : state -> int list Lwt.t + + val get_evaluation_result : state -> bool option Lwt.t + + val get_is_stuck : state -> string option Lwt.t +end + +module Make (Context : P) : S with type context = Context.Tree.t = struct + module Tree = Context.Tree + + type context = Context.Tree.t + + type hash = State_hash.t + + type proof = Context.proof + + let proof_encoding = Context.proof_encoding + + let name = "arith" + + let parse_boot_sector s = Some (PVM.boot_sector_of_string s) + + let pp_boot_sector fmt s = + Format.fprintf fmt "%s" (PVM.boot_sector_to_string s) + + type tree = Tree.tree + + type status = Halted | WaitingForInputMessage | Parsing | Evaluating + + type instruction = IPush : int -> instruction | IAdd : instruction + + let equal_instruction i1 i2 = + match (i1, i2) with + | (IPush x, IPush y) -> Compare.Int.(x = y) + | (IAdd, IAdd) -> true + | (_, _) -> false + + let pp_instruction fmt = function + | IPush x -> Format.fprintf fmt "push(%d)" x + | IAdd -> Format.fprintf fmt "add" + + (* + + The machine state is represented using a Merkle tree. + + Here is the data model of this state represented in the tree: + + - tick : Tick.t + The current tick counter of the machine. + - status : status + The current status of the machine. + - stack : int deque + The stack of integers. + - next_message : string option + The current input message to be processed. + - code : instruction deque + The instructions parsed from the input message. + - lexer_state : int * int + The internal state of the lexer. + - parsing_state : parsing_state + The internal state of the parser. + - parsing_result : bool option + The outcome of parsing. + - evaluation_result : bool option + The outcome of evaluation. + + *) + module State = struct + type state = tree + + module Monad : sig + type 'a t + + val run : 'a t -> state -> (state * 'a option) Lwt.t + + val is_stuck : string option t + + val internal_error : string -> 'a t + + val return : 'a -> 'a t + + module Syntax : sig + val ( let* ) : 'a t -> ('a -> 'b t) -> 'b t + end + + val remove : Tree.key -> unit t + + val find_value : Tree.key -> 'a Data_encoding.t -> 'a option t + + val get_value : default:'a -> Tree.key -> 'a Data_encoding.t -> 'a t + + val set_value : Tree.key -> 'a Data_encoding.t -> 'a -> unit t + end = struct + type 'a t = state -> (state * 'a option) Lwt.t + + let return x state = Lwt.return (state, Some x) + + let bind m f state = + let open Lwt_syntax in + let* (state, res) = m state in + match res with None -> return (state, None) | Some res -> f res state + + module Syntax = struct + let ( let* ) = bind + end + + let run m state = m state + + let internal_error_key = ["internal_error"] + + let internal_error msg tree = + let open Lwt_syntax in + let* tree = Tree.add tree internal_error_key (Bytes.of_string msg) in + return (tree, None) + + let is_stuck tree = + let open Lwt_syntax in + let* v = Tree.find tree internal_error_key in + return (tree, Some (Option.map Bytes.to_string v)) + + let remove key tree = + let open Lwt_syntax in + let* tree = Tree.remove tree key in + return (tree, Some ()) + + let find_value key encoding state = + let open Lwt_syntax in + let* obytes = Tree.find state key in + match obytes with + | None -> return (state, Some None) + | Some bytes -> ( + match Data_encoding.Binary.of_bytes_opt encoding bytes with + | None -> internal_error "Internal_Error during decoding" state + | Some v -> return (state, Some (Some v))) + + let get_value ~default key encoding = + let open Syntax in + let* ov = find_value key encoding in + match ov with None -> return default | Some x -> return x + + let set_value key encoding value tree = + let open Lwt_syntax in + Data_encoding.Binary.to_bytes_opt encoding value |> function + | None -> internal_error "Internal_Error during encoding" tree + | Some bytes -> + let* tree = Tree.add tree key bytes in + return (tree, Some ()) + end + + open Monad + open Monad.Syntax + + module MakeVar (P : sig + type t + + val name : string + + val initial : t + + val pp : Format.formatter -> t -> unit + + val encoding : t Data_encoding.t + end) = + struct + let key = [P.name] + + let create = set_value key P.encoding P.initial + + let get = + let* v = find_value key P.encoding in + match v with + | None -> + (* This case should not happen if [create] is properly called. *) + return P.initial + | Some v -> return v + + let set = set_value key P.encoding + + let pp = + let open Monad.Syntax in + let* v = get in + return @@ fun fmt () -> Format.fprintf fmt "@[%s : %a@]" P.name P.pp v + end + + module MakeDeque (P : sig + type t + + val name : string + + val encoding : t Data_encoding.t + end) = + struct + (* + + A stateful deque. + + [[head; end[] is the index range for the elements of the deque. + + The length of the deque is therefore [end - head]. + + *) + + let head_key = [P.name; "head"] + + let end_key = [P.name; "end"] + + let get_head = get_value ~default:Z.zero head_key Data_encoding.z + + let set_head = set_value head_key Data_encoding.z + + let get_end = get_value ~default:(Z.of_int 0) end_key Data_encoding.z + + let set_end = set_value end_key Data_encoding.z + + let idx_key idx = [P.name; Z.to_string idx] + + let push x = + let open Monad.Syntax in + let* head_idx = get_head in + let head_idx' = Z.pred head_idx in + let* () = set_head head_idx' in + set_value (idx_key head_idx') P.encoding x + + let pop = + let open Monad.Syntax in + let* head_idx = get_head in + let* end_idx = get_end in + if Z.(leq end_idx head_idx) then return None + else + let* v = find_value (idx_key head_idx) P.encoding in + match v with + | None -> (* By invariants of the Deque. *) assert false + | Some x -> + let* () = remove (idx_key head_idx) in + let head_idx = Z.succ head_idx in + let* () = set_head head_idx in + return (Some x) + + let inject x = + let open Monad.Syntax in + let* end_idx = get_end in + let end_idx' = Z.succ end_idx in + let* () = set_end end_idx' in + set_value (idx_key end_idx) P.encoding x + + let to_list = + let open Monad.Syntax in + let* head_idx = get_head in + let* end_idx = get_end in + let rec aux l idx = + if Z.(lt idx head_idx) then return l + else + let* v = find_value (idx_key idx) P.encoding in + match v with + | None -> (* By invariants of deque *) assert false + | Some v -> aux (v :: l) (Z.pred idx) + in + aux [] (Z.pred end_idx) + + let clear = remove [P.name] + end + + module CurrentTick = MakeVar (struct + include Tick + + let name = "tick" + end) + + module Stack = MakeDeque (struct + type t = int + + let name = "stack" + + let encoding = Data_encoding.int31 + end) + + module Code = MakeDeque (struct + type t = instruction + + let name = "code" + + let encoding = + Data_encoding.( + union + [ + case + ~title:"push" + (Tag 0) + Data_encoding.int31 + (function IPush x -> Some x | _ -> None) + (fun x -> IPush x); + case + ~title:"add" + (Tag 1) + Data_encoding.unit + (function IAdd -> Some () | _ -> None) + (fun () -> IAdd); + ]) + end) + + module Boot_sector = MakeVar (struct + type t = PVM.boot_sector + + let name = "boot_sector" + + let initial = PVM.boot_sector_of_string "" + + let encoding = PVM.boot_sector_encoding + + let pp fmt s = Format.fprintf fmt "%s" (PVM.boot_sector_to_string s) + end) + + module Status = MakeVar (struct + type t = status + + let initial = Halted + + let encoding = + Data_encoding.string_enum + [ + ("Halted", Halted); + ("WaitingForInput", WaitingForInputMessage); + ("Parsing", Parsing); + ("Evaluating", Evaluating); + ] + + let name = "status" + + let string_of_status = function + | Halted -> "Halted" + | WaitingForInputMessage -> "WaitingForInputMessage" + | Parsing -> "Parsing" + | Evaluating -> "Evaluating" + + let pp fmt status = Format.fprintf fmt "%s" (string_of_status status) + end) + + module CurrentLevel = MakeVar (struct + type t = Raw_level.t + + let initial = Raw_level.root + + let encoding = Raw_level.encoding + + let name = "current_level" + + let pp = Raw_level.pp + end) + + module MessageCounter = MakeVar (struct + type t = Z.t + + let initial = Z.(pred zero) + + let encoding = Data_encoding.n + + let name = "message_counter" + + let pp = Z.pp_print + end) + + module NextMessage = MakeVar (struct + type t = string option + + let initial = None + + let encoding = Data_encoding.(option string) + + let name = "next_message" + + let pp fmt = function + | None -> Format.fprintf fmt "None" + | Some s -> Format.fprintf fmt "Some %s" s + end) + + type parser_state = ParseInt | SkipLayout + + module LexerState = MakeVar (struct + type t = int * int + + let name = "lexer_buffer" + + let initial = (-1, -1) + + let encoding = Data_encoding.(tup2 int31 int31) + + let pp fmt (start, len) = + Format.fprintf fmt "lexer.(start = %d, len = %d)" start len + end) + + module ParserState = MakeVar (struct + type t = parser_state + + let name = "parser_state" + + let initial = SkipLayout + + let encoding = + Data_encoding.string_enum + [("ParseInt", ParseInt); ("SkipLayout", SkipLayout)] + + let pp fmt = function + | ParseInt -> Format.fprintf fmt "Parsing int" + | SkipLayout -> Format.fprintf fmt "Skipping layout" + end) + + module ParsingResult = MakeVar (struct + type t = bool option + + let name = "parsing_result" + + let initial = None + + let encoding = Data_encoding.(option bool) + + let pp fmt = function + | None -> Format.fprintf fmt "n/a" + | Some true -> Format.fprintf fmt "parsing succeeds" + | Some false -> Format.fprintf fmt "parsing fails" + end) + + module EvaluationResult = MakeVar (struct + type t = bool option + + let name = "evaluation_result" + + let initial = None + + let encoding = Data_encoding.(option bool) + + let pp fmt = function + | None -> Format.fprintf fmt "n/a" + | Some true -> Format.fprintf fmt "evaluation succeeds" + | Some false -> Format.fprintf fmt "evaluation fails" + end) + + let pp = + let open Monad.Syntax in + let* status_pp = Status.pp in + let* message_counter_pp = MessageCounter.pp in + let* next_message_pp = NextMessage.pp in + let* parsing_result_pp = ParsingResult.pp in + let* parser_state_pp = ParserState.pp in + let* lexer_state_pp = LexerState.pp in + let* evaluation_result_pp = EvaluationResult.pp in + return @@ fun fmt () -> + Format.fprintf + fmt + "@[@;%a@;%a@;%a@;%a@;%a@;%a@;%a@]" + status_pp + () + message_counter_pp + () + next_message_pp + () + parsing_result_pp + () + parser_state_pp + () + lexer_state_pp + () + evaluation_result_pp + () + end + + open State + + type state = State.state + + let pp state = + let open Lwt_syntax in + let* (_, pp) = Monad.run pp state in + match pp with + | None -> return @@ fun fmt _ -> Format.fprintf fmt "" + | Some pp -> return pp + + open Monad + + let initial_state ctxt boot_sector = + let state = Tree.empty ctxt in + let m = + let open Monad.Syntax in + let* () = Boot_sector.set boot_sector in + let* () = Status.set Halted in + return () + in + let open Lwt_syntax in + let* (state, _) = run m state in + return state + + let state_hash state = + let m = + let open Monad.Syntax in + let* status = Status.get in + match status with + | Halted -> return State_hash.zero + | _ -> + Context_hash.to_bytes @@ Tree.hash state |> fun h -> + return @@ State_hash.hash_bytes [h] + in + let open Lwt_syntax in + let* state = Monad.run m state in + match state with + | (_, Some hash) -> return hash + | _ -> (* Hash computation always succeeds. *) assert false + + let boot = + let open Monad.Syntax in + let* () = Status.create in + let* () = NextMessage.create in + let* () = Status.set WaitingForInputMessage in + return () + + let result_of ~default m state = + let open Lwt_syntax in + let* (_, v) = run m state in + match v with None -> return default | Some v -> return v + + let state_of m state = + let open Lwt_syntax in + let* (s, _) = run m state in + return s + + let get_tick = result_of ~default:Tick.initial CurrentTick.get + + let is_input_state_monadic = + let open Monad.Syntax in + let* status = Status.get in + match status with + | WaitingForInputMessage -> + let* level = CurrentLevel.get in + let* counter = MessageCounter.get in + return (Some (level, counter)) + | _ -> return None + + let is_input_state = result_of ~default:None @@ is_input_state_monadic + + let get_status = result_of ~default:WaitingForInputMessage @@ Status.get + + let get_code = result_of ~default:[] @@ Code.to_list + + let get_parsing_result = result_of ~default:None @@ ParsingResult.get + + let get_stack = result_of ~default:[] @@ Stack.to_list + + let get_evaluation_result = result_of ~default:None @@ EvaluationResult.get + + let get_is_stuck = result_of ~default:None @@ is_stuck + + type input = { + inbox_level : Raw_level.t; + message_counter : Z.t; + payload : string; + } + + let set_input_monadic {inbox_level; message_counter; payload} = + let open Monad.Syntax in + let* boot_sector = Boot_sector.get in + let msg = PVM.boot_sector_to_string boot_sector ^ payload in + let* last_level = CurrentLevel.get in + let* last_counter = MessageCounter.get in + let update = + let* () = CurrentLevel.set inbox_level in + let* () = MessageCounter.set message_counter in + let* () = NextMessage.set (Some msg) in + return () + in + let does_not_follow = + internal_error "The input message does not follow the previous one." + in + if Raw_level.(equal last_level inbox_level) then + if Z.(equal message_counter (succ last_counter)) then update + else does_not_follow + else if Raw_level.(last_level < inbox_level) then + if Z.(equal message_counter Z.zero) then update else does_not_follow + else does_not_follow + + let set_input input = state_of @@ set_input_monadic input + + let next_char = + let open Monad.Syntax in + LexerState.( + let* (start, len) = get in + set (start, len + 1)) + + let no_message_to_lex () = + internal_error "lexer: There is no input message to lex" + + let current_char = + let open Monad.Syntax in + let* (start, len) = LexerState.get in + let* msg = NextMessage.get in + match msg with + | None -> no_message_to_lex () + | Some s -> + if Compare.Int.(start + len < String.length s) then + return (Some s.[start + len]) + else return None + + let lexeme = + let open Monad.Syntax in + let* (start, len) = LexerState.get in + let* msg = NextMessage.get in + match msg with + | None -> no_message_to_lex () + | Some s -> + let* () = LexerState.set (start + len, 0) in + return (String.sub s start len) + + let push_int_literal = + let open Monad.Syntax in + let* s = lexeme in + match int_of_string_opt s with + | Some x -> Code.inject (IPush x) + | None -> (* By validity of int parsing. *) assert false + + let start_parsing : unit t = + let open Monad.Syntax in + let* () = Status.set Parsing in + let* () = ParsingResult.set None in + let* () = ParserState.set SkipLayout in + let* () = LexerState.set (0, 0) in + let* () = Status.set Parsing in + let* () = Code.clear in + return () + + let start_evaluating : unit t = + let open Monad.Syntax in + let* () = EvaluationResult.set None in + let* () = Stack.clear in + let* () = Status.set Evaluating in + return () + + let stop_parsing outcome = + let open Monad.Syntax in + let* () = ParsingResult.set (Some outcome) in + start_evaluating + + let stop_evaluating outcome = + let open Monad.Syntax in + let* () = EvaluationResult.set (Some outcome) in + Status.set WaitingForInputMessage + + let parse : unit t = + let open Monad.Syntax in + let produce_add = + let* _ = lexeme in + let* () = next_char in + let* () = Code.inject IAdd in + return () + in + let produce_int = + let* () = push_int_literal in + let* () = ParserState.set SkipLayout in + return () + in + let is_digit d = Compare.Char.(d >= '0' && d <= '9') in + let* parser_state = ParserState.get in + match parser_state with + | ParseInt -> ( + let* char = current_char in + match char with + | Some d when is_digit d -> next_char + | Some '+' -> + let* () = produce_int in + let* () = produce_add in + return () + | Some ' ' -> + let* () = produce_int in + let* () = next_char in + return () + | None -> + let* () = push_int_literal in + stop_parsing true + | _ -> stop_parsing false) + | SkipLayout -> ( + let* char = current_char in + match char with + | Some ' ' -> next_char + | Some '+' -> produce_add + | Some d when is_digit d -> + let* _ = lexeme in + let* () = next_char in + let* () = ParserState.set ParseInt in + return () + | None -> stop_parsing true + | _ -> stop_parsing false) + + let evaluate = + let open Monad.Syntax in + let* i = Code.pop in + match i with + | None -> stop_evaluating true + | Some (IPush x) -> Stack.push x + | Some IAdd -> ( + let* v = Stack.pop in + match v with + | None -> stop_evaluating false + | Some x -> ( + let* v = Stack.pop in + match v with + | None -> stop_evaluating false + | Some y -> Stack.push (x + y))) + + let reboot = + let open Monad.Syntax in + let* () = Status.set WaitingForInputMessage in + let* () = Stack.clear in + let* () = Code.clear in + return () + + let eval_step = + let open Monad.Syntax in + let* x = is_stuck in + match x with + | Some _ -> reboot + | None -> ( + let* status = Status.get in + match status with + | Halted -> boot + | WaitingForInputMessage -> ( + let* msg = NextMessage.get in + match msg with + | None -> + internal_error + "An input state was not provided an input message." + | Some _ -> start_parsing) + | Parsing -> parse + | Evaluating -> evaluate) + + let ticked m = + let open Monad.Syntax in + let* tick = CurrentTick.get in + let* () = CurrentTick.set (Tick.next tick) in + m + + let eval state = state_of (ticked eval_step) state + + let verify_proof ~input proof = + let open Lwt_syntax in + let transition state = + let* state = + match input with + | None -> eval state + | Some input -> state_of (ticked (set_input_monadic input)) state + in + return (state, ()) + in + let* x = Context.verify_proof proof transition in + match x with Ok _ -> return_true | Error _ -> return_false +end + +module ProtocolImplementation = Make (struct + module Tree = struct + include Context.Tree + + type tree = Context.tree + + type t = Context.t + + type key = string list + + type value = bytes + end + + type tree = Context.tree + + type proof = Context.Proof.tree Context.Proof.t + + let verify_proof = Context.verify_tree_proof + + let kinded_hash_to_state_hash = function + | `Value hash | `Node hash -> + State_hash.hash_bytes [Context_hash.to_bytes hash] + + let proof_start_state proof = + kinded_hash_to_state_hash proof.Context.Proof.before + + let proof_stop_state proof = + kinded_hash_to_state_hash proof.Context.Proof.after + + let proof_encoding = Context.Proof_encoding.V2.Tree32.tree_proof_encoding +end) diff --git a/src/proto_alpha/lib_protocol/sc_rollup_arith.mli b/src/proto_alpha/lib_protocol/sc_rollup_arith.mli index 738120f8e3..e3dda85c1f 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_arith.mli +++ b/src/proto_alpha/lib_protocol/sc_rollup_arith.mli @@ -23,14 +23,119 @@ (* *) (*****************************************************************************) -(** This module provides a temporary toy rollup. *) +(** This module provides a temporary toy rollup to be used as a demo. *) -open Alpha_context.Sc_rollup +(** -val name : string + This rollup is a stack machine equipped with addition. -val parse_boot_sector : string -> PVM.boot_sector option + It processed postfix arithmetic expressions written as sequence of + (space separated) [int] and [+] using the following rules: -val pp_boot_sector : Format.formatter -> PVM.boot_sector -> unit + - a number [x] is interpreted as pushing [x] on the stack ; -include Sc_rollup_PVM_sem.S + - a symbol [+] pops two integers [x] and [y] and pushes [x + y] on + the stack. + + If a message is not syntactically correct or does not evaluate + correctly, the machine stops its evaluation and waits for the next + message. + + The machine has a boot sector which is a mere string used a prefix + for each message. + + The module implements the {!Sc_rollup_PVM_sem.S} interface to be + used in the smart contract rollup infrastructure. + + The machine exposes extra operations to be used in the rollup node. + +*) +open Alpha_context + +module type S = sig + include Sc_rollup_PVM_sem.S + + (** [name] is "arith". *) + val name : string + + (** [parse_boot_sector s] builds a boot sector from its human + writable description. *) + val parse_boot_sector : string -> Sc_rollup.PVM.boot_sector option + + (** [pp_boot_sector fmt s] prints a human readable representation of + a boot sector. *) + val pp_boot_sector : Format.formatter -> Sc_rollup.PVM.boot_sector -> unit + + (** [pp state] returns a pretty-printer valid for [state]. *) + val pp : state -> (Format.formatter -> unit -> unit) Lwt.t + + (** [get_tick state] returns the current tick of [state]. *) + val get_tick : state -> Sc_rollup.Tick.t Lwt.t + + (** The machine has three possible states: *) + type status = Halted | WaitingForInputMessage | Parsing | Evaluating + + (** [get_status state] returns the machine status in [state]. *) + val get_status : state -> status Lwt.t + + (** The machine has only two instructions. *) + type instruction = IPush : int -> instruction | IAdd : instruction + + (** [equal_instruction i1 i2] is [true] iff [i1] equals [i2]. *) + val equal_instruction : instruction -> instruction -> bool + + (** [pp_instruction fmt i] shows a human readable representation of [i]. *) + val pp_instruction : Format.formatter -> instruction -> unit + + (** [get_parsing_result state] is [Some true] if the current + message is syntactically correct, [Some false] when it + contains a syntax error, and [None] when the machine is + not in parsing state. *) + val get_parsing_result : state -> bool option Lwt.t + + (** [get_code state] returns the current code obtained by parsing + the current input message. *) + val get_code : state -> instruction list Lwt.t + + (** [get_stack state] returns the current stack. *) + val get_stack : state -> int list Lwt.t + + (** [get_evaluation_result state] returns [Some true] if the current + message evaluation succeeds, [Some false] if it failed, and + [None] if the evaluation has not been done yet. *) + val get_evaluation_result : state -> bool option Lwt.t + + (** [get_is_stuck state] returns [Some err] if some internal error + made the machine fail during the last evaluation step. [None] + if no internal error occurred. When a machine is stuck, it + reboots, waiting for the next message to process. *) + val get_is_stuck : state -> string option Lwt.t +end + +module ProtocolImplementation : S with type context = Context.t + +module type P = sig + module Tree : Context.TREE with type key = string list and type value = bytes + + type tree = Tree.tree + + type proof + + val proof_encoding : proof Data_encoding.t + + val proof_start_state : proof -> Sc_rollup.State_hash.t + + val proof_stop_state : proof -> Sc_rollup.State_hash.t + + val verify_proof : + proof -> + (tree -> (tree * 'a) Lwt.t) -> + ( tree * 'a, + [ `Proof_mismatch of string + | `Stream_too_long of string + | `Stream_too_short of string ] ) + result + Lwt.t +end + +module Make (Context : P) : S with type context = Context.Tree.t diff --git a/src/proto_alpha/lib_protocol/sc_rollups.ml b/src/proto_alpha/lib_protocol/sc_rollups.ml index 8e4ed907fc..e9ddbecf85 100644 --- a/src/proto_alpha/lib_protocol/sc_rollups.ml +++ b/src/proto_alpha/lib_protocol/sc_rollups.ml @@ -45,7 +45,7 @@ let all = [Kind.Example_arith] let kind_of_string = function "arith" -> Some Kind.Example_arith | _ -> None -let example_arith_pvm = (module Sc_rollup_arith : PVM.S) +let example_arith_pvm = (module Sc_rollup_arith.ProtocolImplementation : PVM.S) let of_kind = function Kind.Example_arith -> example_arith_pvm diff --git a/src/proto_alpha/lib_protocol/test/unit/main.ml b/src/proto_alpha/lib_protocol/test/unit/main.ml index 2e82aca0a7..fc85a60e2c 100644 --- a/src/proto_alpha/lib_protocol/test/unit/main.ml +++ b/src/proto_alpha/lib_protocol/test/unit/main.ml @@ -72,5 +72,6 @@ let () = Unit_test.spec "tx rollup l2" Test_tx_rollup_l2.tests; Unit_test.spec "tx rollup l2 apply" Test_tx_rollup_l2_apply.tests; Unit_test.spec "liquidity baking" Test_liquidity_baking_repr.tests; + Unit_test.spec "sc rollup arith" Test_sc_rollup_arith.tests; ] |> Lwt_main.run 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 new file mode 100644 index 0000000000..2cec6ec1ac --- /dev/null +++ b/src/proto_alpha/lib_protocol/test/unit/test_sc_rollup_arith.ml @@ -0,0 +1,204 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (saturated arithmetic) + Invocation: dune exec src/proto_alpha/lib_protocol/test/unit/main.exe \ + -- test "^\[Unit\] sc rollup arith$" + Subject: Basic testing of the arithmetic rollup example +*) + +open Protocol +open Sc_rollup_arith.ProtocolImplementation +open Alpha_context + +let create_context () = + Context.init 1 >>=? fun (block, _) -> return block.context + +let setup boot_sector f = + create_context () >>=? fun ctxt -> + initial_state ctxt boot_sector >>= fun state -> f state + +let pre_boot boot_sector f = + parse_boot_sector boot_sector |> function + | None -> failwith "Invalid boot sector" + | Some boot_sector -> setup boot_sector @@ f + +let test_preboot () = + [""; "1"; "1 2 +"] + |> List.iter_es (fun boot_sector -> + pre_boot boot_sector @@ fun _state -> return ()) + +let boot boot_sector f = pre_boot boot_sector @@ fun state -> eval state >>= f + +let test_boot () = + boot "" @@ fun state -> + is_input_state state >>= function + | Some _ -> return () + | _ -> failwith "After booting, the machine must be waiting for input." + +let test_input_message () = + boot "" @@ fun state -> + let input = + { + inbox_level = Raw_level.root; + message_counter = Z.zero; + payload = "MESSAGE"; + } + in + set_input input state >>= fun state -> + eval state >>= fun state -> + is_input_state state >>= function + | Some _ -> + failwith + "After receiving a message, the rollup must not be waiting for input." + | None -> return () + +let go ~max_steps target_status state = + let rec aux i state = + pp state >>= fun pp -> + Format.eprintf "%a" pp () ; + if i > max_steps then + failwith "Maximum number of steps reached before target status." + else + get_status state >>= fun current_status -> + if target_status = current_status then return state + else eval state >>= aux (i + 1) + in + aux 0 state + +let test_parsing_message ~valid (source, expected_code) = + boot "" @@ fun state -> + let input = + {inbox_level = Raw_level.root; message_counter = Z.zero; payload = source} + in + set_input input state >>= fun state -> + eval state >>= fun state -> + go ~max_steps:10000 Evaluating state >>=? fun state -> + get_parsing_result state >>= fun result -> + Assert.equal + ~loc:__LOC__ + (Option.equal Bool.equal) + "Unexpected parsing resutlt" + (fun fmt r -> + Format.fprintf + fmt + (match r with + | None -> "No parsing running" + | Some true -> "Syntax correct" + | Some false -> "Syntax error")) + (Some valid) + result + >>=? fun () -> + if valid then + get_code state >>= fun code -> + Assert.equal + ~loc:__LOC__ + (List.equal equal_instruction) + "The parsed code is not what we expected: " + (Format.pp_print_list pp_instruction) + expected_code + code + else return () + +let syntactically_valid_messages = + List.map + (fun nums -> + ( String.concat " " (List.map string_of_int nums), + List.map (fun x -> IPush x) nums )) + [[0]; [42]; [373]; [0; 1]; [0; 123; 42; 73; 34; 13; 31]] + @ [ + ("1 2 +", [IPush 1; IPush 2; IAdd]); + ( "1 2 3 + + 3 +", + [IPush 1; IPush 2; IPush 3; IAdd; IAdd; IPush 3; IAdd] ); + ("1 2+", [IPush 1; IPush 2; IAdd]); + ("1 2 3++3+", [IPush 1; IPush 2; IPush 3; IAdd; IAdd; IPush 3; IAdd]); + ("", []); + ] + +let syntactically_invalid_messages = + List.map (fun s -> (s, [])) ["a"; " a"; " a "; "---"; "12 +++ --"] + +let test_parsing_messages () = + List.iter_es (test_parsing_message ~valid:true) syntactically_valid_messages + >>=? fun () -> + List.iter_es + (test_parsing_message ~valid:false) + syntactically_invalid_messages + +let test_evaluation_message ~valid (boot_sector, source, expected_stack) = + boot boot_sector @@ fun state -> + let input = + {inbox_level = Raw_level.root; message_counter = Z.zero; payload = source} + in + set_input input state >>= fun state -> + eval state >>= fun state -> + go ~max_steps:10000 WaitingForInputMessage state >>=? fun state -> + if valid then + get_stack state >>= fun stack -> + Assert.equal + ~loc:__LOC__ + (List.equal Compare.Int.equal) + "The stack is not what we expected: " + Format.(pp_print_list (fun fmt -> fprintf fmt "%d;@;")) + expected_stack + stack + else + get_evaluation_result state >>= function + | Some true -> failwith "This code should lead to an evaluation error." + | None -> failwith "We should have reached the evaluation end." + | Some false -> return () + +let valid_messages = + [ + ("", "0", [0]); + ("", "1 2", [2; 1]); + ("", "1 2 +", [3]); + ("", "1 2 + 3 +", [6]); + ("", "1 2 + 3 + 1 1 + +", [8]); + ("0 ", "", [0]); + ("1 ", "2", [2; 1]); + ("1 2 ", "+", [3]); + ("1 2 + ", "3 +", [6]); + ("1 2 + ", "3 + 1 1 + +", [8]); + ] + +let invalid_messages = + List.map (fun s -> ("", s, [])) ["+"; "1 +"; "1 1 + +"; "1 1 + 1 1 + + +"] + +let test_evaluation_messages () = + List.iter_es (test_evaluation_message ~valid:true) valid_messages + >>=? fun () -> + List.iter_es (test_evaluation_message ~valid:false) invalid_messages + +let tests = + [ + Tztest.tztest "PreBoot" `Quick test_preboot; + Tztest.tztest "Boot" `Quick test_boot; + Tztest.tztest "Input message" `Quick test_input_message; + Tztest.tztest "Parsing message" `Quick test_parsing_messages; + Tztest.tztest "Evaluating message" `Quick test_evaluation_messages; + ] From 11fa1d5d762bd4a19aff41de2e5ba269093158c1 Mon Sep 17 00:00:00 2001 From: Yann Regis-Gianas Date: Mon, 14 Mar 2022 18:22:48 +0100 Subject: [PATCH 046/100] Proto,SCORU: Add proof start/end state hash Signed-off-by: Yann Regis-Gianas --- src/proto_alpha/lib_protocol/sc_rollup_PVM_sem.ml | 8 ++++++++ src/proto_alpha/lib_protocol/sc_rollup_arith.ml | 4 ++++ 2 files changed, 12 insertions(+) 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 42d275b009..0397854c8c 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_PVM_sem.ml +++ b/src/proto_alpha/lib_protocol/sc_rollup_PVM_sem.ml @@ -70,6 +70,14 @@ module type S = sig (** A commitment hash characterized the contents of the state. *) type hash = State_hash.t + (** [proof_start_state proof] returns the initial state hash of the + [proof] execution step. *) + val proof_start_state : proof -> hash + + (** [proof_stop_state proof] returns the final state hash of the + [proof] execution step. *) + val proof_stop_state : proof -> hash + (** [state_hash state] returns a compressed representation of [state]. *) val state_hash : state -> hash Lwt.t diff --git a/src/proto_alpha/lib_protocol/sc_rollup_arith.ml b/src/proto_alpha/lib_protocol/sc_rollup_arith.ml index 97c1194780..ea2ca32b53 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_arith.ml +++ b/src/proto_alpha/lib_protocol/sc_rollup_arith.ml @@ -95,6 +95,10 @@ module Make (Context : P) : S with type context = Context.Tree.t = struct let proof_encoding = Context.proof_encoding + let proof_start_state = Context.proof_start_state + + let proof_stop_state = Context.proof_stop_state + let name = "arith" let parse_boot_sector s = Some (PVM.boot_sector_of_string s) From c3b9239242306b7a968fe5d8795d56971fa8d5d1 Mon Sep 17 00:00:00 2001 From: Yann Regis-Gianas Date: Tue, 15 Mar 2022 11:53:33 +0100 Subject: [PATCH 047/100] Proto,SCORU: Remove abstraction of boot_sector type Signed-off-by: Yann Regis-Gianas --- .../lib_client/client_proto_context.mli | 2 +- .../lib_protocol/alpha_context.mli | 14 ++------------ .../lib_protocol/operation_repr.ml | 4 ++-- .../lib_protocol/operation_repr.mli | 2 +- .../lib_protocol/sc_rollup_PVM_sem.ml | 2 +- .../lib_protocol/sc_rollup_arith.ml | 19 +++++++++---------- .../lib_protocol/sc_rollup_arith.mli | 4 ++-- .../lib_protocol/sc_rollup_operations.mli | 2 +- .../lib_protocol/sc_rollup_repr.ml | 10 ---------- .../lib_protocol/sc_rollup_repr.mli | 10 ---------- .../lib_protocol/sc_rollup_storage.ml | 4 +--- .../lib_protocol/sc_rollup_storage.mli | 6 +++--- src/proto_alpha/lib_protocol/sc_rollups.ml | 2 +- src/proto_alpha/lib_protocol/sc_rollups.mli | 2 +- src/proto_alpha/lib_protocol/storage.ml | 4 ++-- src/proto_alpha/lib_protocol/storage.mli | 2 +- .../lib_protocol/test/helpers/op.mli | 2 +- .../integration/operations/test_sc_rollup.ml | 2 +- .../test/unit/test_sc_rollup_storage.ml | 5 +---- 19 files changed, 31 insertions(+), 67 deletions(-) diff --git a/src/proto_alpha/lib_client/client_proto_context.mli b/src/proto_alpha/lib_client/client_proto_context.mli index fa2ca61284..effd467ea0 100644 --- a/src/proto_alpha/lib_client/client_proto_context.mli +++ b/src/proto_alpha/lib_client/client_proto_context.mli @@ -589,7 +589,7 @@ val sc_rollup_originate : ?counter:counter -> source:public_key_hash -> kind:Sc_rollup.Kind.t -> - boot_sector:Sc_rollup.PVM.boot_sector -> + boot_sector:string -> src_pk:public_key -> src_sk:Client_keys.sk_uri -> fee_parameter:Injection.fee_parameter -> diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index 1e237890d0..0b48f65763 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -2419,16 +2419,6 @@ module Sc_rollup : sig module Map : Map.S with type key = t end - module PVM : sig - type boot_sector - - val boot_sector_encoding : boot_sector Data_encoding.t - - val boot_sector_of_string : string -> boot_sector - - val boot_sector_to_string : boot_sector -> string - end - module Address : S.HASH type t = Address.t @@ -2467,7 +2457,7 @@ module Sc_rollup : sig val originate : context -> kind:Kind.t -> - boot_sector:PVM.boot_sector -> + boot_sector:string -> (t * Z.t * context) tzresult Lwt.t val kind : context -> t -> Kind.t option tzresult Lwt.t @@ -2884,7 +2874,7 @@ and _ manager_operation = -> Kind.tx_rollup_withdraw manager_operation | Sc_rollup_originate : { kind : Sc_rollup.Kind.t; - boot_sector : Sc_rollup.PVM.boot_sector; + boot_sector : string; } -> Kind.sc_rollup_originate manager_operation | Sc_rollup_add_messages : { diff --git a/src/proto_alpha/lib_protocol/operation_repr.ml b/src/proto_alpha/lib_protocol/operation_repr.ml index 8d7642089c..468e530e92 100644 --- a/src/proto_alpha/lib_protocol/operation_repr.ml +++ b/src/proto_alpha/lib_protocol/operation_repr.ml @@ -341,7 +341,7 @@ and _ manager_operation = -> Kind.tx_rollup_withdraw manager_operation | Sc_rollup_originate : { kind : Sc_rollup_repr.Kind.t; - boot_sector : Sc_rollup_repr.PVM.boot_sector; + boot_sector : string; } -> Kind.sc_rollup_originate manager_operation | Sc_rollup_add_messages : { @@ -847,7 +847,7 @@ module Encoding = struct encoding = obj2 (req "kind" Sc_rollup_repr.Kind.encoding) - (req "boot_sector" Sc_rollup_repr.PVM.boot_sector_encoding); + (req "boot_sector" Data_encoding.string); select = (function | Manager (Sc_rollup_originate _ as op) -> Some op | _ -> None); diff --git a/src/proto_alpha/lib_protocol/operation_repr.mli b/src/proto_alpha/lib_protocol/operation_repr.mli index f9a994e90e..e86162b789 100644 --- a/src/proto_alpha/lib_protocol/operation_repr.mli +++ b/src/proto_alpha/lib_protocol/operation_repr.mli @@ -409,7 +409,7 @@ and _ manager_operation = sector). *) | Sc_rollup_originate : { kind : Sc_rollup_repr.Kind.t; - boot_sector : Sc_rollup_repr.PVM.boot_sector; + boot_sector : string; } -> Kind.sc_rollup_originate manager_operation (* [Sc_rollup_add_messages] adds messages to a given rollup's 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 0397854c8c..067250b4ea 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_PVM_sem.ml +++ b/src/proto_alpha/lib_protocol/sc_rollup_PVM_sem.ml @@ -84,7 +84,7 @@ module type S = sig (** [initial_state context] is the state of the PVM before booting. It must be such that [state_hash state = Commitment_hash.zero]. Any [context] should be enough to create an initial state. *) - val initial_state : context -> PVM.boot_sector -> state Lwt.t + val initial_state : context -> string -> state Lwt.t (** [is_input_state state] returns [Some (level, counter)] if [state] is waiting for the input message that comes next to the message numbered diff --git a/src/proto_alpha/lib_protocol/sc_rollup_arith.ml b/src/proto_alpha/lib_protocol/sc_rollup_arith.ml index ea2ca32b53..299f364362 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_arith.ml +++ b/src/proto_alpha/lib_protocol/sc_rollup_arith.ml @@ -55,9 +55,9 @@ module type S = sig val name : string - val parse_boot_sector : string -> Sc_rollup.PVM.boot_sector option + val parse_boot_sector : string -> string option - val pp_boot_sector : Format.formatter -> Sc_rollup.PVM.boot_sector -> unit + val pp_boot_sector : Format.formatter -> string -> unit val pp : state -> (Format.formatter -> unit -> unit) Lwt.t @@ -101,10 +101,9 @@ module Make (Context : P) : S with type context = Context.Tree.t = struct let name = "arith" - let parse_boot_sector s = Some (PVM.boot_sector_of_string s) + let parse_boot_sector s = Some s - let pp_boot_sector fmt s = - Format.fprintf fmt "%s" (PVM.boot_sector_to_string s) + let pp_boot_sector fmt s = Format.fprintf fmt "%s" s type tree = Tree.tree @@ -382,15 +381,15 @@ module Make (Context : P) : S with type context = Context.Tree.t = struct end) module Boot_sector = MakeVar (struct - type t = PVM.boot_sector + type t = string let name = "boot_sector" - let initial = PVM.boot_sector_of_string "" + let initial = "" - let encoding = PVM.boot_sector_encoding + let encoding = Data_encoding.string - let pp fmt s = Format.fprintf fmt "%s" (PVM.boot_sector_to_string s) + let pp fmt s = Format.fprintf fmt "%s" s end) module Status = MakeVar (struct @@ -639,7 +638,7 @@ module Make (Context : P) : S with type context = Context.Tree.t = struct let set_input_monadic {inbox_level; message_counter; payload} = let open Monad.Syntax in let* boot_sector = Boot_sector.get in - let msg = PVM.boot_sector_to_string boot_sector ^ payload in + let msg = boot_sector ^ payload in let* last_level = CurrentLevel.get in let* last_counter = MessageCounter.get in let update = diff --git a/src/proto_alpha/lib_protocol/sc_rollup_arith.mli b/src/proto_alpha/lib_protocol/sc_rollup_arith.mli index e3dda85c1f..cb3fc4bfbd 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_arith.mli +++ b/src/proto_alpha/lib_protocol/sc_rollup_arith.mli @@ -60,11 +60,11 @@ module type S = sig (** [parse_boot_sector s] builds a boot sector from its human writable description. *) - val parse_boot_sector : string -> Sc_rollup.PVM.boot_sector option + val parse_boot_sector : string -> string option (** [pp_boot_sector fmt s] prints a human readable representation of a boot sector. *) - val pp_boot_sector : Format.formatter -> Sc_rollup.PVM.boot_sector -> unit + val pp_boot_sector : Format.formatter -> string -> unit (** [pp state] returns a pretty-printer valid for [state]. *) val pp : state -> (Format.formatter -> unit -> unit) Lwt.t diff --git a/src/proto_alpha/lib_protocol/sc_rollup_operations.mli b/src/proto_alpha/lib_protocol/sc_rollup_operations.mli index d5c5b2fcfd..c050eb81ae 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_operations.mli +++ b/src/proto_alpha/lib_protocol/sc_rollup_operations.mli @@ -33,5 +33,5 @@ type origination_result = {address : Sc_rollup.Address.t; size : Z.t} val originate : context -> kind:Sc_rollup.Kind.t -> - boot_sector:Sc_rollup.PVM.boot_sector -> + boot_sector:string -> (origination_result * context) tzresult Lwt.t diff --git a/src/proto_alpha/lib_protocol/sc_rollup_repr.ml b/src/proto_alpha/lib_protocol/sc_rollup_repr.ml index 431d7474d0..ebebb4eae4 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_repr.ml +++ b/src/proto_alpha/lib_protocol/sc_rollup_repr.ml @@ -24,16 +24,6 @@ (* *) (*****************************************************************************) -module PVM = struct - type boot_sector = string - - let boot_sector_encoding = Data_encoding.string - - let boot_sector_of_string s = s - - let boot_sector_to_string s = s -end - module Address = struct let prefix = "scr1" diff --git a/src/proto_alpha/lib_protocol/sc_rollup_repr.mli b/src/proto_alpha/lib_protocol/sc_rollup_repr.mli index 70b6f7caa2..f9c49c2b01 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_repr.mli +++ b/src/proto_alpha/lib_protocol/sc_rollup_repr.mli @@ -39,16 +39,6 @@ as well as the potentially-disputed operations. *) -module PVM : sig - (** A PVM instance can be initialized by setting a boot sector. *) - type boot_sector - - val boot_sector_encoding : boot_sector Data_encoding.t - - val boot_sector_of_string : string -> boot_sector - - val boot_sector_to_string : boot_sector -> string -end (** A smart-contract rollup has an address starting with "scr1". *) module Address : sig diff --git a/src/proto_alpha/lib_protocol/sc_rollup_storage.ml b/src/proto_alpha/lib_protocol/sc_rollup_storage.ml index 5fe839433a..98eb0fb8a2 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_storage.ml +++ b/src/proto_alpha/lib_protocol/sc_rollup_storage.ml @@ -227,9 +227,7 @@ let originate ctxt ~kind ~boot_sector = let addresses_size = 2 * Sc_rollup_repr.Address.size in let stored_kind_size = 2 (* because tag_size of kind encoding is 16bits. *) in let boot_sector_size = - Data_encoding.Binary.length - Sc_rollup_repr.PVM.boot_sector_encoding - boot_sector + Data_encoding.Binary.length Data_encoding.string boot_sector in let origination_size = Constants_storage.sc_rollup_origination_size ctxt in let size = diff --git a/src/proto_alpha/lib_protocol/sc_rollup_storage.mli b/src/proto_alpha/lib_protocol/sc_rollup_storage.mli index 5a04b76350..efaab6709c 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_storage.mli +++ b/src/proto_alpha/lib_protocol/sc_rollup_storage.mli @@ -151,7 +151,7 @@ type error += val originate : Raw_context.t -> kind:Sc_rollup_repr.Kind.t -> - boot_sector:Sc_rollup_repr.PVM.boot_sector -> + boot_sector:string -> (Sc_rollup_repr.Address.t * Z.t * Raw_context.t) tzresult Lwt.t (** [kind context address] returns [Some kind] iff [address] is an @@ -228,7 +228,7 @@ val withdraw_stake : commitments and {i staking on existing commitments}. The storage of commitments is content-addressable to minimize storage duplication. - Subsequent calls to [refine_stake] and [cement_commitment] must use + Subsequent calls to [refine_stake] and [cement_commitment] must use a [context] with greater level, or behavior is undefined. The first time a commitment hash is staked on, it is assigned a deadline, @@ -277,7 +277,7 @@ val last_cemented_commitment : (** [cement_commitment context rollup commitment] cements the given commitment. - Subsequent calls to [refine_stake] and [cement_commitment] must use + Subsequent calls to [refine_stake] and [cement_commitment] must use a [context] with greater level, or behavior is undefined. For cementing to succeed, the following must hold: diff --git a/src/proto_alpha/lib_protocol/sc_rollups.ml b/src/proto_alpha/lib_protocol/sc_rollups.ml index e9ddbecf85..6383f16562 100644 --- a/src/proto_alpha/lib_protocol/sc_rollups.ml +++ b/src/proto_alpha/lib_protocol/sc_rollups.ml @@ -26,7 +26,7 @@ open Alpha_context.Sc_rollup module PVM = struct - type boot_sector = Alpha_context.Sc_rollup.PVM.boot_sector + type boot_sector = string module type S = sig val name : string diff --git a/src/proto_alpha/lib_protocol/sc_rollups.mli b/src/proto_alpha/lib_protocol/sc_rollups.mli index 8daea3f013..dc74b289ea 100644 --- a/src/proto_alpha/lib_protocol/sc_rollups.mli +++ b/src/proto_alpha/lib_protocol/sc_rollups.mli @@ -27,7 +27,7 @@ open Alpha_context.Sc_rollup module PVM : sig - type boot_sector = Alpha_context.Sc_rollup.PVM.boot_sector + type boot_sector = string module type S = sig val name : string diff --git a/src/proto_alpha/lib_protocol/storage.ml b/src/proto_alpha/lib_protocol/storage.ml index 4d52e2e945..d9b03f7b74 100644 --- a/src/proto_alpha/lib_protocol/storage.ml +++ b/src/proto_alpha/lib_protocol/storage.ml @@ -1549,9 +1549,9 @@ module Sc_rollup = struct let name = ["boot_sector"] end) (struct - type t = Sc_rollup_repr.PVM.boot_sector + type t = string - let encoding = Sc_rollup_repr.PVM.boot_sector_encoding + let encoding = Data_encoding.string end) module Initial_level = diff --git a/src/proto_alpha/lib_protocol/storage.mli b/src/proto_alpha/lib_protocol/storage.mli index e4829e067a..85cbaa74bf 100644 --- a/src/proto_alpha/lib_protocol/storage.mli +++ b/src/proto_alpha/lib_protocol/storage.mli @@ -720,7 +720,7 @@ module Sc_rollup : sig module Boot_sector : Indexed_data_storage with type key = Sc_rollup_repr.t - and type value = Sc_rollup_repr.PVM.boot_sector + and type value = string and type t := Raw_context.t module Initial_level : diff --git a/src/proto_alpha/lib_protocol/test/helpers/op.mli b/src/proto_alpha/lib_protocol/test/helpers/op.mli index 7b7e3cbb78..b4aa981b5e 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/op.mli +++ b/src/proto_alpha/lib_protocol/test/helpers/op.mli @@ -249,7 +249,7 @@ val sc_rollup_origination : Context.t -> Contract.t -> Sc_rollup.Kind.t -> - Sc_rollup.PVM.boot_sector -> + string -> packed_operation tzresult Lwt.t (** [tx_rollup_commit ctxt source tx_rollup commitment] Commits to a tx diff --git a/src/proto_alpha/lib_protocol/test/integration/operations/test_sc_rollup.ml b/src/proto_alpha/lib_protocol/test/integration/operations/test_sc_rollup.ml index 9183c97091..1e25f86abf 100644 --- a/src/proto_alpha/lib_protocol/test/integration/operations/test_sc_rollup.ml +++ b/src/proto_alpha/lib_protocol/test/integration/operations/test_sc_rollup.ml @@ -49,7 +49,7 @@ let test_disable_feature_flag () = in Incremental.begin_construction b >>=? fun i -> let kind = Sc_rollup.Kind.Example_arith in - let boot_sector = Sc_rollup.PVM.boot_sector_of_string "" in + let boot_sector = "" in Op.sc_rollup_origination (I i) contract kind boot_sector >>=? fun op -> let expect_failure = function | Environment.Ecoproto_error (Apply.Sc_rollup_feature_disabled as e) :: _ -> diff --git a/src/proto_alpha/lib_protocol/test/unit/test_sc_rollup_storage.ml b/src/proto_alpha/lib_protocol/test/unit/test_sc_rollup_storage.ml index 429157f666..c7e50d6b9f 100644 --- a/src/proto_alpha/lib_protocol/test/unit/test_sc_rollup_storage.ml +++ b/src/proto_alpha/lib_protocol/test/unit/test_sc_rollup_storage.ml @@ -48,10 +48,7 @@ let new_context () = let new_sc_rollup ctxt = let+ (rollup, _size, ctxt) = - Sc_rollup_storage.originate - ctxt - ~kind:Example_arith - ~boot_sector:(Sc_rollup_repr.PVM.boot_sector_of_string "") + Sc_rollup_storage.originate ctxt ~kind:Example_arith ~boot_sector:"" in (rollup, ctxt) From f84f5ed87dc562a5e879c2ed40b6fdbda7b2640b Mon Sep 17 00:00:00 2001 From: Arvid Jakobsson Date: Thu, 17 Feb 2022 11:14:45 +0100 Subject: [PATCH 048/100] Proto/Michelson: feature flag tx rollup addresses in elaboration --- .../lib_protocol/script_ir_translator.ml | 28 +++++--- .../lib_protocol/script_tc_errors.ml | 2 + .../script_tc_errors_registration.ml | 9 +++ .../lib_protocol/test/helpers/context.ml | 8 ++- .../lib_protocol/test/helpers/context.mli | 4 ++ .../tx_rollup_parse_comparable_type.tz | 7 ++ .../contracts/tx_rollup_parse_data.tz | 7 ++ .../contracts/tx_rollup_parse_type.tz | 3 + .../integration/operations/test_tx_rollup.ml | 66 +++++++++++++++++-- 9 files changed, 118 insertions(+), 16 deletions(-) create mode 100644 src/proto_alpha/lib_protocol/test/integration/operations/contracts/tx_rollup_parse_comparable_type.tz create mode 100644 src/proto_alpha/lib_protocol/test/integration/operations/contracts/tx_rollup_parse_data.tz create mode 100644 src/proto_alpha/lib_protocol/test/integration/operations/contracts/tx_rollup_parse_type.tz diff --git a/src/proto_alpha/lib_protocol/script_ir_translator.ml b/src/proto_alpha/lib_protocol/script_ir_translator.ml index a4ffaa7a2d..313f14a5ab 100644 --- a/src/proto_alpha/lib_protocol/script_ir_translator.ml +++ b/src/proto_alpha/lib_protocol/script_ir_translator.ml @@ -1139,8 +1139,10 @@ let[@coq_struct "ty"] rec parse_comparable_ty : check_type_annot loc annot >|? fun () -> (Ex_comparable_ty address_key, ctxt) | Prim (loc, T_tx_rollup_l2_address, [], annot) -> - check_type_annot loc annot >|? fun () -> - (Ex_comparable_ty tx_rollup_l2_address_key, ctxt) + if Constants.tx_rollup_enable ctxt then + check_type_annot loc annot >|? fun () -> + (Ex_comparable_ty tx_rollup_l2_address_key, ctxt) + else error @@ Tx_rollup_addresses_disabled loc | Prim ( loc, (( T_unit | T_never | T_int | T_nat | T_string | T_bytes | T_mutez @@ -1301,8 +1303,10 @@ let[@coq_axiom_with_reason "complex mutually recursive definition"] rec parse_ty | Prim (loc, T_address, [], annot) -> check_type_annot loc annot >|? fun () -> return ctxt address_t | Prim (loc, T_tx_rollup_l2_address, [], annot) -> - check_type_annot loc annot >|? fun () -> - return ctxt tx_rollup_l2_address_t + if Constants.tx_rollup_enable ctxt then + check_type_annot loc annot >|? fun () -> + return ctxt tx_rollup_l2_address_t + else error @@ Tx_rollup_addresses_disabled loc | Prim (loc, T_signature, [], annot) -> check_type_annot loc annot >|? fun () -> return ctxt signature_t | Prim (loc, T_operation, [], annot) -> @@ -2256,7 +2260,14 @@ let parse_chain_id ctxt : Script.node -> (Script_chain_id.t * context) tzresult | expr -> error @@ Invalid_kind (location expr, [String_kind; Bytes_kind], kind expr) -let parse_address ctxt : Script.node -> (address * context) tzresult = function +let parse_address ctxt : Script.node -> (address * context) tzresult = + let destination_allowed loc {destination; entrypoint} ctxt = + match destination with + | Destination.Tx_rollup _ when not (Constants.tx_rollup_enable ctxt) -> + error @@ Tx_rollup_addresses_disabled loc + | _ -> Ok ({destination; entrypoint}, ctxt) + in + function | Bytes (loc, bytes) as expr (* As unparsed with [Optimized]. *) -> ( Gas.consume ctxt Typecheck_costs.contract >>? fun ctxt -> match @@ -2264,7 +2275,8 @@ let parse_address ctxt : Script.node -> (address * context) tzresult = function Data_encoding.(tup2 Destination.encoding Entrypoint.value_encoding) bytes with - | Some (destination, entrypoint) -> Ok ({destination; entrypoint}, ctxt) + | Some (destination, entrypoint) -> + destination_allowed loc {destination; entrypoint} ctxt | None -> error @@ Invalid_syntactic_constant @@ -2279,8 +2291,8 @@ let parse_address ctxt : Script.node -> (address * context) tzresult = function Entrypoint.of_string_strict ~loc name >|? fun entrypoint -> (String.sub s 0 pos, entrypoint)) >>? fun (addr, entrypoint) -> - Destination.of_b58check addr >|? fun destination -> - ({destination; entrypoint}, ctxt) + Destination.of_b58check addr >>? fun destination -> + destination_allowed loc {destination; entrypoint} ctxt | expr -> error @@ Invalid_kind (location expr, [String_kind; Bytes_kind], kind expr) diff --git a/src/proto_alpha/lib_protocol/script_tc_errors.ml b/src/proto_alpha/lib_protocol/script_tc_errors.ml index b5a8728d55..6e5846a1e7 100644 --- a/src/proto_alpha/lib_protocol/script_tc_errors.ml +++ b/src/proto_alpha/lib_protocol/script_tc_errors.ml @@ -74,6 +74,8 @@ type error += Tx_rollup_bad_deposit_parameter of Script.location * Script.expr type error += Tx_rollup_invalid_ticket_amount of Z.t +type error += Tx_rollup_addresses_disabled of Script.location + (* Instruction typing errors *) type error += Fail_not_in_tail_position of Script.location diff --git a/src/proto_alpha/lib_protocol/script_tc_errors_registration.ml b/src/proto_alpha/lib_protocol/script_tc_errors_registration.ml index b47e420772..0b92547fd1 100644 --- a/src/proto_alpha/lib_protocol/script_tc_errors_registration.ml +++ b/src/proto_alpha/lib_protocol/script_tc_errors_registration.ml @@ -254,6 +254,15 @@ let () = (obj1 (req "requested_value" Data_encoding.z)) (function Tx_rollup_invalid_ticket_amount z -> Some z | _ -> None) (fun z -> Tx_rollup_invalid_ticket_amount z) ; + (* Tx rollup addresses disabled *) + register_error_kind + `Permanent + ~id:"michelson_v1.tx_rollup_addresses_disabled" + ~title:"Tx rollup addresses are disabled" + ~description:"Cannot parse a tx_rollup address as tx rollups are disabled." + (obj1 (req "location" Script.location_encoding)) + (function Tx_rollup_addresses_disabled loc -> Some loc | _ -> None) + (fun loc -> Tx_rollup_addresses_disabled loc) ; (* Duplicate entrypoint *) register_error_kind `Permanent diff --git a/src/proto_alpha/lib_protocol/test/helpers/context.ml b/src/proto_alpha/lib_protocol/test/helpers/context.ml index 4379c86254..543e15907f 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/context.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/context.ml @@ -386,7 +386,7 @@ let init1 ?rng_state ?commitments ?(initial_balances = []) ?consensus_threshold ?min_proposal_quorum ?level ?cost_per_byte ?liquidity_baking_subsidy ?endorsing_reward_per_slot ?baking_reward_bonus_per_slot ?baking_reward_fixed_portion ?origination_size ?blocks_per_cycle - ?cycles_per_voting_period () = + ?cycles_per_voting_period ?tx_rollup_enable ?sc_rollup_enable () = init ?rng_state ?commitments @@ -402,6 +402,8 @@ let init1 ?rng_state ?commitments ?(initial_balances = []) ?consensus_threshold ?origination_size ?blocks_per_cycle ?cycles_per_voting_period + ?tx_rollup_enable + ?sc_rollup_enable 1 >|=? function | (_, []) -> assert false @@ -411,7 +413,7 @@ let init2 ?rng_state ?commitments ?(initial_balances = []) ?consensus_threshold ?min_proposal_quorum ?level ?cost_per_byte ?liquidity_baking_subsidy ?endorsing_reward_per_slot ?baking_reward_bonus_per_slot ?baking_reward_fixed_portion ?origination_size ?blocks_per_cycle - ?cycles_per_voting_period () = + ?cycles_per_voting_period ?tx_rollup_enable ?sc_rollup_enable () = init ?rng_state ?commitments @@ -427,6 +429,8 @@ let init2 ?rng_state ?commitments ?(initial_balances = []) ?consensus_threshold ?origination_size ?blocks_per_cycle ?cycles_per_voting_period + ?tx_rollup_enable + ?sc_rollup_enable 2 >|=? function | (_, []) | (_, [_]) -> assert false diff --git a/src/proto_alpha/lib_protocol/test/helpers/context.mli b/src/proto_alpha/lib_protocol/test/helpers/context.mli index 8ac2f85a25..194116c765 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/context.mli +++ b/src/proto_alpha/lib_protocol/test/helpers/context.mli @@ -230,6 +230,8 @@ val init1 : ?origination_size:int -> ?blocks_per_cycle:int32 -> ?cycles_per_voting_period:int32 -> + ?tx_rollup_enable:bool -> + ?sc_rollup_enable:bool -> unit -> (Block.t * Alpha_context.Contract.t) tzresult Lwt.t @@ -250,6 +252,8 @@ val init2 : ?origination_size:int -> ?blocks_per_cycle:int32 -> ?cycles_per_voting_period:int32 -> + ?tx_rollup_enable:bool -> + ?sc_rollup_enable:bool -> unit -> (Block.t * Alpha_context.Contract.t * Alpha_context.Contract.t) tzresult Lwt.t diff --git a/src/proto_alpha/lib_protocol/test/integration/operations/contracts/tx_rollup_parse_comparable_type.tz b/src/proto_alpha/lib_protocol/test/integration/operations/contracts/tx_rollup_parse_comparable_type.tz new file mode 100644 index 0000000000..a14c478611 --- /dev/null +++ b/src/proto_alpha/lib_protocol/test/integration/operations/contracts/tx_rollup_parse_comparable_type.tz @@ -0,0 +1,7 @@ +parameter unit; +storage unit; +code { + DROP; + EMPTY_SET tx_rollup_l2_address; DROP; + UNIT; NIL operation; PAIR; + } diff --git a/src/proto_alpha/lib_protocol/test/integration/operations/contracts/tx_rollup_parse_data.tz b/src/proto_alpha/lib_protocol/test/integration/operations/contracts/tx_rollup_parse_data.tz new file mode 100644 index 0000000000..3955efd612 --- /dev/null +++ b/src/proto_alpha/lib_protocol/test/integration/operations/contracts/tx_rollup_parse_data.tz @@ -0,0 +1,7 @@ +parameter unit; +storage unit; +code { + DROP; + PUSH address "txr1YNMEtkj5Vkqsbdmt7xaxBTMRZjzS96UAi"; DROP; + UNIT; NIL operation; PAIR; + } diff --git a/src/proto_alpha/lib_protocol/test/integration/operations/contracts/tx_rollup_parse_type.tz b/src/proto_alpha/lib_protocol/test/integration/operations/contracts/tx_rollup_parse_type.tz new file mode 100644 index 0000000000..8756195f7f --- /dev/null +++ b/src/proto_alpha/lib_protocol/test/integration/operations/contracts/tx_rollup_parse_type.tz @@ -0,0 +1,3 @@ +parameter tx_rollup_l2_address; +storage unit; +code { DROP; UNIT; NIL operation; PAIR; } diff --git a/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml b/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml index e7c674fbf4..8c2625f969 100644 --- a/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml +++ b/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml @@ -55,6 +55,11 @@ let check_proto_error_f f t = equals [e]. *) let check_proto_error e t = check_proto_error_f (( = ) e) t +let is_implicit_exn x = + match Alpha_context.Contract.is_implicit x with + | Some x -> x + | None -> raise (Invalid_argument "is_implicit_exn") + (** [test_disable_feature_flag] try to originate a tx rollup with the feature flag is deactivated and check it fails *) let test_disable_feature_flag () = @@ -70,6 +75,60 @@ let test_disable_feature_flag () = op >>=? fun _i -> return_unit +(** [parsing_tests] try originating contracts using the + type [tx_rollup_l2_address], test that it only works + when rollups are enabled. + *) +let parsing_tests = + let test_origination ~tx_rollup_enable script_path initial_storage = + Context.init1 ~tx_rollup_enable () >>=? fun (b, contract) -> + Contract_helpers.originate_contract + script_path + initial_storage + contract + b + (is_implicit_exn contract) + >>= fun res -> + if not tx_rollup_enable then + Assert.error ~loc:__LOC__ res (function + | Environment.Ecoproto_error + (Script_tc_errors.Tx_rollup_addresses_disabled _) -> + true + | _ -> false) + else + match res with + | Ok _ -> return_unit + | Error err -> + Alcotest.fail + (Format.asprintf + "Unexpected failure when parsing %s: %a" + script_path + pp_print_trace + err) + in + List.concat_map + (fun (description, path) -> + [ + Tztest.tztest + (Format.asprintf + "Originating `%s` succeeds w/ tx rollups enabled" + description) + `Quick + (fun () -> test_origination ~tx_rollup_enable:true path "Unit"); + Tztest.tztest + (Format.asprintf + "Originating `%s` fails w/ tx rollups disabled" + description) + `Quick + (fun () -> test_origination ~tx_rollup_enable:false path "Unit"); + ]) + [ + ("deposit", "contracts/tx_rollup_deposit.tz"); + ("type", "contracts/tx_rollup_parse_type.tz"); + ("comparable_type", "contracts/tx_rollup_parse_comparable_type.tz"); + ("data", "contracts/tx_rollup_parse_data.tz"); + ] + let message_hash_testable : Tx_rollup_message.hash Alcotest.testable = Alcotest.testable Tx_rollup_message.pp_hash ( = ) @@ -182,11 +241,6 @@ let gen_l2_account () = let public_key = Bls12_381.Signature.MinPk.derive_pk secret_key in (secret_key, public_key, Tx_rollup_l2_address.of_bls_pk public_key) -let is_implicit_exn x = - match Alpha_context.Contract.is_implicit x with - | Some x -> x - | None -> raise (Invalid_argument "is_implicit_exn") - (** [make_ticket_key ty contents ticketer tx_rollup] computes the ticket hash of the ticket containing [contents] of type [ty], crafted by [ticketer] and owned by [tx_rollup]. *) @@ -2526,4 +2580,4 @@ let tests = test_too_many_commitments; Tztest.tztest "Test bond finalization" `Quick test_bond_finalization; ] - @ Withdraw.tests @ Rejection.tests + @ Withdraw.tests @ Rejection.tests @ parsing_tests From afc962789b1e0a57318df7042254310a95a6d3ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Proust?= Date: Mon, 14 Mar 2022 13:55:25 +0100 Subject: [PATCH 049/100] Docs: convert code to use `let*` rather than infix binders --- docs/developer/time_measurement_ppx.rst | 11 ++++++----- docs/doc_gen/node_helpers.ml | 25 ++++++++++++++----------- docs/doc_gen/rpc_doc.ml | 5 +++-- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/docs/developer/time_measurement_ppx.rst b/docs/developer/time_measurement_ppx.rst index 7690ec1fd4..7ff3c97077 100644 --- a/docs/developer/time_measurement_ppx.rst +++ b/docs/developer/time_measurement_ppx.rst @@ -26,9 +26,10 @@ the following OCaml function inside the module ``lib_my_module``: .. code-block:: OCaml let my_function () = + let open Lwt_syntax in let a = f () in let b = g () in - h () >>= fun c -> + let* c = h () in foo a b c Suppose also that module ``lib_my_module`` contains the following dune file: @@ -48,7 +49,7 @@ adding the following OCaml attributes: let my_function () = let a = f () [@time.duration f_time] in let b = g () [@time.duration g_time] in - h () >>= fun c -> + let* c = h () in foo a b c [@time.flush] ``[@time.duration]`` will be used to measure the time of ``f ()`` and ``g ()`` @@ -68,9 +69,9 @@ When the preprocessing will occur, the code will be transformed as follows: ("g_time", []) (fun () -> g ()) in - h () >>= fun c -> - foo a b c >>= fun __flush__id__0 -> - Tezos_time_measurement_runtime.Default.Time_measurement.flush () >|= fun () -> + let* c = h () in + let* __flush__id__0 = foo a b c in + let+ () = Tezos_time_measurement_runtime.Default.Time_measurement.flush () in __flush__id__0 Woah! What a mess... Let's see what this means. diff --git a/docs/doc_gen/node_helpers.ml b/docs/doc_gen/node_helpers.ml index 5751b7ac85..fba7e138aa 100644 --- a/docs/doc_gen/node_helpers.ml +++ b/docs/doc_gen/node_helpers.ml @@ -35,6 +35,7 @@ let genesis : Genesis.t = } let with_node f = + let open Lwt_result_syntax in let run dir = let ( / ) = Filename.concat in let node_config : Node.config = @@ -56,18 +57,20 @@ let with_node f = enable_testchain = false; } in - Node.create - ~singleprocess:true - node_config - Node.default_peer_validator_limits - Node.default_block_validator_limits - Node.default_prevalidator_limits - Node.default_chain_validator_limits - None - >>=? fun node -> - f node >>=? fun () -> return () + let* node = + Node.create + ~singleprocess:true + node_config + Node.default_peer_validator_limits + Node.default_block_validator_limits + Node.default_prevalidator_limits + Node.default_chain_validator_limits + None + in + f node in - Lwt_utils_unix.with_tempdir "tezos_rpcdoc_" run >>= function + let*! r = Lwt_utils_unix.with_tempdir "tezos_rpcdoc_" run in + match r with | Ok () -> Lwt.return_unit | Error err -> Format.eprintf "%a@." pp_print_trace err ; diff --git a/docs/doc_gen/rpc_doc.ml b/docs/doc_gen/rpc_doc.ml index b0f8f8b169..c6bcdc8b82 100644 --- a/docs/doc_gen/rpc_doc.ml +++ b/docs/doc_gen/rpc_doc.ml @@ -366,6 +366,7 @@ let pp_document ppf descriptions version = descriptions let make_index node required_version = + let open Lwt_syntax in let shell_dir = Node.build_rpc_directory node in let protocol_dirs = List.map @@ -402,10 +403,10 @@ let make_index node required_version = version = required_version) dirs in - RPC_directory.describe_directory ~recurse:true ~arg:() dir >>= fun dir -> + let* dir = RPC_directory.describe_directory ~recurse:true ~arg:() dir in let ppf = Format.std_formatter in pp_document ppf [(name, intro, path, dir)] required_version ; - return () + return_ok () let make_default_acl _node = let addr_of_string addr = P2p_point.Id.{addr; port = None; peer_id = None} in From 6e5933a1afe6a8d0f01dceb43b0e1550327d809e Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Fri, 11 Mar 2022 16:44:58 +0100 Subject: [PATCH 050/100] Tx_rollup,Proto: distinguish [Transfer] and [Withdraw] for type safety --- .../test/pbt/test_tx_rollup_l2_encoding.ml | 48 +++--- .../test/unit/test_tx_rollup_l2.ml | 99 ++++--------- .../test/unit/test_tx_rollup_l2_apply.ml | 138 +++++++++--------- .../lib_protocol/tx_rollup_l2_apply.ml | 31 ++-- .../lib_protocol/tx_rollup_l2_batch.ml | 102 ++++++------- .../lib_protocol/tx_rollup_l2_batch.mli | 29 ++-- tezt/tests/tx_rollup_node.ml | 6 +- 7 files changed, 197 insertions(+), 256 deletions(-) diff --git a/src/proto_alpha/lib_protocol/test/pbt/test_tx_rollup_l2_encoding.ml b/src/proto_alpha/lib_protocol/test/pbt/test_tx_rollup_l2_encoding.ml index 1795cf328f..2cfb6aaf1c 100644 --- a/src/proto_alpha/lib_protocol/test/pbt/test_tx_rollup_l2_encoding.ml +++ b/src/proto_alpha/lib_protocol/test/pbt/test_tx_rollup_l2_encoding.ml @@ -65,18 +65,27 @@ let l2_address_gen = let open QCheck2.Gen in Protocol.Tx_rollup_l2_address.of_bls_pk <$> bls_pk_gen +let idx_l2_address_idx_gen = + let open QCheck2.Gen in + from_index_exn <$> ui32 + +let idx_l2_address_value_gen = + let open QCheck2.Gen in + from_value <$> l2_address_gen + +let idx_l2_address_gen = + let open QCheck2.Gen in + oneof [idx_l2_address_idx_gen; idx_l2_address_value_gen] + let public_key_hash = Signature.Public_key_hash.of_b58check_exn "tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU" -let destination_gen = +let public_key_hash_gen = let open QCheck2.Gen in - let* choice = bool in - if choice then return (Layer1 public_key_hash) - else - let* choice = bool in - if choice then (fun x -> Layer2 (from_index_exn x)) <$> ui32 - else (fun x -> Layer2 (from_value x)) <$> l2_address_gen + let+ seed = seed_gen in + let (pkh, _, _) = Tx_rollup_l2_helpers.gen_l1_address ~seed () in + pkh let ticket_hash_gen : Protocol.Alpha_context.Ticket_hash.t QCheck2.Gen.t = let open QCheck2.Gen in @@ -107,17 +116,22 @@ let qty_gen = Protocol.Tx_rollup_l2_qty.of_int64_exn <$> graft_corners ui64 [0L; 1L; 2L; Int64.max_int] () -let v1_operation_content_gen = +let v1_withdraw_gen = let open QCheck2.Gen in - let* destination = destination_gen and+ qty = qty_gen in - (* in valid [operation_content]s, the ticket_hash is a value when the - destination is layer1 *) - let+ ticket_hash = - match destination with - | Layer1 _ -> idx_ticket_hash_value_gen - | Layer2 _ -> idx_ticket_hash_gen - in - V1.{destination; ticket_hash; qty} + let+ destination = public_key_hash_gen + and+ ticket_hash = ticket_hash_gen + and+ qty = qty_gen in + V1.Withdraw {destination; ticket_hash; qty} + +let v1_transfer_gen = + let open QCheck2.Gen in + let+ destination = idx_l2_address_gen + and+ ticket_hash = idx_ticket_hash_gen + and+ qty = qty_gen in + V1.Transfer {destination; ticket_hash; qty} + +let v1_operation_content_gen = + QCheck2.Gen.oneof [v1_withdraw_gen; v1_transfer_gen] let v1_operation_gen = let open QCheck2.Gen in diff --git a/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2.ml b/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2.ml index db4bd65ae5..054deb04b4 100644 --- a/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2.ml +++ b/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2.ml @@ -542,37 +542,42 @@ module Test_batch_encodings = struct let decode_transaction buffer = Binary.of_bytes_exn transaction_encoding buffer - let destination_pp fmt = - let open Protocol.Tx_rollup_l2_batch in - function - | Layer1 pkh -> Signature.Public_key_hash.pp fmt pkh - | Layer2 l2 -> Tx_rollup_l2_address.Indexable.pp fmt l2 - let operation_content_pp fmt = function - | {destination; ticket_hash; qty} -> + | Transfer {destination; ticket_hash; qty} -> Format.fprintf fmt - "@[Operation:@ destination=%a,@ ticket_hash=%a,@ qty:%a@]" - destination_pp + "@[Transfer:@ destination=%a,@ ticket_hash=%a,@ qty:%a@]" + Tx_rollup_l2_address.Indexable.pp destination Tx_rollup_l2_context_sig.Ticket_indexable.pp ticket_hash Tx_rollup_l2_qty.pp qty + | Withdraw {destination; ticket_hash; qty} -> + Format.fprintf + fmt + "@[Withdraw:@ destination=%a,@ ticket_hash=%a,@ qty:%a@]" + Signature.Public_key_hash.pp + destination + Alpha_context.Ticket_hash.pp + ticket_hash + Tx_rollup_l2_qty.pp + qty - let test_l2_operation_size () = - (* Assert the smallest operation_content size is 4 *) + let test_l2_transaction_size () = + (* Assert the smallest operation_content size is 5 *) let opc = - { - destination = Layer2 (Indexable.from_index_exn 0l); - ticket_hash = Indexable.from_index_exn 1l; - qty = Tx_rollup_l2_qty.of_int64_exn 12L; - } + Transfer + { + destination = Indexable.from_index_exn 0l; + ticket_hash = Indexable.from_index_exn 1l; + qty = Tx_rollup_l2_qty.of_int64_exn 12L; + } in let buffer = encode_content opc in let opc' = decode_content buffer in - Alcotest.(check int "smallest transfer content" 4 (Bytes.length buffer)) ; + Alcotest.(check int "smallest operation content" 4 (Bytes.length buffer)) ; assert (opc = opc') ; (* Assert the smallest operation size is 7 *) @@ -582,7 +587,7 @@ module Test_batch_encodings = struct let buffer = encode_operation op in let op' = decode_operation buffer in - Alcotest.(check int "smallest transfer" 7 (Bytes.length buffer)) ; + Alcotest.(check int "smallest operation" 7 (Bytes.length buffer)) ; assert (op = op') ; (* Assert the smallest transaction size is 8 *) @@ -595,66 +600,12 @@ module Test_batch_encodings = struct return_unit - let test_l2_operation_encode_guard () = - let invalid_indexed_l2_to_l1_op = - { - destination = Layer1 Signature.Public_key_hash.zero; - ticket_hash = Indexable.from_index_exn 1l; - qty = Tx_rollup_l2_qty.of_int64_exn 12L; - } - in - try - let buffer = encode_content invalid_indexed_l2_to_l1_op in - Alcotest.failf - "Expected encoding of layer2-to-layer1 operation_content with indexed \ - ticket to fail. Binary output: %s" - Hex.(of_bytes buffer |> show) - with - | Data_encoding.Binary.Write_error (Exception_raised_in_user_function _) -> - return_unit - | Data_encoding.Binary.Write_error e -> - Alcotest.failf - "Got unexpected exception Write_error: %a" - Binary.pp_write_error - e - | e -> Alcotest.failf "Got unexpected exception: %s" (Printexc.to_string e) - - let test_l2_operation_decode_guard () = - let invalid_indexed_l2_to_l1_op_serialized = - Hex.( - `Hex "00000000000000000000000000000000000000000000010c" |> to_bytes - |> Stdlib.Option.get) - in - try - let invalid_indexed_l2_to_l1_op = - decode_content invalid_indexed_l2_to_l1_op_serialized - in - Alcotest.failf - "Expected decoding of layer2-to-layer1 operation_content with indexed \ - ticket to fail. Got operation: %a" - operation_content_pp - invalid_indexed_l2_to_l1_op - with - | Data_encoding.Binary.Read_error (Exception_raised_in_user_function _) -> - return_unit - | Data_encoding.Binary.Read_error e -> - Alcotest.failf - "Got unexpected exception Read_error: %a" - Binary.pp_read_error - e - | e -> Alcotest.failf "Got unexpected exception: %s" (Printexc.to_string e) - let tests = [ - tztest "test layer-2 operation encoding size" `Quick test_l2_operation_size; - tztest - "test layer-2 operation encoding guard" - `Quick - test_l2_operation_encode_guard; tztest - "test layer-2 operation decoding guard" + "test layer-2 transaction encoding size" `Quick - test_l2_operation_decode_guard; + test_l2_transaction_size; ] end diff --git a/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml b/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml index ea5751cf5b..d8a0256e2e 100644 --- a/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml +++ b/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml @@ -258,15 +258,22 @@ let with_initial_setup tickets contracts = return (ctxt, tidxs, rev_contracts) -let transfer ?(counter = 1L) ~signer ~dest ~ticket qty = +let operation_content ?(counter = 1L) ~signer content = let open Tx_rollup_l2_batch.V1 in - let qty = Tx_rollup_l2_qty.of_int64_exn qty in - let content = {destination = dest; ticket_hash = from_value ticket; qty} in {signer = from_value signer; counter; contents = [content]} -let l1addr pkh = Tx_rollup_l2_batch.Layer1 pkh +let transfer ?counter ~signer ~dest ~ticket qty = + let qty = Tx_rollup_l2_qty.of_int64_exn qty in + let content = + Transfer + {destination = from_value dest; ticket_hash = from_value ticket; qty} + in + operation_content ?counter ~signer content -let l2addr addr = Tx_rollup_l2_batch.Layer2 (from_value addr) +let withdraw ?counter ~signer ~dest ~ticket qty = + let qty = Tx_rollup_l2_qty.of_int64_exn qty in + let content = Withdraw {destination = dest; ticket_hash = ticket; qty} in + operation_content ?counter ~signer content let transfers = List.map (fun (pk_source, dest, ticket, amount, counter) -> @@ -442,16 +449,16 @@ let test_indexes_creation () = (* We create a transaction for each transfer, it makes the test of each transaction result easier. *) let transaction1 = - [transfer ~counter:1L ~signer:pk1 ~dest:(l2addr addr2) ~ticket:ticket1 10L] + [transfer ~counter:1L ~signer:pk1 ~dest:addr2 ~ticket:ticket1 10L] in let signature1 = sign_transaction [sk1] transaction1 in let transaction2 = - [transfer ~counter:2L ~signer:pk1 ~dest:(l2addr addr3) ~ticket:ticket1 20L] + [transfer ~counter:2L ~signer:pk1 ~dest:addr3 ~ticket:ticket1 20L] in let signature2 = sign_transaction [sk1] transaction2 in let transaction3 = - [transfer ~counter:3L ~signer:pk1 ~dest:(l2addr addr4) ~ticket:ticket1 30L] + [transfer ~counter:3L ~signer:pk1 ~dest:addr4 ~ticket:ticket1 30L] in let signature3 = sign_transaction [sk1] transaction3 in let batch = @@ -495,19 +502,12 @@ let test_indexes_creation_bad () = let transaction1 = (* This transaction will fail because the number of tickets required is more than its own. *) - [ - transfer - ~counter:1L - ~signer:pk1 - ~dest:(l2addr addr2) - ~ticket:ticket1 - 10000L; - ] + [transfer ~counter:1L ~signer:pk1 ~dest:addr2 ~ticket:ticket1 10000L] in let signature1 = sign_transaction [sk1] transaction1 in let transaction2 = (* This is ok *) - [transfer ~counter:2L ~signer:pk1 ~dest:(l2addr addr3) ~ticket:ticket1 1L] + [transfer ~counter:2L ~signer:pk1 ~dest:addr3 ~ticket:ticket1 1L] in let signature2 = sign_transaction [sk1] transaction2 in @@ -556,10 +556,7 @@ let test_simple_l2_transaction () = [addr1] -> [addr2] & [addr2] -> [addr1]. *) let transaction = transfers - [ - (pk1, l2addr addr2, ticket1, 10L, None); - (pk2, l2addr addr1, ticket2, 20L, None); - ] + [(pk1, addr2, ticket1, 10L, None); (pk2, addr1, ticket2, 20L, None)] in let batch = create_batch_v1 [transaction] [[sk1; sk2]] in @@ -633,7 +630,8 @@ let test_simple_l1_transaction () = (* Then, we build a transaction with: [addr1] -> [pkh2] *) - let transaction = transfers [(pk1, l1addr pkh2, ticket1, 10L, None)] in + let withdraw = withdraw ~signer:pk1 ~dest:pkh2 ~ticket:ticket1 10L in + let transaction = [withdraw] in let batch = create_batch_v1 [transaction] [[sk1]] in let* (ctxt, Batch_result {results; _}, withdrawals) = @@ -681,7 +679,8 @@ let test_l1_transaction_inexistant_ticket () = let (_sk2, _pk2, _addr2, _idx2, pkh2) = nth_exn accounts 1 in (* We build an invalid transaction with: [addr1] -> [pkh2] *) - let transaction = transfers [(pk1, l1addr pkh2, ticket1, 10L, None)] in + let withdraw = withdraw ~signer:pk1 ~dest:pkh2 ~ticket:ticket1 10L in + let transaction = [withdraw] in let batch = create_batch_v1 [transaction] [[sk1]] in let* (_ctxt, Batch_result {results; _}, withdrawals) = @@ -718,7 +717,8 @@ let test_l1_transaction_inexistant_signer () = (* Then, we build an invalid transaction with: [pk_unknown] -> [pkh2] *) - let transaction = transfers [(pk_unknown, l1addr pkh2, ticket1, 10L, None)] in + let withdraw = withdraw ~signer:pk_unknown ~dest:pkh2 ~ticket:ticket1 10L in + let transaction = [withdraw] in let batch = create_batch_v1 [transaction] [[sk_unknown]] in let* (_ctxt, Batch_result {results; _}, withdrawals) = @@ -757,7 +757,8 @@ let test_l1_transaction_overdraft () = let tidx2 = nth_exn tidxs 1 in (* Then, we build an transaction with: [addr1] -> [pkh2] where addr1 attempts to spend too much*) - let transaction = transfers [(pk1, l1addr pkh2, ticket1, 30L, None)] in + let withdraw = withdraw ~signer:pk1 ~dest:pkh2 ~ticket:ticket1 30L in + let transaction = [withdraw] in let batch = create_batch_v1 [transaction] [[sk1]] in let* (ctxt, Batch_result {results; _}, withdrawals) = @@ -840,7 +841,8 @@ let test_l1_transaction_zero () = let tidx2 = nth_exn tidxs 1 in (* Then, we build an transaction with: [addr1] -> [pkh2] with amount 0 *) - let transaction = transfers [(pk1, l1addr pkh2, ticket1, 0L, None)] in + let withdraw = withdraw ~signer:pk1 ~dest:pkh2 ~ticket:ticket1 0L in + let transaction = [withdraw] in let batch = create_batch_v1 [transaction] [[sk1]] in let* (ctxt, Batch_result {results; _}, withdrawals) = @@ -917,7 +919,8 @@ let test_l1_transaction_partial () = let tidx2 = nth_exn tidxs 1 in (* Then, we build an transaction with: [addr1] -> [pkh2] , addr1 spending the ticket partially *) - let transaction = transfers [(pk1, l1addr pkh2, ticket1, 5L, None)] in + let withdraw = withdraw ~signer:pk1 ~dest:pkh2 ~ticket:ticket1 5L in + let transaction = [withdraw] in let batch = create_batch_v1 [transaction] [[sk1]] in let* (ctxt, Batch_result {results; _}, withdrawals) = @@ -1013,16 +1016,18 @@ let test_transaction_with_unknown_indexable () = counter = 1L; contents = [ - { - destination = Layer2 (forget aidx2); - ticket_hash = from_value ticket1; - qty = Tx_rollup_l2_qty.of_int64_exn 5L; - }; - { - destination = Layer2 (from_value addr2); - ticket_hash = forget tidx1; - qty = Tx_rollup_l2_qty.of_int64_exn 5L; - }; + Transfer + { + destination = forget aidx2; + ticket_hash = from_value ticket1; + qty = Tx_rollup_l2_qty.of_int64_exn 5L; + }; + Transfer + { + destination = from_value addr2; + ticket_hash = forget tidx1; + qty = Tx_rollup_l2_qty.of_int64_exn 5L; + }; ]; } in @@ -1032,16 +1037,18 @@ let test_transaction_with_unknown_indexable () = counter = 1L; contents = [ - { - destination = Layer2 (forget aidx1); - ticket_hash = from_value ticket2; - qty = Tx_rollup_l2_qty.of_int64_exn 10L; - }; - { - destination = Layer2 (from_value addr1); - ticket_hash = forget tidx2; - qty = Tx_rollup_l2_qty.of_int64_exn 10L; - }; + Transfer + { + destination = forget aidx1; + ticket_hash = from_value ticket2; + qty = Tx_rollup_l2_qty.of_int64_exn 10L; + }; + Transfer + { + destination = from_value addr1; + ticket_hash = forget tidx2; + qty = Tx_rollup_l2_qty.of_int64_exn 10L; + }; ]; } in @@ -1124,10 +1131,7 @@ let test_invalid_transaction () = [addr1] -> [addr2] & [addr2] -> [addr1]. *) let transaction = transfers - [ - (pk1, l2addr addr2, ticket1, 10L, None); - (pk2, l2addr addr1, ticket2, 20L, None); - ] + [(pk1, addr2, ticket1, 10L, None); (pk2, addr1, ticket2, 20L, None)] in let batch = create_batch_v1 [transaction] [[sk1; sk2]] in @@ -1175,9 +1179,7 @@ let test_invalid_counter () = let (sk1, pk1, addr1, _idx1, _) = nth_exn accounts 0 in let counter = 10L in - let transaction = - transfers [(pk1, l2addr addr2, ticket1, 10L, Some counter)] - in + let transaction = transfers [(pk1, addr2, ticket1, 10L, Some counter)] in let batch = create_batch_v1 [transaction] [[sk1]] in let* (_ctxt, Batch_result {results; _}, _withdrawals) = @@ -1207,11 +1209,11 @@ let test_update_counter () = let transactions = transfers [ - (pk1, l2addr addr2, ticket1, 10L, Some 1L); - (pk1, l2addr addr2, ticket1, 20L, Some 2L); - (pk1, l2addr addr2, ticket1, 30L, Some 3L); - (pk1, l2addr addr2, ticket1, 40L, Some 4L); - (pk1, l2addr addr2, ticket1, 50L, Some 5L); + (pk1, addr2, ticket1, 10L, Some 1L); + (pk1, addr2, ticket1, 20L, Some 2L); + (pk1, addr2, ticket1, 30L, Some 3L); + (pk1, addr2, ticket1, 40L, Some 4L); + (pk1, addr2, ticket1, 50L, Some 5L); ] |> List.map (fun x -> [x]) in @@ -1253,10 +1255,7 @@ let test_pre_apply_batch () = let transaction = transfers - [ - (pk1, l2addr addr2, ticket1, 10L, None); - (pk2, l2addr addr1, ticket2, 20L, None); - ] + [(pk1, addr2, ticket1, 10L, None); (pk2, addr1, ticket2, 20L, None)] in let batch1 = create_batch_v1 [transaction] [[sk1; sk2]] in let* (ctxt, _indexes, _) = Batch_V1.check_signature ctxt batch1 in @@ -1306,10 +1305,7 @@ let test_apply_message_batch () = [addr1] -> [addr2] & [addr2] -> [addr1]. *) let transaction = transfers - [ - (pk1, l2addr addr2, ticket1, 10L, None); - (pk2, l2addr addr1, ticket2, 20L, None); - ] + [(pk1, addr2, ticket1, 10L, None); (pk2, addr1, ticket2, 20L, None)] in let batch = create_batch_v1 [transaction] [[sk1; sk2]] in let (msg, _) = @@ -1350,10 +1346,10 @@ let test_apply_message_batch_withdrawals () = *) let transactions = [ - transfers [(pk1, l2addr addr2, ticket1, 5L, Some 1L)]; - transfers [(pk1, l1addr pkh2, ticket1, 5L, Some 2L)]; - transfers [(pk2, l2addr addr1, ticket2, 10L, Some 1L)]; - transfers [(pk2, l1addr pkh1, ticket2, 10L, Some 2L)]; + [transfer ~signer:pk1 ~dest:addr2 ~ticket:ticket1 ~counter:1L 5L]; + [withdraw ~signer:pk1 ~dest:pkh2 ~ticket:ticket1 ~counter:2L 5L]; + [transfer ~signer:pk2 ~dest:addr1 ~ticket:ticket2 ~counter:1L 10L]; + [withdraw ~signer:pk2 ~dest:pkh1 ~ticket:ticket2 ~counter:2L 10L]; ] in let batch = create_batch_v1 transactions [[sk1]; [sk1]; [sk2]; [sk2]] in diff --git a/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.ml b/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.ml index 5795dbf1a0..63c0812eea 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.ml @@ -561,9 +561,6 @@ module Make (Context : CONTEXT) = struct {ul {li The destination address index.} {li The ticket exchanged index.}} - - If the transfer is layer2-to-layer1, then it also returns - the resulting withdrawal. *) let apply_operation_content : ctxt -> @@ -571,19 +568,13 @@ module Make (Context : CONTEXT) = struct Signer_indexable.index -> 'content operation_content -> (ctxt * indexes * Tx_rollup_withdraw.withdrawal option) m = - fun ctxt indexes source_idx {destination; ticket_hash; qty} -> - match destination with - | Layer1 l1_dest -> - (* To withdraw, the ticket must be given in the form of a - value. Furthermore, the ticket must already exist in the + fun ctxt indexes source_idx op_content -> + match op_content with + | Withdraw {destination = claimer; ticket_hash; qty = amount} -> + (* To withdraw, the ticket must already exist in the rollup and be indexed (the ticket must have already been assigned an index in the content: otherwise the ticket has - not been seen before and we can't withdraw from - it). Therefore, we do not create any new associations in - the ticket index. *) - let*? ticket_hash = - Indexable.is_value_e ~error:Unexpectedly_indexed_ticket ticket_hash - in + not been seen before and we can't withdraw from it). *) let* tidx_opt = Ticket_index.get ctxt ticket_hash in let*? tidx = Option.value_e ~error:(Missing_ticket ticket_hash) tidx_opt @@ -591,13 +582,13 @@ module Make (Context : CONTEXT) = struct let source_idx = address_of_signer_index source_idx in (* spend the ticket -- this is responsible for checking that the source has the required balance *) - let* ctxt = Ticket_ledger.spend ctxt tidx source_idx qty in - let withdrawal = - Tx_rollup_withdraw.{claimer = l1_dest; ticket_hash; amount = qty} - in + let* ctxt = Ticket_ledger.spend ctxt tidx source_idx amount in + let withdrawal = Tx_rollup_withdraw.{claimer; ticket_hash; amount} in return (ctxt, indexes, Some withdrawal) - | Layer2 l2_dest -> - let* (ctxt, created_addr, dest_idx) = address_index ctxt l2_dest in + | Transfer {destination; ticket_hash; qty} -> + let* (ctxt, created_addr, dest_idx) = + address_index ctxt destination + in let* (ctxt, created_ticket, tidx) = ticket_index ctxt ticket_hash in let source_idx = address_of_signer_index source_idx in let* ctxt = transfer ctxt source_idx dest_idx tidx qty in diff --git a/src/proto_alpha/lib_protocol/tx_rollup_l2_batch.ml b/src/proto_alpha/lib_protocol/tx_rollup_l2_batch.ml index e51d0e7b4f..8e596d766e 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_l2_batch.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_l2_batch.ml @@ -39,21 +39,6 @@ let signer_encoding = | None -> Error "not a BLS public key") (Fixed.bytes Bls_signature.pk_size_in_bytes) -(* A version of Data_encoding.Compact.conv that can check an invariant - at encoding and decoding. - - It is used at runtime to enforce the invariant that transfers to L1 - accounts should reference tickets by value. - - TODO: does this makes sense? Wouldn't it be easier to have the - type of operation_content enforce this invariant? -*) -let with_coding_guard guard encoding = - let guard_conv x = - match guard x with Ok () -> x | Error s -> raise (Invalid_argument s) - in - Data_encoding.Compact.conv guard_conv guard_conv encoding - module Signer_indexable = Indexable.Make (struct type t = Bls_signature.pk @@ -65,32 +50,18 @@ module Signer_indexable = Indexable.Make (struct let encoding = signer_encoding end) -type 'status destination = - | Layer1 of Signature.Public_key_hash.t - | Layer2 of 'status Tx_rollup_l2_address.Indexable.t - -let compact_destination = - Data_encoding.Compact.( - union - [ - case - ~title:"layer1" - (payload Signature.Public_key_hash.encoding) - (function Layer1 x -> Some x | _ -> None) - (fun x -> Layer1 x); - case - ~title:"layer2" - (Indexable.compact Tx_rollup_l2_address.encoding) - (function Layer2 x -> Some x | _ -> None) - (fun x -> Layer2 x); - ]) - module V1 = struct - type 'status operation_content = { - destination : 'status destination; - ticket_hash : 'status Ticket_indexable.t; - qty : Tx_rollup_l2_qty.t; - } + type 'status operation_content = + | Withdraw of { + destination : Signature.Public_key_hash.t; + ticket_hash : Alpha_context.Ticket_hash.t; + qty : Tx_rollup_l2_qty.t; + } + | Transfer of { + destination : 'status Tx_rollup_l2_address.Indexable.t; + ticket_hash : 'status Ticket_indexable.t; + qty : Tx_rollup_l2_qty.t; + } type ('signer, 'content) operation = { signer : 'signer Signer_indexable.t; @@ -112,27 +83,36 @@ module V1 = struct (* --- [operation_content] *) let compact_operation_content = - Data_encoding.Compact.( - conv - (fun {destination; ticket_hash; qty} -> (destination, ticket_hash, qty)) - (fun (destination, ticket_hash, qty) -> {destination; ticket_hash; qty}) - @@ obj3 - (req "destination" compact_destination) - (req "ticket_hash" Ticket_indexable.compact) - (req "qty" Tx_rollup_l2_qty.compact_encoding)) - - let compact_operation_content = - with_coding_guard - (function - | {destination; ticket_hash; _} -> ( - match (destination, Indexable.destruct ticket_hash) with - | (Layer1 _, Left _) -> - (* Layer2-to-layer1 transfers must include the value of the ticket_hash *) - Result.error - "Attempted to decode layer2 operation containing ticket \ - index." - | _ -> Result.ok ())) - compact_operation_content + let open Data_encoding.Compact in + union + [ + case + ~title:"withdraw" + (obj3 + (req "destination" (payload Signature.Public_key_hash.encoding)) + (req "ticket_hash" (payload Alpha_context.Ticket_hash.encoding)) + (req "qty" Tx_rollup_l2_qty.compact_encoding)) + (function + | Withdraw {destination; ticket_hash; qty} -> + Some (destination, ticket_hash, qty) + | _ -> None) + (fun (destination, ticket_hash, qty) -> + Withdraw {destination; ticket_hash; qty}); + case + ~title:"transfer" + (obj3 + (req + "destination" + (Indexable.compact Tx_rollup_l2_address.encoding)) + (req "ticket_hash" Ticket_indexable.compact) + (req "qty" Tx_rollup_l2_qty.compact_encoding)) + (function + | Transfer {destination; ticket_hash; qty} -> + Some (destination, ticket_hash, qty) + | _ -> None) + (fun (destination, ticket_hash, qty) -> + Transfer {destination; ticket_hash; qty}); + ] let operation_content_encoding = Data_encoding.Compact.make ~tag_size compact_operation_content diff --git a/src/proto_alpha/lib_protocol/tx_rollup_l2_batch.mli b/src/proto_alpha/lib_protocol/tx_rollup_l2_batch.mli index 222b4111fe..40c902dcc3 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_l2_batch.mli +++ b/src/proto_alpha/lib_protocol/tx_rollup_l2_batch.mli @@ -86,21 +86,28 @@ end (** {1 Layer-2 Batches Definitions} *) -type 'status destination = - | Layer1 of Signature.Public_key_hash.t - | Layer2 of 'status Tx_rollup_l2_address.Indexable.t - -val compact_destination : Indexable.unknown destination Data_encoding.Compact.t - (** The operations are versioned, to let the possibility to propose new features in future iterations of the protocol. *) module V1 : sig - type 'status operation_content = { - destination : 'status destination; - ticket_hash : 'status Ticket_indexable.t; - qty : Tx_rollup_l2_qty.t; - } + type 'status operation_content = + | Withdraw of { + destination : Signature.Public_key_hash.t; + ticket_hash : Alpha_context.Ticket_hash.t; + qty : Tx_rollup_l2_qty.t; + } + (** A [Withdraw] removes [qty] of the tickets represented by + [ticket_hash] from the operation's signer in layer-2, and + permits [destination] to retrieve those tickets in layer-1 + through a [Tx_rollup_withdraw] operation. *) + | Transfer of { + destination : 'status Tx_rollup_l2_address.Indexable.t; + ticket_hash : 'status Ticket_indexable.t; + qty : Tx_rollup_l2_qty.t; + } + (** A [Transfer] moves [qty] of the tickets represented by + [ticket_hash] from the operation's signer in layer-2 to + [destination] in layer-2. *) type ('signer, 'content) operation = { signer : 'signer Signer_indexable.t; diff --git a/tezt/tests/tx_rollup_node.ml b/tezt/tests/tx_rollup_node.ml index 9716e5edeb..f52d07e6a8 100644 --- a/tezt/tests/tx_rollup_node.ml +++ b/tezt/tests/tx_rollup_node.ml @@ -423,13 +423,15 @@ let craft_tx ~counter ~signer ~dest ~ticket qty = let open Tezos_protocol_alpha.Protocol in let qty = Tx_rollup_l2_qty.of_int64_exn qty in let l2_addr = Tx_rollup_l2_address.of_b58check_exn dest in - let destination = Tx_rollup_l2_batch.Layer2 (Indexable.from_value l2_addr) in + let destination = Indexable.from_value l2_addr in let ticket_hash = Indexable.from_value (Tezos_protocol_alpha.Protocol.Alpha_context.Ticket_hash.of_b58check_exn ticket) in - let content = Tx_rollup_l2_batch.V1.{destination; ticket_hash; qty} in + let content = + Tx_rollup_l2_batch.V1.Transfer {destination; ticket_hash; qty} + in let signer = Indexable.from_value signer in Tx_rollup_l2_batch.V1.{signer; counter; contents = [content]} From 46cae048bef84afba1ec391ed4f172e2d1b21c94 Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Fri, 11 Mar 2022 17:30:03 +0100 Subject: [PATCH 051/100] Tx_rollup,Proto: allow signer field to be a layer2 address --- .../test/pbt/test_tx_rollup_l2_encoding.ml | 13 +- .../test/unit/test_tx_rollup_l2_apply.ml | 208 +++++++++++++++--- .../lib_protocol/tx_rollup_l2_apply.ml | 42 +++- .../lib_protocol/tx_rollup_l2_apply.mli | 1 + .../lib_protocol/tx_rollup_l2_batch.ml | 39 +++- .../lib_protocol/tx_rollup_l2_batch.mli | 17 +- tezt/tests/tx_rollup_node.ml | 2 +- 7 files changed, 270 insertions(+), 52 deletions(-) diff --git a/src/proto_alpha/lib_protocol/test/pbt/test_tx_rollup_l2_encoding.ml b/src/proto_alpha/lib_protocol/test/pbt/test_tx_rollup_l2_encoding.ml index 2cfb6aaf1c..82b32a3461 100644 --- a/src/proto_alpha/lib_protocol/test/pbt/test_tx_rollup_l2_encoding.ml +++ b/src/proto_alpha/lib_protocol/test/pbt/test_tx_rollup_l2_encoding.ml @@ -49,22 +49,23 @@ let bls_pk_gen = let secret_key = Bls12_381.Signature.generate_sk seed in Bls12_381.Signature.MinPk.derive_pk secret_key +let l2_address_gen = + let open QCheck2.Gen in + Protocol.Tx_rollup_l2_address.of_bls_pk <$> bls_pk_gen + let signer_gen : Signer_indexable.either QCheck2.Gen.t = let open QCheck2.Gen in frequency [ - (1, (fun pk -> from_value pk) <$> bls_pk_gen); - (9, (fun x -> from_index_exn x) <$> ui32); + (1, (fun pk -> from_value (Bls_pk pk)) <$> bls_pk_gen); + (5, (fun addr -> from_value (L2_addr addr)) <$> l2_address_gen); + (4, (fun x -> from_index_exn x) <$> ui32); ] let signer_index_gen : Signer_indexable.index QCheck2.Gen.t = let open QCheck2.Gen in (fun x -> Protocol.Indexable.index_exn x) <$> ui32 -let l2_address_gen = - let open QCheck2.Gen in - Protocol.Tx_rollup_l2_address.of_bls_pk <$> bls_pk_gen - let idx_l2_address_idx_gen = let open QCheck2.Gen in from_index_exn <$> ui32 diff --git a/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml b/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml index d8a0256e2e..cdf6202d0f 100644 --- a/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml +++ b/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml @@ -270,6 +270,10 @@ let transfer ?counter ~signer ~dest ~ticket qty = in operation_content ?counter ~signer content +let signer_pk x = Tx_rollup_l2_batch.Bls_pk x + +let signer_addr x = Tx_rollup_l2_batch.L2_addr x + let withdraw ?counter ~signer ~dest ~ticket qty = let qty = Tx_rollup_l2_qty.of_int64_exn qty in let content = Withdraw {destination = dest; ticket_hash = ticket; qty} in @@ -449,16 +453,37 @@ let test_indexes_creation () = (* We create a transaction for each transfer, it makes the test of each transaction result easier. *) let transaction1 = - [transfer ~counter:1L ~signer:pk1 ~dest:addr2 ~ticket:ticket1 10L] + [ + transfer + ~counter:1L + ~signer:(signer_pk pk1) + ~dest:addr2 + ~ticket:ticket1 + 10L; + ] in let signature1 = sign_transaction [sk1] transaction1 in let transaction2 = - [transfer ~counter:2L ~signer:pk1 ~dest:addr3 ~ticket:ticket1 20L] + [ + transfer + ~counter:2L + ~signer:(signer_pk pk1) + ~dest:addr3 + ~ticket:ticket1 + 20L; + ] in let signature2 = sign_transaction [sk1] transaction2 in let transaction3 = - [transfer ~counter:3L ~signer:pk1 ~dest:addr4 ~ticket:ticket1 30L] + [ + transfer + ~counter:3L + ~signer:(signer_pk pk1) + ~dest:addr4 + ~ticket:ticket1 + 30L; + ] in let signature3 = sign_transaction [sk1] transaction3 in let batch = @@ -502,12 +527,21 @@ let test_indexes_creation_bad () = let transaction1 = (* This transaction will fail because the number of tickets required is more than its own. *) - [transfer ~counter:1L ~signer:pk1 ~dest:addr2 ~ticket:ticket1 10000L] + [ + transfer + ~counter:1L + ~signer:(signer_pk pk1) + ~dest:addr2 + ~ticket:ticket1 + 10000L; + ] in let signature1 = sign_transaction [sk1] transaction1 in let transaction2 = (* This is ok *) - [transfer ~counter:2L ~signer:pk1 ~dest:addr3 ~ticket:ticket1 1L] + [ + transfer ~counter:2L ~signer:(signer_pk pk1) ~dest:addr3 ~ticket:ticket1 1L; + ] in let signature2 = sign_transaction [sk1] transaction2 in @@ -556,7 +590,10 @@ let test_simple_l2_transaction () = [addr1] -> [addr2] & [addr2] -> [addr1]. *) let transaction = transfers - [(pk1, addr2, ticket1, 10L, None); (pk2, addr1, ticket2, 20L, None)] + [ + (signer_pk pk1, addr2, ticket1, 10L, None); + (signer_pk pk2, addr1, ticket2, 20L, None); + ] in let batch = create_batch_v1 [transaction] [[sk1; sk2]] in @@ -615,6 +652,70 @@ let test_simple_l2_transaction () = | (Transaction_success, _) -> fail_msg "Did not expect any withdrawals" | (Transaction_failure _, _) -> fail_msg "The transaction should be a success" +(** Test that a signer can be layer2 address. *) +let test_l2_transaction_l2_addr_signer_good () = + let open Context_l2 in + let open Syntax in + let* (ctxt, _tidxs, accounts) = + with_initial_setup [] [[(ticket1, 10L)]; []] + in + let (sk1, pk1, addr1, idx1, _pkh1) = nth_exn accounts 0 in + let (_sk2, _pk2, addr2, _idx2, _pkh2) = nth_exn accounts 1 in + let* ctxt = Address_metadata.init_with_public_key ctxt idx1 pk1 in + let transfer = + [transfer ~signer:(signer_addr addr1) ~dest:addr2 ~ticket:ticket1 10L] + in + let signature = sign_transaction [sk1] transfer in + let batch = batch signature [transfer] in + let* (_ctxt, Batch_result {results; indexes = _}, _withdrawals) = + Batch_V1.apply_batch ctxt batch + in + let status = nth_exn results 0 in + match status with + | (_, Transaction_success) -> return_unit + | (_, Transaction_failure _) -> fail_msg "The transaction should be a success" + +(** Test that signing with a layer2 address needs a proper context. *) +let test_l2_transaction_l2_addr_signer_bad () = + let open Context_l2 in + let open Syntax in + let ctxt = empty_context in + let (sk1, pk1, addr1) = gen_l2_address () in + let (_sk2, _pk2, addr2) = gen_l2_address () in + (* The address has no index in the context *) + let transfer = + [transfer ~signer:(signer_addr addr1) ~dest:addr2 ~ticket:ticket1 10L] + in + let signature = sign_transaction [sk1] transfer in + let batch = batch signature [transfer] in + let* () = + expect_error + ~msg_if_valid:"The check should fail with an unknown address" + (Batch_V1.apply_batch ctxt batch) + (Tx_rollup_l2_apply.Unknown_address addr1) + in + (* Now we add the index but the metadata is still missing *) + let* (ctxt, _, idx1) = Address_index.get_or_associate_index ctxt addr1 in + let* () = + expect_error + ~msg_if_valid:"The check should fail with unknown metadata" + (Batch_V1.apply_batch ctxt batch) + (Tx_rollup_l2_apply.Unallocated_metadata 0l) + in + (* Finally we add the metadata and the test pass *) + let* ctxt = Address_metadata.init_with_public_key ctxt idx1 pk1 in + let* (ctxt, _, tidx) = Ticket_index.get_or_associate_index ctxt ticket1 in + let* ctxt = + Ticket_ledger.credit ctxt tidx idx1 (Tx_rollup_l2_qty.of_int64_exn 100L) + in + let* (_ctxt, Batch_result {results; indexes = _}, _withdrawals) = + Batch_V1.apply_batch ctxt batch + in + let status = nth_exn results 0 in + match status with + | (_, Transaction_success) -> return_unit + | (_, Transaction_failure _) -> fail_msg "The transaction should succeed" + (** The test consists of [pk1] sending [ticket1] to [pkh2]. This results in a withdrawal. *) let test_simple_l1_transaction () = @@ -630,7 +731,9 @@ let test_simple_l1_transaction () = (* Then, we build a transaction with: [addr1] -> [pkh2] *) - let withdraw = withdraw ~signer:pk1 ~dest:pkh2 ~ticket:ticket1 10L in + let withdraw = + withdraw ~signer:(signer_pk pk1) ~dest:pkh2 ~ticket:ticket1 10L + in let transaction = [withdraw] in let batch = create_batch_v1 [transaction] [[sk1]] in @@ -679,7 +782,9 @@ let test_l1_transaction_inexistant_ticket () = let (_sk2, _pk2, _addr2, _idx2, pkh2) = nth_exn accounts 1 in (* We build an invalid transaction with: [addr1] -> [pkh2] *) - let withdraw = withdraw ~signer:pk1 ~dest:pkh2 ~ticket:ticket1 10L in + let withdraw = + withdraw ~signer:(signer_pk pk1) ~dest:pkh2 ~ticket:ticket1 10L + in let transaction = [withdraw] in let batch = create_batch_v1 [transaction] [[sk1]] in @@ -717,7 +822,9 @@ let test_l1_transaction_inexistant_signer () = (* Then, we build an invalid transaction with: [pk_unknown] -> [pkh2] *) - let withdraw = withdraw ~signer:pk_unknown ~dest:pkh2 ~ticket:ticket1 10L in + let withdraw = + withdraw ~signer:(signer_pk pk_unknown) ~dest:pkh2 ~ticket:ticket1 10L + in let transaction = [withdraw] in let batch = create_batch_v1 [transaction] [[sk_unknown]] in @@ -757,7 +864,9 @@ let test_l1_transaction_overdraft () = let tidx2 = nth_exn tidxs 1 in (* Then, we build an transaction with: [addr1] -> [pkh2] where addr1 attempts to spend too much*) - let withdraw = withdraw ~signer:pk1 ~dest:pkh2 ~ticket:ticket1 30L in + let withdraw = + withdraw ~signer:(signer_pk pk1) ~dest:pkh2 ~ticket:ticket1 30L + in let transaction = [withdraw] in let batch = create_batch_v1 [transaction] [[sk1]] in @@ -841,7 +950,9 @@ let test_l1_transaction_zero () = let tidx2 = nth_exn tidxs 1 in (* Then, we build an transaction with: [addr1] -> [pkh2] with amount 0 *) - let withdraw = withdraw ~signer:pk1 ~dest:pkh2 ~ticket:ticket1 0L in + let withdraw = + withdraw ~signer:(signer_pk pk1) ~dest:pkh2 ~ticket:ticket1 0L + in let transaction = [withdraw] in let batch = create_batch_v1 [transaction] [[sk1]] in @@ -919,7 +1030,9 @@ let test_l1_transaction_partial () = let tidx2 = nth_exn tidxs 1 in (* Then, we build an transaction with: [addr1] -> [pkh2] , addr1 spending the ticket partially *) - let withdraw = withdraw ~signer:pk1 ~dest:pkh2 ~ticket:ticket1 5L in + let withdraw = + withdraw ~signer:(signer_pk pk1) ~dest:pkh2 ~ticket:ticket1 5L + in let transaction = [withdraw] in let batch = create_batch_v1 [transaction] [[sk1]] in @@ -1012,7 +1125,7 @@ let test_transaction_with_unknown_indexable () = let transfer1 : (Indexable.unknown, Indexable.unknown) operation = { - signer = from_value pk1; + signer = from_value (signer_pk pk1); counter = 1L; contents = [ @@ -1131,7 +1244,10 @@ let test_invalid_transaction () = [addr1] -> [addr2] & [addr2] -> [addr1]. *) let transaction = transfers - [(pk1, addr2, ticket1, 10L, None); (pk2, addr1, ticket2, 20L, None)] + [ + (signer_pk pk1, addr2, ticket1, 10L, None); + (signer_pk pk2, addr1, ticket2, 20L, None); + ] in let batch = create_batch_v1 [transaction] [[sk1; sk2]] in @@ -1179,7 +1295,9 @@ let test_invalid_counter () = let (sk1, pk1, addr1, _idx1, _) = nth_exn accounts 0 in let counter = 10L in - let transaction = transfers [(pk1, addr2, ticket1, 10L, Some counter)] in + let transaction = + transfers [(signer_pk pk1, addr2, ticket1, 10L, Some counter)] + in let batch = create_batch_v1 [transaction] [[sk1]] in let* (_ctxt, Batch_result {results; _}, _withdrawals) = @@ -1209,11 +1327,11 @@ let test_update_counter () = let transactions = transfers [ - (pk1, addr2, ticket1, 10L, Some 1L); - (pk1, addr2, ticket1, 20L, Some 2L); - (pk1, addr2, ticket1, 30L, Some 3L); - (pk1, addr2, ticket1, 40L, Some 4L); - (pk1, addr2, ticket1, 50L, Some 5L); + (signer_pk pk1, addr2, ticket1, 10L, Some 1L); + (signer_pk pk1, addr2, ticket1, 20L, Some 2L); + (signer_pk pk1, addr2, ticket1, 30L, Some 3L); + (signer_pk pk1, addr2, ticket1, 40L, Some 4L); + (signer_pk pk1, addr2, ticket1, 50L, Some 5L); ] |> List.map (fun x -> [x]) in @@ -1255,7 +1373,10 @@ let test_pre_apply_batch () = let transaction = transfers - [(pk1, addr2, ticket1, 10L, None); (pk2, addr1, ticket2, 20L, None)] + [ + (signer_pk pk1, addr2, ticket1, 10L, None); + (signer_pk pk2, addr1, ticket2, 20L, None); + ] in let batch1 = create_batch_v1 [transaction] [[sk1; sk2]] in let* (ctxt, _indexes, _) = Batch_V1.check_signature ctxt batch1 in @@ -1305,7 +1426,10 @@ let test_apply_message_batch () = [addr1] -> [addr2] & [addr2] -> [addr1]. *) let transaction = transfers - [(pk1, addr2, ticket1, 10L, None); (pk2, addr1, ticket2, 20L, None)] + [ + (signer_pk pk1, addr2, ticket1, 10L, None); + (signer_pk pk2, addr1, ticket2, 20L, None); + ] in let batch = create_batch_v1 [transaction] [[sk1; sk2]] in let (msg, _) = @@ -1346,10 +1470,38 @@ let test_apply_message_batch_withdrawals () = *) let transactions = [ - [transfer ~signer:pk1 ~dest:addr2 ~ticket:ticket1 ~counter:1L 5L]; - [withdraw ~signer:pk1 ~dest:pkh2 ~ticket:ticket1 ~counter:2L 5L]; - [transfer ~signer:pk2 ~dest:addr1 ~ticket:ticket2 ~counter:1L 10L]; - [withdraw ~signer:pk2 ~dest:pkh1 ~ticket:ticket2 ~counter:2L 10L]; + [ + transfer + ~signer:(signer_pk pk1) + ~dest:addr2 + ~ticket:ticket1 + ~counter:1L + 5L; + ]; + [ + withdraw + ~signer:(signer_pk pk1) + ~dest:pkh2 + ~ticket:ticket1 + ~counter:2L + 5L; + ]; + [ + transfer + ~signer:(signer_pk pk2) + ~dest:addr1 + ~ticket:ticket2 + ~counter:1L + 10L; + ]; + [ + withdraw + ~signer:(signer_pk pk2) + ~dest:pkh1 + ~ticket:ticket2 + ~counter:2L + 10L; + ]; ] in let batch = create_batch_v1 transactions [[sk1]; [sk1]; [sk2]; [sk2]] in @@ -1497,6 +1649,10 @@ let tests = ("test simple l1 transaction: zero", test_l1_transaction_zero); ("test simple l1 transaction: partial", test_l1_transaction_partial); ("test simple l2 transaction", test_simple_l2_transaction); + ( "test l2 transaction with l2 addr: good", + test_l2_transaction_l2_addr_signer_good ); + ( "test l2 transaction with l2 addr: bad", + test_l2_transaction_l2_addr_signer_bad ); ( "test simple transaction with indexes and values", test_transaction_with_unknown_indexable ); ("invalid transaction", test_invalid_transaction); diff --git a/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.ml b/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.ml index 63c0812eea..cfaf48aab1 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.ml @@ -42,6 +42,7 @@ type error += | Invalid_batch_encoding | Unexpectedly_indexed_ticket | Missing_ticket of Ticket_hash.t + | Unknown_address of Tx_rollup_l2_address.t let () = let open Data_encoding in @@ -131,7 +132,17 @@ let () = "A withdrawal must reference a ticket that already exists in the rollup." (obj1 (req "ticket_hash" Ticket_hash.encoding)) (function Missing_ticket ticket_hash -> Some ticket_hash | _ -> None) - (function ticket_hash -> Missing_ticket ticket_hash) + (function ticket_hash -> Missing_ticket ticket_hash) ; + (* Unknown address *) + register_error_kind + `Temporary + ~id:"tx_rollup_unknown_address" + ~title:"Attempted to sign a transfer with an unknown address" + ~description: + "The address must exist in the context when signing a transfer with it." + (obj1 (req "address" Tx_rollup_l2_address.encoding)) + (function Unknown_address addr -> Some addr | _ -> None) + (function addr -> Unknown_address addr) module Address_indexes = Map.Make (Tx_rollup_l2_address) module Ticket_indexes = Map.Make (Ticket_hash) @@ -433,15 +444,15 @@ module Make (Context : CONTEXT) = struct fun ctxt indexes op -> let* (ctxt, indexes, pk, idx) = match Indexable.destruct op.signer with - | Left pk_index -> + | Left signer_index -> (* Get the public key from the index. *) - let address_index = address_of_signer_index pk_index in + let address_index = address_of_signer_index signer_index in let* metadata = get_metadata ctxt address_index in let pk = metadata.public_key in return (ctxt, indexes, pk, address_index) - | Right pk -> ( + | Right (Bls_pk signer_pk) -> ( (* Initialize the ctxt with public_key if it's necessary. *) - let addr = Tx_rollup_l2_address.of_bls_pk pk in + let addr = Tx_rollup_l2_address.of_bls_pk signer_pk in let* (ctxt, created, idx) = Address_index.get_or_associate_index ctxt addr in @@ -462,15 +473,28 @@ module Make (Context : CONTEXT) = struct (* If the metadata exists, then the public key necessarily exists, we do not need to change the context. *) return ctxt - | None -> Address_metadata.init_with_public_key ctxt idx pk + | None -> + Address_metadata.init_with_public_key ctxt idx signer_pk in - return (ctxt, indexes, pk, idx) + return (ctxt, indexes, signer_pk, idx) | `Created -> (* If the index is created however, we need to add to indexes and initiliaze the metadata. *) let indexes = add_addr_to_indexes indexes addr idx in - let* ctxt = Address_metadata.init_with_public_key ctxt idx pk in - return (ctxt, indexes, pk, idx)) + let* ctxt = + Address_metadata.init_with_public_key ctxt idx signer_pk + in + return (ctxt, indexes, signer_pk, idx)) + | Right (L2_addr signer_addr) -> ( + (* In order to get the public key associated to [signer_addr], there + needs to be both an index associated to it, and a metadata for this + index. *) + let* idx = Address_index.get ctxt signer_addr in + match idx with + | None -> fail (Unknown_address signer_addr) + | Some idx -> + let* metadata = get_metadata ctxt idx in + return (ctxt, indexes, metadata.public_key, idx)) in let op : (Indexable.index_only, 'content) operation = {op with signer = signer_of_address_index idx} diff --git a/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.mli b/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.mli index e05d7e7bd0..ac76e5193f 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.mli +++ b/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.mli @@ -61,6 +61,7 @@ type error += | Invalid_batch_encoding | Unexpectedly_indexed_ticket | Missing_ticket of Ticket_hash.t + | Unknown_address of Tx_rollup_l2_address.t module Address_indexes : Map.S with type key = Tx_rollup_l2_address.t diff --git a/src/proto_alpha/lib_protocol/tx_rollup_l2_batch.ml b/src/proto_alpha/lib_protocol/tx_rollup_l2_batch.ml index 8e596d766e..210668f9a9 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_l2_batch.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_l2_batch.ml @@ -29,7 +29,7 @@ open Tx_rollup_l2_context_sig let tag_size = `Uint8 -let signer_encoding = +let bls_pk_encoding = let open Data_encoding in conv_with_guard Bls_signature.pk_to_bytes @@ -39,15 +39,42 @@ let signer_encoding = | None -> Error "not a BLS public key") (Fixed.bytes Bls_signature.pk_size_in_bytes) +type signer = Bls_pk of Bls_signature.pk | L2_addr of Tx_rollup_l2_address.t + module Signer_indexable = Indexable.Make (struct - type t = Bls_signature.pk + type t = signer - let pp fmt _ = Format.pp_print_string fmt "" + let pp fmt = function + | Bls_pk _ -> Format.pp_print_string fmt "" + | L2_addr addr -> Tx_rollup_l2_address.pp fmt addr let compare x y = - Bytes.compare (Bls_signature.pk_to_bytes x) (Bls_signature.pk_to_bytes y) - - let encoding = signer_encoding + match (x, y) with + | (Bls_pk pk1, Bls_pk pk2) -> + Bytes.compare + (Bls_signature.pk_to_bytes pk1) + (Bls_signature.pk_to_bytes pk2) + | (L2_addr addr1, L2_addr addr2) -> Tx_rollup_l2_address.compare addr1 addr2 + | (L2_addr _, Bls_pk _) -> -1 + | (Bls_pk _, L2_addr _) -> 1 + + let encoding = + let open Data_encoding in + union + [ + case + ~title:"bls_pk" + (Tag 0) + bls_pk_encoding + (function Bls_pk pk -> Some pk | _ -> None) + (fun pk -> Bls_pk pk); + case + ~title:"l2_addr" + (Tag 1) + Tx_rollup_l2_address.encoding + (function L2_addr addr -> Some addr | _ -> None) + (fun addr -> L2_addr addr); + ] end) module V1 = struct diff --git a/src/proto_alpha/lib_protocol/tx_rollup_l2_batch.mli b/src/proto_alpha/lib_protocol/tx_rollup_l2_batch.mli index 40c902dcc3..6eca66c727 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_l2_batch.mli +++ b/src/proto_alpha/lib_protocol/tx_rollup_l2_batch.mli @@ -68,14 +68,23 @@ open Tx_rollup_l2_context_sig implementation of their encodings have been carefully crafted in order to allow for compact batches. *) +(** Represents the [signer] of an layer-2 operation. This is either a + BLS public key or a layer-2 address index, whose metadata in turn + contains a corresponding BLS public. key *) +type signer = + | Bls_pk of Bls_signature.pk (** A signer identified by a BLS public key. *) + | L2_addr of Tx_rollup_l2_address.t + (** A signer identified by a layer-2 address. Each such adress + is in turn identified with a BLS public key. *) + module Signer_indexable : sig - type nonrec 'state t = ('state, Bls_signature.pk) Indexable.t + type nonrec 'state t = ('state, signer) Indexable.t - type nonrec index = Bls_signature.pk Indexable.index + type nonrec index = signer Indexable.index - type nonrec value = Bls_signature.pk Indexable.value + type nonrec value = signer Indexable.value - type either = Bls_signature.pk Indexable.either + type either = signer Indexable.either val encoding : either Data_encoding.t diff --git a/tezt/tests/tx_rollup_node.ml b/tezt/tests/tx_rollup_node.ml index f52d07e6a8..5e656dc1ab 100644 --- a/tezt/tests/tx_rollup_node.ml +++ b/tezt/tests/tx_rollup_node.ml @@ -566,7 +566,7 @@ let test_l2_to_l2_transaction = let tx = craft_tx ~counter:1L - ~signer:bls_pk_1 + ~signer:(Bls_pk bls_pk_1) ~dest:bls_pkh_2_str ~ticket:ticket_id 1L From a3346e831399abd374727a0779868ccf4918038c Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Mon, 14 Mar 2022 10:33:13 +0100 Subject: [PATCH 052/100] Tx_rollup,Proto: small typo --- src/proto_alpha/lib_protocol/tx_rollup_l2_apply.ml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.ml b/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.ml index cfaf48aab1..f04805cd04 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.ml @@ -478,8 +478,8 @@ module Make (Context : CONTEXT) = struct in return (ctxt, indexes, signer_pk, idx) | `Created -> - (* If the index is created however, we need to add to indexes and - initiliaze the metadata. *) + (* If the index is created, we need to add to indexes and + initialize the metadata. *) let indexes = add_addr_to_indexes indexes addr idx in let* ctxt = Address_metadata.init_with_public_key ctxt idx signer_pk From 3508b15eadb3048a8145d11a3ab27b0c8278dc2a Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Mon, 14 Mar 2022 13:27:58 +0100 Subject: [PATCH 053/100] Tx_rollup,Proto: forbid a transfer to self --- src/proto_alpha/lib_protocol/indexable.ml | 7 +++++- src/proto_alpha/lib_protocol/indexable.mli | 7 ++++++ .../test/unit/test_tx_rollup_l2_apply.ml | 24 +++++++++++++++++++ .../lib_protocol/tx_rollup_l2_apply.ml | 17 ++++++++++++- .../lib_protocol/tx_rollup_l2_apply.mli | 1 + 5 files changed, 54 insertions(+), 2 deletions(-) diff --git a/src/proto_alpha/lib_protocol/indexable.ml b/src/proto_alpha/lib_protocol/indexable.ml index 627d318334..918e33f7d2 100644 --- a/src/proto_alpha/lib_protocol/indexable.ml +++ b/src/proto_alpha/lib_protocol/indexable.ml @@ -148,7 +148,10 @@ let compare : | ((Hidden_value _ | Value _), (Hidden_index _ | Index _)) -> 1 let compare_values c : 'a value -> 'a value -> int = - fun x y -> match (x, y) with (Value x, Value y) -> c x y + fun (Value x) (Value y) -> c x y + +let compare_indexes : 'a index -> 'a index -> int = + fun (Index x) (Index y) -> Compare.Int32.compare x y module type VALUE = sig type t @@ -190,5 +193,7 @@ module Make (V : VALUE) = struct let compare_values = compare_values V.compare + let compare_indexes = compare_indexes + let compare : 'state t -> 'state' t -> int = fun x y -> compare V.compare x y end diff --git a/src/proto_alpha/lib_protocol/indexable.mli b/src/proto_alpha/lib_protocol/indexable.mli index fa631ae1f1..cc921e802f 100644 --- a/src/proto_alpha/lib_protocol/indexable.mli +++ b/src/proto_alpha/lib_protocol/indexable.mli @@ -147,6 +147,11 @@ val compare : ('a -> 'a -> int) -> ('state, 'a) t -> ('state', 'a) t -> int are indeed both values. *) val compare_values : ('a -> 'a -> int) -> 'a value -> 'a value -> int +(** [compare_indexes x y] compares the indexes [x] and [y], and relies + on the type system of OCaml to ensure that [x] and [y] are indeed + both indexes. *) +val compare_indexes : 'a index -> 'a index -> int + module type VALUE = sig type t @@ -184,6 +189,8 @@ module Make (V : VALUE) : sig val compare_values : value -> value -> int + val compare_indexes : index -> index -> int + val pp : Format.formatter -> 'state t -> unit end diff --git a/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml b/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml index cdf6202d0f..c73b67b574 100644 --- a/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml +++ b/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml @@ -1634,6 +1634,29 @@ let test_apply_message_deposit () = return_unit | _ -> fail_msg "Invalid apply message result" +let test_transfer_to_self () = + let open Context_l2.Syntax in + let* (ctxt, _, accounts) = with_initial_setup [ticket1] [[(ticket1, 10L)]] in + + let (sk1, pk1, addr1, _idx1, _) = nth_exn accounts 0 in + let transaction = + [transfer ~signer:(signer_pk pk1) ~dest:addr1 ~ticket:ticket1 1L] + in + let batch = create_batch_v1 [transaction] [[sk1]] in + + let* (_ctxt, Batch_result {results; _}, _withdrawals) = + Batch_V1.apply_batch ctxt batch + in + + let status = nth_exn results 0 in + + match status with + | ( _, + Transaction_failure + {index = 0; reason = Tx_rollup_l2_apply.Invalid_self_transfer} ) -> + return_unit + | (_, _) -> fail_msg "The transaction should faild with [Invalid_destination]" + let tests = wrap_tztest_tests [ @@ -1665,4 +1688,5 @@ let tests = ( "apply batch from message with withdrawals", test_apply_message_batch_withdrawals ); ("apply deposit from message", test_apply_message_deposit); + ("test transfer to self fail", test_transfer_to_self); ] diff --git a/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.ml b/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.ml index f04805cd04..84306f5fd9 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.ml @@ -43,6 +43,7 @@ type error += | Unexpectedly_indexed_ticket | Missing_ticket of Ticket_hash.t | Unknown_address of Tx_rollup_l2_address.t + | Invalid_self_transfer let () = let open Data_encoding in @@ -142,7 +143,16 @@ let () = "The address must exist in the context when signing a transfer with it." (obj1 (req "address" Tx_rollup_l2_address.encoding)) (function Unknown_address addr -> Some addr | _ -> None) - (function addr -> Unknown_address addr) + (function addr -> Unknown_address addr) ; + (* Invalid self transfer *) + register_error_kind + `Temporary + ~id:"tx_rollup_invalid_self_transfer" + ~title:"Attempted to transfer ticket to self" + ~description:"The index for the destination is the same as the sender" + empty + (function Invalid_self_transfer -> Some () | _ -> None) + (function () -> Invalid_self_transfer) module Address_indexes = Map.Make (Tx_rollup_l2_address) module Ticket_indexes = Map.Make (Ticket_hash) @@ -408,6 +418,11 @@ module Make (Context : CONTEXT) = struct (** [transfers ctxt source_idx destination_idx tidx amount] transfers [amount] from [source_idx] to [destination_idx] of [tidx]. *) let transfer ctxt source_idx destination_idx tidx amount = + let* () = + fail_unless + Compare.Int.(Indexable.compare_indexes source_idx destination_idx <> 0) + Invalid_self_transfer + in let* ctxt = Ticket_ledger.spend ctxt tidx source_idx amount in Ticket_ledger.credit ctxt tidx destination_idx amount diff --git a/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.mli b/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.mli index ac76e5193f..bec1cdd7d2 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.mli +++ b/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.mli @@ -62,6 +62,7 @@ type error += | Unexpectedly_indexed_ticket | Missing_ticket of Ticket_hash.t | Unknown_address of Tx_rollup_l2_address.t + | Invalid_self_transfer module Address_indexes : Map.S with type key = Tx_rollup_l2_address.t From 2062781184565155ab48549b7dec0d6d7db84959 Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Mon, 14 Mar 2022 13:41:16 +0100 Subject: [PATCH 054/100] Tx_rollup,Proto: forbid transfer of zero ticket --- .../test/unit/test_tx_rollup_l2.ml | 12 ------------ .../test/unit/test_tx_rollup_l2_apply.ml | 18 +++++++++--------- .../lib_protocol/tx_rollup_l2_apply.ml | 18 +++++++++++++++++- .../lib_protocol/tx_rollup_l2_apply.mli | 1 + .../lib_protocol/tx_rollup_l2_context.ml | 1 - .../lib_protocol/tx_rollup_l2_context_sig.ml | 3 +++ 6 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2.ml b/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2.ml index 054deb04b4..b5d9787447 100644 --- a/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2.ml +++ b/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2.ml @@ -425,17 +425,6 @@ module Test_Ticket_ledger = struct return_unit - (** Test that crediting a non strictly positive quantity fails. *) - let test_credit_invalid_quantity () = - let* (ctxt, idx1) = context_with_one_addr in - let* () = - expect_error - (credit ctxt ticket_idx1 idx1 Tx_rollup_l2_qty.zero) - Invalid_quantity - in - - return_unit - (** Test that an index can be credited ticket indexes even if its not associated to an address. *) let test_credit_unknown_index () = @@ -504,7 +493,6 @@ module Test_Ticket_ledger = struct [ ("test credit", test_credit); ("test credit too much", test_credit_too_much); - ("test credit invalid quantity", test_credit_invalid_quantity); ("test credit unknown index", test_credit_unknown_index); ("test spend", test_spend_valid); ("test spend without required balance", test_spend_without_balance); diff --git a/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml b/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml index c73b67b574..537e71ebb9 100644 --- a/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml +++ b/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml @@ -931,11 +931,7 @@ let test_l1_transaction_overdraft () = in return_unit) -(** Test that withdrawals with quantity zero are possible. - - TODO: https://gitlab.com/tezos/tezos/-/issues/2593 - Should they be possible? - *) +(** Test that withdrawals with quantity zero are not possible. *) let test_l1_transaction_zero () = let open Context_l2.Syntax in let initial_balances = [[(ticket1, 10L)]; [(ticket2, 20L)]] in @@ -965,11 +961,15 @@ let test_l1_transaction_zero () = check (list eq_withdrawal) "Resulting withdrawal from L2->L1 transfer" - withdrawals - [{claimer = pkh2; ticket_hash = ticket1; amount = Tx_rollup_l2_qty.zero}]) ; + [] + withdrawals) ; match results with - | [([_], Transaction_success)] -> + | [ + ( [_], + Transaction_failure + {index = 0; reason = Tx_rollup_l2_apply.Invalid_zero_transfer} ); + ] -> let* () = check_balance ctxt @@ -1012,7 +1012,7 @@ let test_l1_transaction_zero () = 0L in return_unit - | _ -> fail_msg "Zero-transactions should be successful" + | _ -> fail_msg "Zero-transactions should be a failure" (** Test partial L2 to L1 transaction. Ensure that a withdrawal is emitted for the transferred amount and that the remainder is in the sender's diff --git a/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.ml b/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.ml index 84306f5fd9..3a89a64b3b 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.ml @@ -44,6 +44,7 @@ type error += | Missing_ticket of Ticket_hash.t | Unknown_address of Tx_rollup_l2_address.t | Invalid_self_transfer + | Invalid_zero_transfer let () = let open Data_encoding in @@ -152,7 +153,16 @@ let () = ~description:"The index for the destination is the same as the sender" empty (function Invalid_self_transfer -> Some () | _ -> None) - (function () -> Invalid_self_transfer) + (function () -> Invalid_self_transfer) ; + (* Invalid zero transfer *) + register_error_kind + `Permanent + ~id:"tx_rollup_invalid_zero_transfer" + ~title:"Attempted to transfer zero ticket" + ~description:"A transfer's amount must be greater than zero." + empty + (function Invalid_zero_transfer -> Some () | _ -> None) + (function () -> Invalid_zero_transfer) module Address_indexes = Map.Make (Tx_rollup_l2_address) module Ticket_indexes = Map.Make (Ticket_hash) @@ -397,6 +407,9 @@ module Make (Context : CONTEXT) = struct ticket_indexes = add_to_ticket_indexes indexes.ticket_indexes ticket; } + let assert_non_zero_quantity qty = + fail_when Tx_rollup_l2_qty.(qty = zero) Invalid_zero_transfer + (** {2. Counter } *) (** [get_metadata ctxt idx] returns the metadata associated to [idx] in @@ -423,6 +436,7 @@ module Make (Context : CONTEXT) = struct Compare.Int.(Indexable.compare_indexes source_idx destination_idx <> 0) Invalid_self_transfer in + let* () = assert_non_zero_quantity amount in let* ctxt = Ticket_ledger.spend ctxt tidx source_idx amount in Ticket_ledger.credit ctxt tidx destination_idx amount @@ -619,8 +633,10 @@ module Make (Context : CONTEXT) = struct Option.value_e ~error:(Missing_ticket ticket_hash) tidx_opt in let source_idx = address_of_signer_index source_idx in + (* spend the ticket -- this is responsible for checking that the source has the required balance *) + let* () = assert_non_zero_quantity amount in let* ctxt = Ticket_ledger.spend ctxt tidx source_idx amount in let withdrawal = Tx_rollup_withdraw.{claimer; ticket_hash; amount} in return (ctxt, indexes, Some withdrawal) diff --git a/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.mli b/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.mli index bec1cdd7d2..1f922a43e6 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.mli +++ b/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.mli @@ -63,6 +63,7 @@ type error += | Missing_ticket of Ticket_hash.t | Unknown_address of Tx_rollup_l2_address.t | Invalid_self_transfer + | Invalid_zero_transfer module Address_indexes : Map.S with type key = Tx_rollup_l2_address.t diff --git a/src/proto_alpha/lib_protocol/tx_rollup_l2_context.ml b/src/proto_alpha/lib_protocol/tx_rollup_l2_context.ml index c51ca02566..be60ee7cc1 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_l2_context.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_l2_context.ml @@ -368,7 +368,6 @@ struct let credit ctxt tidx aidx qty = let open Syntax in - let* () = fail_when Tx_rollup_l2_qty.(qty = zero) Invalid_quantity in let* balance = get ctxt tidx aidx in match Tx_rollup_l2_qty.add balance qty with | None -> fail Balance_overflow diff --git a/src/proto_alpha/lib_protocol/tx_rollup_l2_context_sig.ml b/src/proto_alpha/lib_protocol/tx_rollup_l2_context_sig.ml index 20a7f760d5..54f7c95cca 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_l2_context_sig.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_l2_context_sig.ml @@ -211,6 +211,9 @@ module type CONTEXT = sig (** [fail_unless cond err] raises [err] iff [cond] is [false]. *) val fail_unless : bool -> error -> unit m + + (** [fail_when cond err] raises [err] iff [cond] is [true]. *) + val fail_when : bool -> error -> unit m end (** [bls_aggregate_verify] allows to verify the aggregated signature From 34c618d6948e4ed6aa2a70e145d22d9e3d5efb53 Mon Sep 17 00:00:00 2001 From: Antonio Locascio Date: Tue, 15 Mar 2022 13:50:00 +0100 Subject: [PATCH 055/100] Proto: add Merkle_list module for TORU Co-authored-by: Victor Dumitrescu --- src/proto_alpha/lib_protocol/TEZOS_PROTOCOL | 2 + src/proto_alpha/lib_protocol/dune.inc | 5 + src/proto_alpha/lib_protocol/merkle_list.ml | 314 ++++++++++++++++++ src/proto_alpha/lib_protocol/merkle_list.mli | 101 ++++++ .../test/helpers/merkle_list_helper.ml | 54 +++ src/proto_alpha/lib_protocol/test/pbt/dune | 1 + .../lib_protocol/test/pbt/test_merkle_list.ml | 127 +++++++ .../lib_protocol/test/unit/main.ml | 1 + .../test/unit/test_merkle_list.ml | 263 +++++++++++++++ 9 files changed, 868 insertions(+) create mode 100644 src/proto_alpha/lib_protocol/merkle_list.ml create mode 100644 src/proto_alpha/lib_protocol/merkle_list.mli create mode 100644 src/proto_alpha/lib_protocol/test/helpers/merkle_list_helper.ml create mode 100644 src/proto_alpha/lib_protocol/test/pbt/test_merkle_list.ml create mode 100644 src/proto_alpha/lib_protocol/test/unit/test_merkle_list.ml diff --git a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL index f247802069..f799885d5d 100644 --- a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL +++ b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL @@ -183,6 +183,8 @@ "Tx_rollup_services", "Alpha_services", + "Merkle_list", + "Main" ] } diff --git a/src/proto_alpha/lib_protocol/dune.inc b/src/proto_alpha/lib_protocol/dune.inc index 52d534e023..f662b09503 100644 --- a/src/proto_alpha/lib_protocol/dune.inc +++ b/src/proto_alpha/lib_protocol/dune.inc @@ -194,6 +194,7 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end voting_services.mli voting_services.ml tx_rollup_services.mli tx_rollup_services.ml alpha_services.mli alpha_services.ml + merkle_list.mli merkle_list.ml main.mli main.ml (:src_dir TEZOS_PROTOCOL)) (action @@ -369,6 +370,7 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end voting_services.mli voting_services.ml tx_rollup_services.mli tx_rollup_services.ml alpha_services.mli alpha_services.ml + merkle_list.mli merkle_list.ml main.mli main.ml (:src_dir TEZOS_PROTOCOL)) (action (with-stdout-to %{targets} @@ -544,6 +546,7 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end voting_services.mli voting_services.ml tx_rollup_services.mli tx_rollup_services.ml alpha_services.mli alpha_services.ml + merkle_list.mli merkle_list.ml main.mli main.ml) (action (write-file %{targets} @@ -741,6 +744,7 @@ include Tezos_raw_protocol_alpha.Main Voting_services Tx_rollup_services Alpha_services + Merkle_list Main)) (install @@ -957,6 +961,7 @@ include Tezos_raw_protocol_alpha.Main voting_services.mli voting_services.ml tx_rollup_services.mli tx_rollup_services.ml alpha_services.mli alpha_services.ml + merkle_list.mli merkle_list.ml main.mli main.ml (:src_dir TEZOS_PROTOCOL)) (action (run %{bin:tezos-protocol-compiler} -no-hash-check .))) diff --git a/src/proto_alpha/lib_protocol/merkle_list.ml b/src/proto_alpha/lib_protocol/merkle_list.ml new file mode 100644 index 0000000000..c928154024 --- /dev/null +++ b/src/proto_alpha/lib_protocol/merkle_list.ml @@ -0,0 +1,314 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type error += Merkle_list_invalid_position + +let _ = + register_error_kind + `Temporary + ~id:"Merkle_list_invalid_position" + ~title:"Merkle_list_invalid_position" + ~description:"Merkle_list_invalid_position" + ~pp:(fun ppf () -> Format.fprintf ppf "%s" "Merkle_list_invalid_position") + Data_encoding.empty + (function Merkle_list_invalid_position -> Some () | _ -> None) + (fun () -> Merkle_list_invalid_position) + +module type T = sig + type t + + type h + + type elt + + type path + + val nil : t + + val empty : h + + val root : t -> h + + val snoc : t -> elt -> t + + val snoc_tr : t -> elt -> t + + val compute : elt list -> h + + val path_encoding : path Data_encoding.t + + val bounded_path_encoding : ?max_length:int -> unit -> path Data_encoding.t + + val compute_path : t -> int -> path tzresult + + val check_path : path -> int -> elt -> h -> bool tzresult + + val elt_bytes : elt -> Bytes.t + + module Internal_for_tests : sig + val path_to_list : path -> h list + + val equal : t -> t -> bool + + val to_list : t -> h list + end +end + +module Make (El : sig + type t + + val to_bytes : t -> bytes +end) +(H : S.HASH) : T with type elt = El.t and type h = H.t = struct + type h = H.t + + type elt = El.t + + let elt_bytes = El.to_bytes + + (* + The goal of this structure is to model an append-only list. + Its internal representation is that of a binary tree whose + leaves are all at the same level (the tree's height). + + To insert a new element in a full tree t, we create a new root with t + as its left subtree and a new tree t' as its right subtree. t' is just a + left-spine of the same height as t. Visually, + + t = / \ t' = / snoc 4 t = / \ + /\ /\ / / \ / + 0 1 2 3 4 /\ /\ / + 0 1 2 3 4 + + Then, this is a balanced tree by construction. + As the key in the tree for a given position is the position's + binary decomposition of size height(tree), the tree is dense. + For that reason, the use of extenders is not needed. + *) + + type tree = Empty | Leaf of h | Node of (h * tree * tree) + + (* The tree has the following invariants: + A node [Node left right] if valid iff + 1. [right] is Empty and [left] is not Empty, or + 2. [right] is not Empty and [left] is full + Additionally: + [t.depth] is the height of [t.tree] and + [t.next_pos] is the number of leaves in [t.tree] *) + type t = {tree : tree; depth : int; next_pos : int} + + type path = h list + + let empty = H.zero + + let root = function Empty -> empty | Leaf h -> h | Node (h, _, _) -> h + + let nil = {tree = Empty; depth = 0; next_pos = 0} + + let hash_elt el = H.hash_bytes [elt_bytes el] + + let leaf_of el = Leaf (hash_elt el) + + let hash2 h1 h2 = H.(hash_bytes [to_bytes h1; to_bytes h2]) + + let node_of t1 t2 = Node (hash2 (root t1) (root t2), t1, t2) + + (* to_bin computes the [depth]-long binary representation of [pos] + (left-padding with 0s if required). This corresponds to the tree traversal + of en element at position [pos] (false = left, true = right). + + Pre-condition: pos >= 0 /| pos < 2^depth + Post-condition: len(to_bin pos depth) = depth *) + let to_bin ~pos ~depth = + let rec aux acc pos depth = + let (pos', dir) = (pos / 2, pos mod 2) in + match depth with + | 0 -> acc + | d -> aux (Compare.Int.(dir = 1) :: acc) pos' (d - 1) + in + aux [] pos depth + + (* Constructs a tree of a given depth in which every right subtree is empty + * and the only leaf contains the hash of el. *) + let make_spine_with el = + let rec aux left = function + | 0 -> left + | d -> (aux [@tailcall]) (node_of left Empty) (d - 1) + in + aux (leaf_of el) + + let snoc t (el : elt) = + let rec traverse tree depth key = + match (tree, key) with + | (Node (_, t_left, Empty), true :: _key) -> + (* The base case where the left subtree is full and we start + * the right subtree by creating a new tree the size of the remaining + * depth and placing the new element in its leftmost position. *) + let t_right = make_spine_with el (depth - 1) in + node_of t_left t_right + | (Node (_, t_left, Empty), false :: key) -> + (* Traversing left, the left subtree is not full (and thus the right + * subtree is empty). Recurse on left subtree. *) + let t_left = traverse t_left (depth - 1) key in + node_of t_left Empty + | (Node (_, t_left, t_right), true :: key) -> + (* Traversing right, the left subtree is full. + * Recurse on right subtree *) + let t_right = traverse t_right (depth - 1) key in + node_of t_left t_right + | (_, _) -> + (* Impossible by construction of the tree and of the key. + * See [tree] invariants and [to_bin]. *) + assert false + in + + let (tree', depth') = + match (t.tree, t.depth, t.next_pos) with + | (Empty, 0, 0) -> (node_of (leaf_of el) Empty, 1) + | (tree, depth, pos) when Int32.(equal (shift_left 1l depth) (of_int pos)) + -> + let t_right = make_spine_with el depth in + (node_of tree t_right, depth + 1) + | (tree, depth, pos) -> + let key = to_bin ~pos ~depth in + (traverse tree depth key, depth) + in + {tree = tree'; depth = depth'; next_pos = t.next_pos + 1} + + type zipper = Left of zipper * tree | Right of tree * zipper | Top + + let rec rebuild_tree z t = + match z with + | Top -> t + | Left (z, r) -> (rebuild_tree [@tailcall]) z (node_of t r) + | Right (l, z) -> (rebuild_tree [@tailcall]) z (node_of l t) + + let snoc_tr t (el : elt) = + let rec traverse (z : zipper) tree depth key = + match (tree, key) with + | (Node (_, t_left, Empty), true :: _key) -> + let t_right = make_spine_with el (depth - 1) in + rebuild_tree z (node_of t_left t_right) + | (Node (_, t_left, Empty), false :: key) -> + let z = Left (z, Empty) in + (traverse [@tailcall]) z t_left (depth - 1) key + | (Node (_, t_left, t_right), true :: key) -> + let z = Right (t_left, z) in + (traverse [@tailcall]) z t_right (depth - 1) key + | (_, _) -> + (* Impossible by construction of the tree and of the key. + * See [tree] invariants and [to_bin]. *) + assert false + in + + let (tree', depth') = + match (t.tree, t.depth, t.next_pos) with + | (Empty, 0, 0) -> (node_of (leaf_of el) Empty, 1) + | (tree, depth, pos) when Int32.(equal (shift_left 1l depth) (of_int pos)) + -> + let t_right = make_spine_with el depth in + (node_of tree t_right, depth + 1) + | (tree, depth, pos) -> + let key = to_bin ~pos ~depth in + (traverse Top tree depth key, depth) + in + {tree = tree'; depth = depth'; next_pos = t.next_pos + 1} + + let rec tree_to_list = function + | Empty -> [] + | Leaf h -> [h] + | Node (_, t_left, t_right) -> tree_to_list t_left @ tree_to_list t_right + + let path_encoding = Data_encoding.(list H.encoding) + + let bounded_path_encoding ?max_length () = + match max_length with + | None -> path_encoding + | Some max_length -> Data_encoding.((list ~max_length) H.encoding) + + (* The order of the path is from bottom to top *) + let compute_path {tree; depth; next_pos} pos = + if Compare.Int.(pos < 0 || pos >= next_pos) then + error Merkle_list_invalid_position + else + let key = to_bin ~pos ~depth in + let rec aux acc tree key = + match (tree, key) with + | (Leaf _, []) -> ok acc + | (Node (_, l, r), b :: key) -> + if b then aux (root l :: acc) r key else aux (root r :: acc) l key + | _ -> error Merkle_list_invalid_position + in + aux [] tree key + + let check_path path pos el expected_root = + let depth = List.length path in + if + Compare.Int.(pos >= 0) + && Compare.Z.(Z.of_int pos < Z.shift_left Z.one depth) + then + let key = List.rev @@ to_bin ~pos ~depth in + let computed_root = + List.fold_left + (fun acc (sibling, b) -> + if b then hash2 sibling acc else hash2 acc sibling) + (hash_elt el) + (List.combine_drop path key) + in + ok (H.equal computed_root expected_root) + else error Merkle_list_invalid_position + + let compute l = + let rec aux l = + let rec pairs acc = function + | [] -> List.rev acc + | [x] -> List.rev (hash2 x empty :: acc) + | x :: y :: xs -> pairs (hash2 x y :: acc) xs + in + match pairs [] l with [] -> empty | [h] -> h | pl -> aux pl + in + aux (List.map hash_elt l) + + let root t = root t.tree + + module Internal_for_tests = struct + let path_to_list x = x + + let to_list tree = tree_to_list tree.tree + + let equal t1 t2 = + let rec eq_tree t1 t2 = + match (t1, t2) with + | (Empty, Empty) -> true + | (Leaf h1, Leaf h2) -> H.equal h1 h2 + | (Node (h1, l1, r1), Node (h2, l2, r2)) -> + H.equal h1 h2 && eq_tree l1 l2 && eq_tree r1 r2 + | _ -> false + in + Compare.Int.equal t1.depth t2.depth + && Compare.Int.equal t1.next_pos t2.next_pos + && eq_tree t1.tree t2.tree + end +end diff --git a/src/proto_alpha/lib_protocol/merkle_list.mli b/src/proto_alpha/lib_protocol/merkle_list.mli new file mode 100644 index 0000000000..3f4799de1a --- /dev/null +++ b/src/proto_alpha/lib_protocol/merkle_list.mli @@ -0,0 +1,101 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type error += Merkle_list_invalid_position + +module type T = sig + (** The type of a Merkle list *) + type t + + (** The type of a hash *) + type h + + (** The type of an element *) + type elt + + (** A path, together with an element's position, is the proof of inclusion + of an element in the Merkle list. *) + type path + + (** The empty Merkle list *) + val nil : t + + (** The empty hash *) + val empty : h + + (** [root t] returns the root hash of a Merkle list. *) + val root : t -> h + + (** [snoc t el] adds element [el] to a Merkle list [t] and returns + the new list. *) + val snoc : t -> elt -> t + + (** Tail recursive variant of [snoc]. *) + val snoc_tr : t -> elt -> t + + (** [compute elems] returns the root hash of the Merkle list constructed with + [elems]. *) + val compute : elt list -> h + + (** Encoding of a path. *) + val path_encoding : path Data_encoding.t + + (** Encoding of a path, with optional bound [max_length]. *) + val bounded_path_encoding : ?max_length:int -> unit -> path Data_encoding.t + + (** [compute_path t pos] computes the path of the element in position [pos]. + + Can fail with [Merkle_list_invalid_position] if [pos] is negative or + if it is greater than the number of elements in the list. *) + val compute_path : t -> int -> path tzresult + + (** [check_path path pos elt expected_root] checks that an [elt] with path + [path] at position [pos] has the [expected_root]. + + Can fail with [Merkle_list_invalid_position] if [pos] is negative or + if it is greater than the number of elements in the list. *) + val check_path : path -> int -> elt -> h -> bool tzresult + + val elt_bytes : elt -> Bytes.t + + (**/**) + + module Internal_for_tests : sig + val path_to_list : path -> h list + + (** Checks equality between Merkle lists. Outside of testing, clients should + use [root] for comparison. *) + val equal : t -> t -> bool + + val to_list : t -> h list + end +end + +module Make (El : sig + type t + + val to_bytes : t -> bytes +end) +(H : S.HASH) : T with type elt = El.t and type h = H.t diff --git a/src/proto_alpha/lib_protocol/test/helpers/merkle_list_helper.ml b/src/proto_alpha/lib_protocol/test/helpers/merkle_list_helper.ml new file mode 100644 index 0000000000..bf823ad6f9 --- /dev/null +++ b/src/proto_alpha/lib_protocol/test/helpers/merkle_list_helper.ml @@ -0,0 +1,54 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let prefix = "\001\002\003" (* 8uE(36) *) + +module Hash = + Environment.Blake2B.Make + (Environment.Base58) + (struct + let name = "Merkle_list" + + let title = "Merkle_list" + + let b58check_prefix = prefix + + let size = Some 20 + end) + +module ML = + Protocol.Merkle_list.Make + (struct + type t = bytes + + let to_bytes x = x + end) + (Hash) + +include ML + +(* Hash two hashes *) +let hash2 (h1 : Hash.t) (h2 : Hash.t) = + Hash.(hash_bytes [to_bytes h1; to_bytes h2]) diff --git a/src/proto_alpha/lib_protocol/test/pbt/dune b/src/proto_alpha/lib_protocol/test/pbt/dune index dcdd85f2d2..307e7a1b56 100644 --- a/src/proto_alpha/lib_protocol/test/pbt/dune +++ b/src/proto_alpha/lib_protocol/test/pbt/dune @@ -2,6 +2,7 @@ (package tezos-protocol-alpha-tests) (names liquidity_baking_pbt saturation_fuzzing + test_merkle_list test_gas_properties test_sampler test_script_comparison diff --git a/src/proto_alpha/lib_protocol/test/pbt/test_merkle_list.ml b/src/proto_alpha/lib_protocol/test/pbt/test_merkle_list.ml new file mode 100644 index 0000000000..d2f1d01a67 --- /dev/null +++ b/src/proto_alpha/lib_protocol/test/pbt/test_merkle_list.ml @@ -0,0 +1,127 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol Library + Invocation: dune exec \ + src/proto_alpha/lib_protocol/test/pbt/test_merkle_list.exe + Subject: Tx rollup l2 encoding +*) + +open Lib_test.Qcheck2_helpers + +(* ------ generators -------------------------------------------------------- *) + +let input : bytes list QCheck2.Gen.t = + let open QCheck2.Gen in + list_size (2 -- 100) bytes_gen + +let valid_pos l = + let open QCheck2.Gen in + let* pos = 0 -- (List.length l - 1) in + return pos + +let invalid_pos l = + let open QCheck2.Gen in + let* choice = bool in + let* pos = + if choice then -20 -- -1 + else + let len = List.length l in + len -- (2 * len) + in + return pos + +let input_and_pos : (int * bytes list) QCheck2.Gen.t = + let open QCheck2.Gen in + let* l = input in + let* pos = valid_pos l in + return (pos, l) + +let input_and_pos_and_wrong_pos : (int * int * bytes list) QCheck2.Gen.t = + let open QCheck2.Gen in + let* l = input in + let* pos = valid_pos l in + let* wrong_pos = invalid_pos l in + return (pos, wrong_pos, l) + +(* ------ tests ------------------------------------------------------------- *) + +let test_scons_scons_tr_equiv ~count = + let open Merkle_list_helper in + QCheck2.Test.make ~count ~name:"scons_scons_tr_equiv" input (fun input -> + let snoc = List.fold_left snoc nil input in + let snoc_tr = List.fold_left snoc_tr nil input in + Internal_for_tests.equal snoc snoc_tr) + +let test_scons_compute_equiv ~count = + let open Merkle_list_helper in + QCheck2.Test.make ~count ~name:"scons_compute_equiv" input (fun input -> + let snoc = List.fold_left snoc nil input |> root in + let compute = compute input in + Hash.equal snoc compute) + +let ok_exn = function Ok x -> x | Error _ -> raise (Invalid_argument "ok_exn") + +let is_error = function Ok _ -> false | Error _ -> true + +let test_check_path ~count = + let open Merkle_list_helper in + QCheck2.Test.make ~count ~name:"check_path" input_and_pos (fun (pos, input) -> + let tree = List.fold_left snoc nil input in + let hash = root tree in + let path = ok_exn @@ compute_path tree pos in + ok_exn @@ check_path path pos (Stdlib.List.nth input pos) hash) + +let test_check_path_wrong ~count = + let open Merkle_list_helper in + QCheck2.Test.make + ~count + ~name:"check_path_wrong" + input_and_pos_and_wrong_pos + (fun (pos, wrong_pos, input) -> + let tree = List.fold_left snoc nil input in + let hash = root tree in + let path = ok_exn @@ compute_path tree pos in + match check_path path wrong_pos (Stdlib.List.nth input pos) hash with + | Ok b -> not b + | Error _ -> true) + +let () = + let qcheck_wrap = qcheck_wrap ~rand:(Random.State.make_self_init ()) in + Alcotest.run + "Merkle list" + [ + ( "scons_equiv", + qcheck_wrap + [ + test_scons_scons_tr_equiv ~count:1000; + test_scons_compute_equiv ~count:1000; + ] ); + ( "check_path", + qcheck_wrap + [test_check_path ~count:1000; test_check_path_wrong ~count:1000] ); + ] diff --git a/src/proto_alpha/lib_protocol/test/unit/main.ml b/src/proto_alpha/lib_protocol/test/unit/main.ml index fc85a60e2c..2ec835e2a2 100644 --- a/src/proto_alpha/lib_protocol/test/unit/main.ml +++ b/src/proto_alpha/lib_protocol/test/unit/main.ml @@ -73,5 +73,6 @@ let () = Unit_test.spec "tx rollup l2 apply" Test_tx_rollup_l2_apply.tests; Unit_test.spec "liquidity baking" Test_liquidity_baking_repr.tests; Unit_test.spec "sc rollup arith" Test_sc_rollup_arith.tests; + Unit_test.spec "merkle list" Test_merkle_list.tests; ] |> Lwt_main.run diff --git a/src/proto_alpha/lib_protocol/test/unit/test_merkle_list.ml b/src/proto_alpha/lib_protocol/test/unit/test_merkle_list.ml new file mode 100644 index 0000000000..ff70a153fb --- /dev/null +++ b/src/proto_alpha/lib_protocol/test/unit/test_merkle_list.ml @@ -0,0 +1,263 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (Merkle list) + Invocation: dune exec src/proto_alpha/lib_protocol/test/unit/main.exe \ + -- test "\[Unit\] merkle list" + Subject: test the ad-hoc merkle tree structure implemented to encode lists +*) + +open Protocol +open Merkle_list_helper + +let assert_invalid_pos : 'a Environment.Error_monad.tzresult -> _ = function + | Error err -> + let expected_error_msg msg = "Error:\n " ^ msg ^ "\n" in + let actual_error_msg : string = + Format.asprintf "%a" Environment.Error_monad.pp_trace err + in + Printf.printf "%s\n" actual_error_msg ; + assert ( + expected_error_msg "Merkle_list_invalid_position" = actual_error_msg) + | _ -> assert false + +(* Check that the result of [compute] is the expected hash *) +let test_compute () = + let open Error_monad.Result_syntax in + let elements = + Stdlib.List.init 5 (fun i -> Bytes.of_string (Int.to_string i)) + in + let element_hashes = List.map (fun e -> Hash.hash_bytes [e]) elements in + let el_hashes_a = Array.of_list element_hashes in + let h01 = hash2 el_hashes_a.(0) el_hashes_a.(1) in + let h23 = hash2 el_hashes_a.(2) el_hashes_a.(3) in + let h4e = hash2 el_hashes_a.(4) empty in + let h03 = hash2 h01 h23 in + let h4ee = hash2 h4e empty in + let expected_root = hash2 h03 h4ee in + assert (Hash.equal (compute elements) expected_root) ; + return_unit + +(* Compare the root of a tree constructed by snoc'ing to the value + given by compute and the values of the leaves *) +let test_snoc () = + let open Error_monad.Result_syntax in + let n = 20 in + let elements = + Stdlib.List.init n (fun i -> Bytes.of_string (Int.to_string i)) + in + + let t = List.fold_left snoc_tr nil elements in + let element_hashes = List.map (fun e -> Hash.hash_bytes [e]) elements in + + assert (Hash.equal (compute elements) (root t)) ; + assert (element_hashes = Internal_for_tests.to_list t) ; + return_unit + +(* Compare the result of the two versions of snoc *) +let test_snoc_non_tr () = + let open Error_monad.Result_syntax in + let n = 20 in + let elements = + Stdlib.List.init n (fun i -> Bytes.of_string (Int.to_string i)) + in + let t1 = List.fold_left snoc_tr nil elements in + let t2 = List.fold_left snoc nil elements in + assert (Internal_for_tests.equal t1 t2) ; + return_unit + +(* Check that the path computed is the expected one *) +let test_compute_path () = + let open Error_monad.Result_syntax in + let elements = + Stdlib.List.init 5 (fun i -> Bytes.of_string (Int.to_string i)) + in + let t = List.fold_left snoc_tr nil elements in + + let element_hashes = List.map (fun e -> Hash.hash_bytes [e]) elements in + let el_hashes_a = Array.of_list element_hashes in + let h23 = hash2 el_hashes_a.(2) el_hashes_a.(3) in + let h4e = hash2 el_hashes_a.(4) empty in + let h4ee = hash2 h4e empty in + let expected_path_for_1 = [el_hashes_a.(0); h23; h4ee] in + let* path = compute_path t 1 in + assert (Internal_for_tests.path_to_list path = expected_path_for_1) ; + return_unit + +(* Negative test: pos < 0 *) +let test_compute_path_negative_pos () = + let open Error_monad.Result_syntax in + let n = 10 in + let elements = + Stdlib.List.init n (fun i -> Bytes.of_string (Int.to_string i)) + in + let t = List.fold_left snoc_tr nil elements in + assert_invalid_pos @@ compute_path t (-1) ; + return_unit + +(* Negative test: pos >= size tree *) +let test_compute_path_out_of_bounds () = + let open Error_monad.Result_syntax in + let n = 20 in + let elements = + Stdlib.List.init n (fun i -> Bytes.of_string (Int.to_string i)) + in + let t = List.fold_left snoc_tr nil elements in + assert_invalid_pos @@ compute_path t n ; + return_unit + +(* Negative test: pos = size tree, when tree is full *) +let test_compute_path_out_of_bounds_full () = + let open Error_monad.Result_syntax in + let n = 4 in + let elements = + Stdlib.List.init n (fun i -> Bytes.of_string (Int.to_string i)) + in + let t = List.fold_left snoc_tr nil elements in + assert_invalid_pos @@ compute_path t n ; + return_unit + +(* Check that a computed root (from [check_path]) is the actual root *) +let test_check_path () = + let open Error_monad.Result_syntax in + let n = 20 in + let elements = + Stdlib.List.init n (fun i -> Bytes.of_string (Int.to_string i)) + in + let elements_array = Array.of_list elements in + let t = List.fold_left snoc_tr nil elements in + let _ = + Stdlib.List.init n (fun pos -> + let* path = compute_path t pos in + let* b = check_path path pos elements_array.(pos) (ML.root t) in + assert b ; + return_unit) + in + return_unit + +(* Check that a path is only valid for the position for which it + was computed *) +let test_check_path_wrong_pos () = + let open Error_monad.Result_syntax in + let n = 20 in + let elements = + Stdlib.List.init n (fun i -> Bytes.of_string (Int.to_string i)) + in + let elements_array = Array.of_list elements in + let t = List.fold_left snoc_tr ML.nil elements in + let* path = compute_path t (n - 1) in + let _ = + Stdlib.List.init (n - 2) (fun pos -> + let* b = check_path path pos elements_array.(pos) (ML.root t) in + assert (not b) ; + return_unit) + in + return_unit + +(* Check that a computed path is invalidated by a tree update *) +let test_check_invalidated_path () = + let open Error_monad.Result_syntax in + let n = 20 in + let elements = + Stdlib.List.init n (fun i -> Bytes.of_string (Int.to_string i)) + in + let new_el = Bytes.of_string (Int.to_string n) in + let t = List.fold_left snoc_tr ML.nil elements in + let* path = compute_path t 0 in + let t = snoc_tr t new_el in + let* b = check_path path 0 (Stdlib.List.hd elements) (ML.root t) in + assert (not b) ; + return_unit + +(* Negative test: pos < 0 in [check_path] *) +let test_check_path_negative_pos () = + let open Error_monad.Result_syntax in + let n = 20 in + let elements = + Stdlib.List.init n (fun i -> Bytes.of_string (Int.to_string i)) + in + let elements_array = Array.of_list elements in + let t = List.fold_left snoc_tr nil elements in + let pos = Random.int n in + let* path = compute_path t pos in + assert_invalid_pos @@ check_path path (-1) elements_array.(pos) (ML.root t) ; + return_unit + +(* Negative test: pos >= 2^depth in [check_path] *) +let test_check_path_out_of_bounds () = + let open Error_monad.Result_syntax in + let n = 20 in + let elements = + Stdlib.List.init n (fun i -> Bytes.of_string (Int.to_string i)) + in + let elements_array = Array.of_list elements in + let t = List.fold_left snoc_tr nil elements in + let pos = Random.int n in + let* path = compute_path t pos in + (* NB: for this to be actually invalid, it is not enough to pass + a position larger than [n]. We need pos >= 2^depth. *) + assert_invalid_pos @@ check_path path 32 elements_array.(pos) (ML.root t) ; + return_unit + +(* Encoding roundtrip *) +let test_path_encoding () = + let open Error_monad.Result_syntax in + let n = 20 in + let elements = + Stdlib.List.init n (fun i -> Bytes.of_string (Int.to_string i)) + in + let t = List.fold_left snoc_tr nil elements in + let pos = n / 2 in + let* path = compute_path t pos in + let b = Data_encoding.Binary.to_bytes_exn path_encoding path in + let path' = Data_encoding.Binary.of_bytes_exn path_encoding b in + assert (path' = path) ; + return_unit + +let valid_tests = + [ + ("test_compute", test_compute); + ("test_snoc", test_snoc); + ("test_snoc_non_tr", test_snoc_non_tr); + ("test_compute_path", test_compute_path); + ("test_check_path", test_check_path); + ("test_path_encoding", test_path_encoding); + ("test_compute_path_negative_pos", test_compute_path_negative_pos); + ("test_compute_path_out_of_bounds", test_compute_path_out_of_bounds); + ("test_check_path_negative_pos", test_check_path_negative_pos); + ("test_check_path_out_of_bounds", test_check_path_out_of_bounds); + ( "test_compute_path_out_of_bounds_full", + test_compute_path_out_of_bounds_full ); + ("test_check_path_wrong_pos", test_check_path_wrong_pos); + ("test_check_invalidated_path", test_check_invalidated_path); + ] + +let wrap (n, f) = + Alcotest_lwt.test_case n `Quick (fun _ () -> + Lwt.return (f ()) >|= function Ok () -> () | Error _ -> assert false) + +let tests = List.map wrap valid_tests From 4c45538614cd8fcd496e9a07127bfc147ff5c620 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Proust?= Date: Mon, 14 Mar 2022 14:40:34 +0100 Subject: [PATCH 056/100] Sapling: convert code to newer `let*` syntax --- src/lib_sapling/test/example.ml | 66 +++++++++++++++------------- src/lib_sapling/test/test_sapling.ml | 28 +++++++----- 2 files changed, 53 insertions(+), 41 deletions(-) diff --git a/src/lib_sapling/test/example.ml b/src/lib_sapling/test/example.ml index fa5e88287d..028706479f 100644 --- a/src/lib_sapling/test/example.ml +++ b/src/lib_sapling/test/example.ml @@ -372,6 +372,7 @@ module Validator = struct let verify_update (transaction : Core.UTXO.transaction) (state : Storage.state) (key : string) : (Int64.t * Storage.state) tzresult Lwt.t = + let open Lwt_tzresult_syntax in (* Check the transaction *) (* Check the memo_size*) let coherence_of_memo_size = @@ -394,38 +395,43 @@ module Validator = struct not (Storage.mem_root state transaction.root) then fail (Too_old_root transaction.root) else - Core.Verification.with_verification_ctx (fun ctx -> - (* Check all the output ZK proofs *) - List.iter_es - (fun output -> - fail_unless - (Core.Verification.check_output ctx output) - (Output_incorrect output)) - transaction.outputs - >>=? fun () -> - (* Check all the input Zk proofs and signatures *) - List.iter_es - (fun input -> - if Core.Verification.check_spend ctx input transaction.root key - then return_unit - else fail (Input_incorrect input)) - transaction.inputs - >>=? fun () -> - (* Check the signature and balance of the whole transaction *) - fail_unless - (Core.Verification.final_check ctx transaction key) - (Binding_sig_incorrect transaction.binding_sig)) - >>=? fun () -> + let* () = + Core.Verification.with_verification_ctx (fun ctx -> + (* Check all the output ZK proofs *) + let* () = + List.iter_es + (fun output -> + fail_unless + (Core.Verification.check_output ctx output) + (Output_incorrect output)) + transaction.outputs + in + (* Check all the input Zk proofs and signatures *) + let* () = + List.iter_es + (fun input -> + if + Core.Verification.check_spend ctx input transaction.root key + then return_unit + else fail (Input_incorrect input)) + transaction.inputs + in + (* Check the signature and balance of the whole transaction *) + fail_unless + (Core.Verification.final_check ctx transaction key) + (Binding_sig_incorrect transaction.binding_sig)) + in (* Check that each nullifier is not already present in the state and add it. Important to avoid spending the same input twice in a transaction. *) - List.fold_left_es - (fun state input -> - if Storage.mem_nullifier state Core.UTXO.(input.nf) then - fail (Input_spent input) - else return (Storage.add_nullifier state Core.UTXO.(input.nf))) - state - transaction.inputs - >>=? fun state -> + let* state = + List.fold_left_es + (fun state input -> + if Storage.mem_nullifier state Core.UTXO.(input.nf) then + fail (Input_spent input) + else return (Storage.add_nullifier state Core.UTXO.(input.nf))) + state + transaction.inputs + in (* Add the commitments to the state *) let state = let open Core.UTXO in diff --git a/src/lib_sapling/test/test_sapling.ml b/src/lib_sapling/test/test_sapling.ml index a13c914686..a486f4a121 100644 --- a/src/lib_sapling/test/test_sapling.ml +++ b/src/lib_sapling/test/test_sapling.ml @@ -303,6 +303,7 @@ let test_full_transaction () = () let test_forge () = + let open Lwt_result_syntax in let module Core = Core.Client in let key = "SaplingForTezosV1" in let sk1 = List.nth Keys.xsks 0 in @@ -316,7 +317,7 @@ let test_forge () = let t1 = Forge.forge_transaction [] [output] sk1 key ~bound_data:"pkh" state in - Example.Validator.verify_update t1 state key >>=? fun (_, state) -> + let* (_, state) = Example.Validator.verify_update t1 state key in let forge_input_opt = Forge.Input.get state 0L vk1 in let (_msg, forge_input) = Stdlib.Option.get @@ forge_input_opt in let forge_output = Forge.make_output addr2 10L Bytes.empty in @@ -329,7 +330,8 @@ let test_forge () = ~bound_data:"" state in - Example.Validator.verify_update transaction state key >>= function + let*! r = Example.Validator.verify_update transaction state key in + match r with | Error l -> pp_print_trace Format.err_formatter l ; assert false @@ -346,7 +348,8 @@ let test_forge () = ~bound_data:"" state in - Example.Validator.verify_update transaction state key >>= function + let*! r = Example.Validator.verify_update transaction state key in + match r with | Ok _ -> assert false | Error l -> assert ( @@ -356,6 +359,7 @@ let test_forge () = return_unit) let test_simple_client () = + let open Lwt_result_syntax in let open Example.Client in (*String that has to be equal to the one of the smart contract/verify_update*) let key = "SaplingForTezosV1" in @@ -366,7 +370,7 @@ let test_simple_client () = let addr_b = new_address wb in (*a gives 2 to b and 1 (of change) to himself with 3 transparent money*) let (t1, wa) = pay wa addr_b 2L ~memo:"t1" 3L state key in - Example.Validator.verify_update t1 state key >>=? fun (balance, state) -> + let* (balance, state) = Example.Validator.verify_update t1 state key in assert (balance = -3L) ; let wb = scan wb state in assert (wb.balance = 2L) ; @@ -375,7 +379,7 @@ let test_simple_client () = let addr_a = new_address wa in (* b gives 1 to a and 1 (of change) to himself with 2 transparent money*) let (t2, wb) = pay wb addr_a 1L ~memo:"t2" 2L state key in - Example.Validator.verify_update t2 state key >>=? fun (balance, state) -> + let* (balance, state) = Example.Validator.verify_update t2 state key in assert (balance = -2L) ; (* before scanning b still has 2*) assert (wb.balance = 2L) ; @@ -386,7 +390,7 @@ let test_simple_client () = (* b gives 1 to a with shielded money *) let addr_a = new_address wa in let (t3, wb) = pay wb addr_a 1L ~memo:"t3" 0L state key in - Example.Validator.verify_update t3 state key >>=? fun (balance, state) -> + let* (balance, state) = Example.Validator.verify_update t3 state key in assert (balance = 0L) ; let wb = scan wb state in assert (wb.balance = 2L) ; @@ -396,7 +400,7 @@ let test_simple_client () = let addr_a = new_address wa in let (t4, wa) = pay wa addr_a 0L ~memo:"t4" Int64.minus_one state key in assert (wa.balance = 2L) ; - Example.Validator.verify_update t4 state key >>=? fun (balance, state) -> + let* (balance, state) = Example.Validator.verify_update t4 state key in assert (balance = 1L) ; let l_a = scan_ovk @@ -420,6 +424,7 @@ let test_simple_client () = (* We sign and verify with two different strings and check that it fails *) let test_replay () = + let open Lwt_result_syntax in let open Example.Client in let right_string = "SaplingForTezosV1" in let wrong_string = "SaplingForTezosVaezf1" in @@ -427,15 +432,15 @@ let test_replay () = let state = Storage.empty ~memo_size:2 in let addr = new_address wa in let (t1, _) = pay wa addr 2L ~memo:"t1" 3L state right_string in - Example.Validator.verify_update t1 state wrong_string >>= function - | Error _ -> return_unit - | _ -> assert false + let*! r = Example.Validator.verify_update t1 state wrong_string in + match r with Error _ -> return_unit | _ -> assert false (* A transaction is signed using "right" as bound_data and a different one with bound_data "wrong" and the same original signature is passed to verify_update. Verify_update should verify the signature and reject the modified transaction. *) let test_wrong_bound_data () = + let open Lwt_result_syntax in let open Example.Client in let key = "SaplingForTezosV1" in let wa = new_wallet (List.nth Keys.xsks 0) in @@ -443,7 +448,8 @@ let test_wrong_bound_data () = let addr = new_address wa in let (t1, _) = pay wa addr 2L ~memo:"t1" ~bound_data:"right" 3L state key in let t1_wrong = {t1 with bound_data = "wrong"} in - Example.Validator.verify_update t1_wrong state key >>= function + let*! r = Example.Validator.verify_update t1_wrong state key in + match r with | Error [Example.Validator.Binding_sig_incorrect _] -> return_unit | _ -> assert false From 000f3fad898775f1bbafff9aa6317302db0b53df Mon Sep 17 00:00:00 2001 From: Mehdi Bouaziz Date: Mon, 4 Oct 2021 09:38:13 +0200 Subject: [PATCH 057/100] Proto/Michelson: add a type parameter to ty This type parameter will be used to represent the comparable character of the type. Since `ty` represents any type, this parameter is universally quantified, except at a few places, where `to_be_replaced` is used for the moment. --- .../lib_benchmark/michelson_samplers.ml | 33 +-- .../lib_benchmark/michelson_samplers.mli | 2 +- .../lib_benchmark/test/test_distribution.ml | 2 +- .../interpreter_benchmarks.ml | 2 +- .../lib_benchmarks_proto/michelson_types.ml | 12 +- src/proto_alpha/lib_plugin/plugin.ml | 3 +- src/proto_alpha/lib_protocol/apply.ml | 4 +- .../lib_protocol/michelson_v1_gas.mli | 2 +- .../lib_protocol/script_interpreter.ml | 6 +- .../lib_protocol/script_interpreter.mli | 2 +- .../lib_protocol/script_interpreter_defs.ml | 8 +- .../lib_protocol/script_ir_translator.ml | 196 +++++++------- .../lib_protocol/script_ir_translator.mli | 64 +++-- .../lib_protocol/script_tc_context.ml | 4 +- .../lib_protocol/script_tc_context.mli | 8 +- .../lib_protocol/script_typed_ir.ml | 238 ++++++++++------ .../lib_protocol/script_typed_ir.mli | 253 ++++++++++-------- .../lib_protocol/script_typed_ir_size.ml | 14 +- .../lib_protocol/script_typed_ir_size.mli | 5 +- .../test/helpers/script_big_map.mli | 2 +- .../michelson/test_script_cache.ml | 3 +- .../michelson/test_script_typed_ir_size.ml | 4 +- .../michelson/test_typechecking.ml | 12 +- src/proto_alpha/lib_protocol/ticket_costs.mli | 2 +- .../lib_protocol/ticket_operations_diff.ml | 7 +- .../lib_protocol/ticket_scanner.ml | 28 +- .../lib_protocol/ticket_scanner.mli | 2 +- 27 files changed, 543 insertions(+), 375 deletions(-) diff --git a/src/proto_alpha/lib_benchmark/michelson_samplers.ml b/src/proto_alpha/lib_benchmark/michelson_samplers.ml index c8dbb91666..ad311af130 100644 --- a/src/proto_alpha/lib_benchmark/michelson_samplers.ml +++ b/src/proto_alpha/lib_benchmark/michelson_samplers.ml @@ -256,7 +256,7 @@ module type S = sig end module rec Random_value : sig - val value : 'a Script_typed_ir.ty -> 'a sampler + val value : ('a, _) Script_typed_ir.ty -> 'a sampler val comparable : 'a Script_typed_ir.comparable_ty -> 'a sampler @@ -489,7 +489,7 @@ end) (* Type-directed generation of random values. *) module rec Random_value : sig - val value : 'a Script_typed_ir.ty -> 'a sampler + val value : ('a, _) Script_typed_ir.ty -> 'a sampler val comparable : 'a Script_typed_ir.comparable_ty -> 'a sampler @@ -538,7 +538,7 @@ end) let signature rng_state = Script_signature.make (Michelson_base.signature rng_state) - let rec value : type a. a Script_typed_ir.ty -> a sampler = + let rec value : type a ac. (a, ac) Script_typed_ir.ty -> a sampler = let open Script_typed_ir in fun typ -> match typ with @@ -597,16 +597,17 @@ end) | Chest_t -> fail_sampling "Michelson_samplers: chest not handled yet" and generate_lambda : - type arg ret. - arg Script_typed_ir.ty -> - ret Script_typed_ir.ty -> + type arg argc ret retc. + (arg, argc) Script_typed_ir.ty -> + (ret, retc) Script_typed_ir.ty -> (arg, ret) Script_typed_ir.lambda sampler = fun _arg_ty _ret_ty _rng_state -> fail_sampling "Michelson_samplers: lambda not handled yet" and generate_list : - type elt. - elt Script_typed_ir.ty -> elt Script_typed_ir.boxed_list sampler = + type elt eltc. + (elt, eltc) Script_typed_ir.ty -> elt Script_typed_ir.boxed_list sampler + = fun elt_type -> let open M in let* (length, elements) = @@ -636,9 +637,9 @@ end) elements and generate_map : - type key elt. + type key elt eltc. key Script_typed_ir.comparable_ty -> - elt Script_typed_ir.ty -> + (elt, eltc) Script_typed_ir.ty -> (key, elt) Script_typed_ir.map sampler = fun key_ty elt_ty rng_state -> let size = @@ -654,9 +655,9 @@ end) elts and generate_big_map : - type key elt. + type key elt eltc. key Script_typed_ir.comparable_ty -> - elt Script_typed_ir.ty -> + (elt, eltc) Script_typed_ir.ty -> (key, elt) Script_typed_ir.big_map sampler = let open Script_typed_ir in fun key_ty elt_ty rng_state -> @@ -688,8 +689,9 @@ end) fail_sampling "raise_if_error" and generate_contract : - type arg. - arg Script_typed_ir.ty -> arg Script_typed_ir.typed_contract sampler = + type arg argc. + (arg, argc) Script_typed_ir.ty -> + arg Script_typed_ir.typed_contract sampler = fun arg_ty -> let open M in let* address = value address_t in @@ -726,7 +728,8 @@ end) | None -> assert false and generate_ticket : - type a. a Script_typed_ir.ty -> a Script_typed_ir.ticket sampler = + type a ac. + (a, ac) Script_typed_ir.ty -> a Script_typed_ir.ticket sampler = fun ty rng_state -> let contents = value ty rng_state in let ticketer = diff --git a/src/proto_alpha/lib_benchmark/michelson_samplers.mli b/src/proto_alpha/lib_benchmark/michelson_samplers.mli index b8833c70be..04894568be 100644 --- a/src/proto_alpha/lib_benchmark/michelson_samplers.mli +++ b/src/proto_alpha/lib_benchmark/michelson_samplers.mli @@ -79,7 +79,7 @@ module type S = sig supported types as listed at the beginning of this file. *) module rec Random_value : sig (** Sample a value given its type. *) - val value : 'a Script_typed_ir.ty -> 'a sampler + val value : ('a, _) Script_typed_ir.ty -> 'a sampler (** Sample a comparable value given its type. *) val comparable : 'a Script_typed_ir.comparable_ty -> 'a sampler diff --git a/src/proto_alpha/lib_benchmark/test/test_distribution.ml b/src/proto_alpha/lib_benchmark/test/test_distribution.ml index 2dee94ce5a..14cdb7a94c 100644 --- a/src/proto_alpha/lib_benchmark/test/test_distribution.ml +++ b/src/proto_alpha/lib_benchmark/test/test_distribution.ml @@ -55,7 +55,7 @@ module Type_name_multiset = Basic_structures.Basic_impl.Free_module.Float_valued.Make_with_map (Type_name) let rec tnames_of_type : - type a. a Script_typed_ir.ty -> type_name list -> type_name list = + type a ac. (a, ac) Script_typed_ir.ty -> type_name list -> type_name list = fun t acc -> match t with | Script_typed_ir.Unit_t -> `TUnit :: acc diff --git a/src/proto_alpha/lib_benchmarks_proto/interpreter_benchmarks.ml b/src/proto_alpha/lib_benchmarks_proto/interpreter_benchmarks.ml index 1a91337abe..aaf5cac030 100644 --- a/src/proto_alpha/lib_benchmarks_proto/interpreter_benchmarks.ml +++ b/src/proto_alpha/lib_benchmarks_proto/interpreter_benchmarks.ml @@ -43,7 +43,7 @@ type ex_stack_and_continuation = -> ex_stack_and_continuation type ex_value = - | Ex_value : {value : 'a; ty : 'a Script_typed_ir.ty} -> ex_value + | Ex_value : {value : 'a; ty : ('a, _) Script_typed_ir.ty} -> ex_value (* ------------------------------------------------------------------------- *) diff --git a/src/proto_alpha/lib_benchmarks_proto/michelson_types.ml b/src/proto_alpha/lib_benchmarks_proto/michelson_types.ml index 019736f39f..55504ceddb 100644 --- a/src/proto_alpha/lib_benchmarks_proto/michelson_types.ml +++ b/src/proto_alpha/lib_benchmarks_proto/michelson_types.ml @@ -98,7 +98,11 @@ let pair k1 k2 = (* (will become) comparable pair type constructor *) let cpair k1 k2 = - match pair_t (-1) k1 k2 with Error _ -> assert false | Ok (Ty_ex_c t) -> t + match pair_t (-1) k1 k2 with + | Error _ -> assert false + | Ok (Ty_ex_c t) -> + let Eq = is_comparable t in + (t : (_, to_be_replaced) ty) (* union type constructor*) let union k1 k2 = @@ -106,7 +110,11 @@ let union k1 k2 = (* (will become) comparable union type constructor *) let cunion k1 k2 = - match union_t (-1) k1 k2 with Error _ -> assert false | Ok (Ty_ex_c t) -> t + match union_t (-1) k1 k2 with + | Error _ -> assert false + | Ok (Ty_ex_c t) -> + let Eq = is_comparable t in + (t : (_, to_be_replaced) ty) let lambda x y = match lambda_t (-1) x y with Error _ -> assert false | Ok t -> t diff --git a/src/proto_alpha/lib_plugin/plugin.ml b/src/proto_alpha/lib_plugin/plugin.ml index 8e0fe2cf24..8492f4e922 100644 --- a/src/proto_alpha/lib_plugin/plugin.ml +++ b/src/proto_alpha/lib_plugin/plugin.ml @@ -2017,7 +2017,8 @@ module RPC = struct Int (loc, z) let rec unparse_ty : - type a loc. loc:loc -> a ty -> (loc, Script.prim) Micheline.node = + type a ac loc. + loc:loc -> (a, ac) ty -> (loc, Script.prim) Micheline.node = fun ~loc ty -> let return (name, args, annot) = Prim (loc, name, args, annot) in match ty with diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index aa21522186..8264047966 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -877,7 +877,9 @@ let apply_delegation ~ctxt ~source ~delegate ~since = (ctxt, Delegation_result {consumed_gas = Gas.consumed ~since ~until:ctxt}, []) type execution_arg = - | Typed_arg : Script.location * 'a Script_typed_ir.ty * 'a -> execution_arg + | Typed_arg : + Script.location * ('a, _) Script_typed_ir.ty * 'a + -> execution_arg | Untyped_arg : Script.expr -> execution_arg let apply_transaction_to_implicit ~ctxt ~contract ~parameter ~entrypoint diff --git a/src/proto_alpha/lib_protocol/michelson_v1_gas.mli b/src/proto_alpha/lib_protocol/michelson_v1_gas.mli index 0ab0e9bea5..15a04ef478 100644 --- a/src/proto_alpha/lib_protocol/michelson_v1_gas.mli +++ b/src/proto_alpha/lib_protocol/michelson_v1_gas.mli @@ -487,7 +487,7 @@ module Cost_of : sig val bls12_381_fr : Gas.cost - val unparse_type : 'a Script_typed_ir.ty -> Gas.cost + val unparse_type : ('a, _) Script_typed_ir.ty -> Gas.cost val unparse_comparable_type : 'a Script_typed_ir.comparable_ty -> Gas.cost diff --git a/src/proto_alpha/lib_protocol/script_interpreter.ml b/src/proto_alpha/lib_protocol/script_interpreter.ml index 44bf599995..70fb97fca2 100644 --- a/src/proto_alpha/lib_protocol/script_interpreter.ml +++ b/src/proto_alpha/lib_protocol/script_interpreter.ml @@ -1714,10 +1714,12 @@ let step logger ctxt step_constants descr stack = *) type execution_arg = - | Typed_arg : Script.location * 'a Script_typed_ir.ty * 'a -> execution_arg + | Typed_arg : + Script.location * ('a, _) Script_typed_ir.ty * 'a + -> execution_arg | Untyped_arg : Script.expr -> execution_arg -let lift_execution_arg (type a) ctxt ~internal (entrypoint_ty : a ty) +let lift_execution_arg (type a ac) ctxt ~internal (entrypoint_ty : (a, ac) ty) (box : a -> 'b) arg : ('b * context) tzresult Lwt.t = (match arg with | Untyped_arg arg -> diff --git a/src/proto_alpha/lib_protocol/script_interpreter.mli b/src/proto_alpha/lib_protocol/script_interpreter.mli index bfbde28e35..c57869e469 100644 --- a/src/proto_alpha/lib_protocol/script_interpreter.mli +++ b/src/proto_alpha/lib_protocol/script_interpreter.mli @@ -126,7 +126,7 @@ val execute_with_typed_parameter : step_constants -> script:Script.t -> entrypoint:Entrypoint.t -> - parameter_ty:'a Script_typed_ir.ty -> + parameter_ty:('a, _) Script_typed_ir.ty -> location:Script.location -> parameter:'a -> internal:bool -> diff --git a/src/proto_alpha/lib_protocol/script_interpreter_defs.ml b/src/proto_alpha/lib_protocol/script_interpreter_defs.ml index 3a0e161d00..7dbabb9d1c 100644 --- a/src/proto_alpha/lib_protocol/script_interpreter_defs.ml +++ b/src/proto_alpha/lib_protocol/script_interpreter_defs.ml @@ -510,9 +510,9 @@ let transfer (ctxt, sc) gas amount location parameters_ty parameters destination parameters submitted by the interpreter to prepare them for the [Transaction] operation. *) let craft_transfer_parameters : - type a. + type a ac. context -> - a ty -> + (a, ac) ty -> (location, prim) Micheline.node -> Destination.t -> ((location, prim) Micheline.node * context) tzresult = @@ -886,12 +886,12 @@ type ('a, 'b, 'c, 'd, 'e, 'f) ilsr_nat_type = type ifailwith_type = { ifailwith : - 'a 'b. + 'a 'ac 'b. logger option -> outdated_context * step_constants -> local_gas_counter -> Script.location -> - 'a ty -> + ('a, 'ac) ty -> 'a -> ('b, error trace) result Lwt.t; } diff --git a/src/proto_alpha/lib_protocol/script_ir_translator.ml b/src/proto_alpha/lib_protocol/script_ir_translator.ml index 313f14a5ab..c37024e5c0 100644 --- a/src/proto_alpha/lib_protocol/script_ir_translator.ml +++ b/src/proto_alpha/lib_protocol/script_ir_translator.ml @@ -161,7 +161,8 @@ let check_kind kinds expr = (everything that cannot contain a lambda). The rest is located at the end of the file. *) -let rec ty_of_comparable_ty : type a. a comparable_ty -> a ty = function +let rec ty_of_comparable_ty : type a. a comparable_ty -> (a, to_be_replaced) ty + = function | Unit_key -> Unit_t | Never_key -> Never_t | Int_key -> Int_t @@ -222,7 +223,8 @@ let unparse_memo_size ~loc memo_size = Int (loc, z) let rec unparse_ty_entrypoints_uncarbonated : - type a loc. loc:loc -> a ty -> a entrypoints -> loc Script.michelson_node = + type a ac loc. + loc:loc -> (a, ac) ty -> a entrypoints -> loc Script.michelson_node = fun ~loc ty {nested = nested_entrypoints; name = entrypoint_name} -> let (name, args) = match ty with @@ -332,8 +334,11 @@ let serialize_ty_for_error ty = unparse_ty_uncarbonated ~loc:() ty |> Micheline.strip_locations let[@coq_axiom_with_reason "gadt"] rec comparable_ty_of_ty : - type a. - context -> Script.location -> a ty -> (a comparable_ty * context) tzresult = + type a ac. + context -> + Script.location -> + (a, ac) ty -> + (a comparable_ty * context) tzresult = fun ctxt loc ty -> Gas.consume ctxt Typecheck_costs.comparable_ty_of_ty_cycle >>? fun ctxt -> match ty with @@ -675,7 +680,7 @@ let check_dupable_comparable_ty : type a. a comparable_ty -> unit = function () let check_dupable_ty ctxt loc ty = - let rec aux : type a. location -> a ty -> (unit, error) Gas_monad.t = + let rec aux : type a ac. location -> (a, ac) ty -> (unit, error) Gas_monad.t = fun loc ty -> let open Gas_monad.Syntax in let* () = Gas_monad.consume_gas Typecheck_costs.check_dupable_cycle in @@ -853,12 +858,12 @@ let memo_size_eq : (** Same as comparable_ty_eq but for any types. *) let ty_eq : - type a b error_trace. + type a ac b bc error_trace. error_details:error_trace error_details -> Script.location -> - a ty -> - b ty -> - ((a ty, b ty) eq, error_trace) Gas_monad.t = + (a, ac) ty -> + (b, bc) ty -> + (((a, ac) ty, (b, bc) ty) eq, error_trace) Gas_monad.t = fun ~error_details loc ty1 ty2 -> let type_metadata_eq meta1 meta2 = Gas_monad.of_result (type_metadata_eq ~error_details meta1 meta2) @@ -871,15 +876,19 @@ let ty_eq : Gas_monad.of_result (memo_size_eq ~error_details ms1 ms2) in let rec help : - type ta tb. ta ty -> tb ty -> ((ta ty, tb ty) eq, error_trace) Gas_monad.t - = + type ta tac tb tbc. + (ta, tac) ty -> + (tb, tbc) ty -> + (((ta, tac) ty, (tb, tbc) ty) eq, error_trace) Gas_monad.t = fun ty1 ty2 -> help0 ty1 ty2 |> Gas_monad.record_trace_eval ~error_details (fun () -> default_ty_eq_error ty1 ty2) and help0 : - type ta tb. ta ty -> tb ty -> ((ta ty, tb ty) eq, error_trace) Gas_monad.t - = + type ta tac tb tbc. + (ta, tac) ty -> + (tb, tbc) ty -> + (((ta, tac) ty, (tb, tbc) ty) eq, error_trace) Gas_monad.t = fun ty1 ty2 -> let open Gas_monad.Syntax in let* () = Gas_monad.consume_gas Typecheck_costs.merge_cycle in @@ -891,7 +900,7 @@ let ty_eq : | Informative -> trace_of_error @@ default_ty_eq_error ty1 ty2) in match (ty1, ty2) with - | (Unit_t, Unit_t) -> return (Eq : (ta ty, tb ty) eq) + | (Unit_t, Unit_t) -> return (Eq : ((ta, tac) ty, (tb, tbc) ty) eq) | (Unit_t, _) -> not_equal () | (Int_t, Int_t) -> return Eq | (Int_t, _) -> not_equal () @@ -933,56 +942,56 @@ let ty_eq : let* () = type_metadata_eq meta1 meta2 in let* Eq = help tar tbr in let+ Eq = comparable_ty_eq ~error_details tal tbl in - (Eq : (ta ty, tb ty) eq) + (Eq : ((ta, tac) ty, (tb, tbc) ty) eq) | (Map_t _, _) -> not_equal () | (Big_map_t (tal, tar, meta1), Big_map_t (tbl, tbr, meta2)) -> let* () = type_metadata_eq meta1 meta2 in let* Eq = help tar tbr in let+ Eq = comparable_ty_eq ~error_details tal tbl in - (Eq : (ta ty, tb ty) eq) + (Eq : ((ta, tac) ty, (tb, tbc) ty) eq) | (Big_map_t _, _) -> not_equal () | (Set_t (ea, meta1), Set_t (eb, meta2)) -> let* () = type_metadata_eq meta1 meta2 in let+ Eq = comparable_ty_eq ~error_details ea eb in - (Eq : (ta ty, tb ty) eq) + (Eq : ((ta, tac) ty, (tb, tbc) ty) eq) | (Set_t _, _) -> not_equal () | (Ticket_t (ea, meta1), Ticket_t (eb, meta2)) -> let* () = type_metadata_eq meta1 meta2 in let+ Eq = comparable_ty_eq ~error_details ea eb in - (Eq : (ta ty, tb ty) eq) + (Eq : ((ta, tac) ty, (tb, tbc) ty) eq) | (Ticket_t _, _) -> not_equal () | (Pair_t (tal, tar, meta1, _), Pair_t (tbl, tbr, meta2, _)) -> let* () = type_metadata_eq meta1 meta2 in let* Eq = help tal tbl in let+ Eq = help tar tbr in - (Eq : (ta ty, tb ty) eq) + (Eq : ((ta, tac) ty, (tb, tbc) ty) eq) | (Pair_t _, _) -> not_equal () | (Union_t (tal, tar, meta1, _), Union_t (tbl, tbr, meta2, _)) -> let* () = type_metadata_eq meta1 meta2 in let* Eq = help tal tbl in let+ Eq = help tar tbr in - (Eq : (ta ty, tb ty) eq) + (Eq : ((ta, tac) ty, (tb, tbc) ty) eq) | (Union_t _, _) -> not_equal () | (Lambda_t (tal, tar, meta1), Lambda_t (tbl, tbr, meta2)) -> let* () = type_metadata_eq meta1 meta2 in let* Eq = help tal tbl in let+ Eq = help tar tbr in - (Eq : (ta ty, tb ty) eq) + (Eq : ((ta, tac) ty, (tb, tbc) ty) eq) | (Lambda_t _, _) -> not_equal () | (Contract_t (tal, meta1), Contract_t (tbl, meta2)) -> let* () = type_metadata_eq meta1 meta2 in let+ Eq = help tal tbl in - (Eq : (ta ty, tb ty) eq) + (Eq : ((ta, tac) ty, (tb, tbc) ty) eq) | (Contract_t _, _) -> not_equal () | (Option_t (tva, meta1, _), Option_t (tvb, meta2, _)) -> let* () = type_metadata_eq meta1 meta2 in let+ Eq = help tva tvb in - (Eq : (ta ty, tb ty) eq) + (Eq : ((ta, tac) ty, (tb, tbc) ty) eq) | (Option_t _, _) -> not_equal () | (List_t (tva, meta1), List_t (tvb, meta2)) -> let* () = type_metadata_eq meta1 meta2 in let+ Eq = help tva tvb in - (Eq : (ta ty, tb ty) eq) + (Eq : ((ta, tac) ty, (tb, tbc) ty) eq) | (List_t _, _) -> not_equal () | (Sapling_state_t ms1, Sapling_state_t ms2) -> let+ () = memo_size_eq ms1 ms2 in @@ -1215,11 +1224,11 @@ let[@coq_struct "ty"] rec parse_comparable_ty : T_key; ] -type ex_ty = Ex_ty : 'a ty -> ex_ty +type ex_ty = Ex_ty : ('a, _) ty -> ex_ty type ex_parameter_ty_and_entrypoints = | Ex_parameter_ty_and_entrypoints : { - arg_type : 'a ty; + arg_type : ('a, _) ty; entrypoints : 'a entrypoints; } -> ex_parameter_ty_and_entrypoints @@ -1730,7 +1739,7 @@ let parse_storage_ty : | _ -> (parse_normal_storage_ty [@tailcall]) ctxt ~stack_depth ~legacy node let check_packable ~legacy loc root = - let rec check : type t. t ty -> unit tzresult = function + let rec check : type t tc. (t, tc) ty -> unit tzresult = function (* /!\ When adding new lazy storage kinds, be sure to return an error. /!\ Lazy storage should not be packable. *) | Big_map_t _ -> error (Unexpected_lazy_storage loc) @@ -1782,8 +1791,8 @@ type ('arg, 'storage) code = | Code : { code : (('arg, 'storage) pair, (operation boxed_list, 'storage) pair) lambda; - arg_type : 'arg ty; - storage_type : 'storage ty; + arg_type : ('arg, _) ty; + storage_type : ('storage, _) ty; views : view_map; entrypoints : 'arg entrypoints; code_size : Cache_memory_helpers.sint; @@ -1794,9 +1803,9 @@ type ex_script = | Ex_script : { code : (('arg, 'storage) pair, (operation boxed_list, 'storage) pair) lambda; - arg_type : 'arg ty; + arg_type : ('arg, _) ty; storage : 'storage; - storage_type : 'storage ty; + storage_type : ('storage, _) ty; views : view_map; entrypoints : 'arg entrypoints; code_size : Cache_memory_helpers.sint; @@ -1818,7 +1827,7 @@ type 'storage ex_view = type (_, _) dig_proof_argument = | Dig_proof_argument : ('x, 'a * 's, 'a, 's, 'b, 't, 'c, 'u) stack_prefix_preservation_witness - * 'x ty + * ('x, _) ty * ('c, 'u) stack_ty -> ('b, 't) dig_proof_argument @@ -1854,24 +1863,24 @@ type 'before uncomb_proof_argument = type 'before comb_get_proof_argument = | Comb_get_proof_argument : - ('before, 'after) comb_get_gadt_witness * 'after ty + ('before, 'after) comb_get_gadt_witness * ('after, _) ty -> 'before comb_get_proof_argument type ('rest, 'before) comb_set_proof_argument = | Comb_set_proof_argument : - ('rest, 'before, 'after) comb_set_gadt_witness * 'after ty + ('rest, 'before, 'after) comb_set_gadt_witness * ('after, _) ty -> ('rest, 'before) comb_set_proof_argument type 'before dup_n_proof_argument = | Dup_n_proof_argument : - ('before, 'a) dup_n_gadt_witness * 'a ty + ('before, 'a) dup_n_gadt_witness * ('a, _) ty -> 'before dup_n_proof_argument let rec make_dug_proof_argument : - type a s x. + type a s x xc. location -> int -> - x ty -> + (x, xc) ty -> (a, s) stack_ty -> (a, s, x) dug_proof_argument option = fun loc n x stk -> @@ -1885,7 +1894,7 @@ let rec make_dug_proof_argument : | (_, _) -> None let rec make_comb_get_proof_argument : - type b. int -> b ty -> b comb_get_proof_argument option = + type b bc. int -> (b, bc) ty -> b comb_get_proof_argument option = fun n ty -> match (n, ty) with | (0, value_ty) -> Some (Comb_get_proof_argument (Comb_get_zero, value_ty)) @@ -1899,13 +1908,13 @@ let rec make_comb_get_proof_argument : | _ -> None let rec make_comb_set_proof_argument : - type value before a s. + type value valuec before beforec a s. context -> (a, s) stack_ty -> location -> int -> - value ty -> - before ty -> + (value, valuec) ty -> + (before, beforec) ty -> (value, before) comb_set_proof_argument tzresult = fun ctxt stack_ty loc n value_ty ty -> match (n, ty) with @@ -1922,17 +1931,19 @@ let rec make_comb_set_proof_argument : let whole_stack = serialize_stack_for_error ctxt stack_ty in error (Bad_stack (loc, I_UPDATE, 2, whole_stack)) -type 'a ex_ty_cstr = Ex_ty_cstr : 'b ty * ('b -> 'a) -> 'a ex_ty_cstr +type 'a ex_ty_cstr = Ex_ty_cstr : ('b, _) ty * ('b -> 'a) -> 'a ex_ty_cstr -let find_entrypoint (type full error_trace) - ~(error_details : error_trace error_details) (full : full ty) +let find_entrypoint (type full fullc error_trace) + ~(error_details : error_trace error_details) (full : (full, fullc) ty) (entrypoints : full entrypoints) entrypoint : (full ex_ty_cstr, error_trace) Gas_monad.t = let open Gas_monad.Syntax in let rec find_entrypoint : - type t. - t ty -> t entrypoints -> Entrypoint.t -> (t ex_ty_cstr, unit) Gas_monad.t - = + type t tc. + (t, tc) ty -> + t entrypoints -> + Entrypoint.t -> + (t ex_ty_cstr, unit) Gas_monad.t = fun ty entrypoints entrypoint -> let* () = Gas_monad.consume_gas Typecheck_costs.find_entrypoint_cycle in match (ty, entrypoints) with @@ -1960,9 +1971,10 @@ let find_entrypoint (type full error_trace) | Fast -> (Inconsistent_types_fast : error_trace) | Informative -> trace_of_error @@ No_such_entrypoint entrypoint) -let find_entrypoint_for_type (type full exp error_trace) ~error_details - ~(full : full ty) ~(expected : exp ty) entrypoints entrypoint loc : - (Entrypoint.t * exp ty, error_trace) Gas_monad.t = +let find_entrypoint_for_type (type full fullc exp expc error_trace) + ~error_details ~(full : (full, fullc) ty) ~(expected : (exp, expc) ty) + entrypoints entrypoint loc : + (Entrypoint.t * (exp, expc) ty, error_trace) Gas_monad.t = let open Gas_monad.Syntax in let* res = find_entrypoint ~error_details full entrypoints entrypoint in match res with @@ -1972,17 +1984,18 @@ let find_entrypoint_for_type (type full exp error_trace) ~error_details Gas_monad.bind_recover (ty_eq ~error_details:Fast loc ty expected) (function - | Ok Eq -> return (Entrypoint.default, (ty : exp ty)) + | Ok Eq -> return (Entrypoint.default, (ty : (exp, expc) ty)) | Error Inconsistent_types_fast -> let+ Eq = ty_eq ~error_details loc full expected in - (Entrypoint.root, (full : exp ty))) + (Entrypoint.root, (full : (exp, expc) ty))) | _ -> let+ Eq = ty_eq ~error_details loc ty expected in - (entrypoint, (ty : exp ty))) + (entrypoint, (ty : (exp, expc) ty))) -let well_formed_entrypoints (type full) (full : full ty) entrypoints = - let merge path (type t) (ty : t ty) (entrypoints : t entrypoints) reachable - ((first_unreachable, all) as acc) = +let well_formed_entrypoints (type full fullc) (full : (full, fullc) ty) + entrypoints = + let merge path (type t tc) (ty : (t, tc) ty) (entrypoints : t entrypoints) + reachable ((first_unreachable, all) as acc) = match entrypoints.name with | None -> ok @@ -2000,8 +2013,8 @@ let well_formed_entrypoints (type full) (full : full ty) entrypoints = else ok ((first_unreachable, Entrypoint.Set.add name all), true) in let rec check : - type t. - t ty -> + type t tc. + (t, tc) ty -> t entrypoints -> prim list -> bool -> @@ -2491,7 +2504,8 @@ let[@coq_axiom_with_reason "gadt"] rec parse_comparable_data : (* -- parse data of any type -- *) -let comb_witness1 : type t. t ty -> (t, unit -> unit) comb_witness = function +let comb_witness1 : type t tc. (t, tc) ty -> (t, unit -> unit) comb_witness = + function | Pair_t _ -> Comb_Pair Comb_Any | _ -> Comb_Any @@ -2509,13 +2523,13 @@ let comb_witness1 : type t. t ty -> (t, unit -> unit) comb_witness = function *) let[@coq_axiom_with_reason "gadt"] rec parse_data : - type a. + type a ac. ?type_logger:type_logger -> stack_depth:int -> context -> legacy:bool -> allow_forged:bool -> - a ty -> + (a, ac) ty -> Script.node -> (a * context) tzresult Lwt.t = fun ?type_logger ~stack_depth ctxt ~legacy ~allow_forged ty script_data -> @@ -2953,11 +2967,11 @@ let[@coq_axiom_with_reason "gadt"] rec parse_data : traced_fail (Invalid_kind (location expr, [Bytes_kind], kind expr)) and parse_view_returning : - type storage. + type storage storagec. ?type_logger:type_logger -> context -> legacy:bool -> - storage ty -> + (storage, storagec) ty -> view -> (storage ex_view * context) tzresult Lwt.t = fun ?type_logger ctxt ~legacy storage_type {input_ty; output_ty; view_code} -> @@ -3013,11 +3027,11 @@ and parse_view_returning : | _ -> error (ill_type_view loc aft ())) and typecheck_views : - type storage. + type storage storagec. ?type_logger:type_logger -> context -> legacy:bool -> - storage ty -> + (storage, storagec) ty -> view_map -> context tzresult Lwt.t = fun ?type_logger ctxt ~legacy storage_type views -> @@ -3028,14 +3042,14 @@ and typecheck_views : Script_map.fold_es aux views ctxt and[@coq_axiom_with_reason "gadt"] parse_returning : - type arg ret. + type arg argc ret retc. ?type_logger:type_logger -> stack_depth:int -> tc_context -> context -> legacy:bool -> - arg ty -> - ret ty -> + (arg, argc) ty -> + (ret, retc) ty -> Script.node -> ((arg, ret) lambda * context) tzresult Lwt.t = fun ?type_logger ~stack_depth tc_context ctxt ~legacy arg ret script_instr -> @@ -3080,8 +3094,8 @@ and[@coq_axiom_with_reason "gadt"] parse_instr : (a, s) stack_ty -> ((a, s) judgement * context) tzresult Lwt.t = fun ?type_logger ~stack_depth tc_context ctxt ~legacy script_instr stack_ty -> - let check_item_ty (type a b) ctxt (exp : a ty) (got : b ty) loc name n m : - ((a, b) eq * context) tzresult = + let check_item_ty (type a ac b bc) ctxt (exp : (a, ac) ty) (got : (b, bc) ty) + loc name n m : ((a, b) eq * context) tzresult = record_trace_eval (fun () -> let stack_ty = serialize_stack_for_error ctxt stack_ty in Bad_stack (loc, name, m, stack_ty)) @@ -5109,11 +5123,11 @@ and[@coq_axiom_with_reason "gadt"] parse_instr : ] and[@coq_axiom_with_reason "complex mutually recursive definition"] parse_contract : - type arg. + type arg argc. stack_depth:int -> context -> Script.location -> - arg ty -> + (arg, argc) ty -> Destination.t -> entrypoint:Entrypoint.t -> (context * arg typed_contract) tzresult Lwt.t = @@ -5304,10 +5318,10 @@ and parse_toplevel : returned and some overapproximation of the typechecking gas is consumed. This can still fail on gas exhaustion. *) let parse_contract_for_script : - type arg. + type arg argc. context -> Script.location -> - arg ty -> + (arg, argc) ty -> Destination.t -> entrypoint:Entrypoint.t -> (context * arg typed_contract option) tzresult Lwt.t = @@ -5468,7 +5482,7 @@ let parse_storage : context -> legacy:bool -> allow_forged:bool -> - 'storage ty -> + ('storage, _) ty -> storage:lazy_expr -> ('storage * context) tzresult Lwt.t = fun ?type_logger ctxt ~legacy ~allow_forged storage_type ~storage -> @@ -5569,10 +5583,10 @@ let typecheck_code : trace (Ill_typed_contract (code, !type_map)) views_result >|=? fun ctxt -> (!type_map, ctxt) -let list_entrypoints ctxt (type full) (full : full ty) +let list_entrypoints ctxt (type full fullc) (full : (full, fullc) ty) (entrypoints : full entrypoints) = - let merge path (type t) (ty : t ty) (entrypoints : t entrypoints) reachable - ((unreachables, all) as acc) = + let merge path (type t tc) (ty : (t, tc) ty) (entrypoints : t entrypoints) + reachable ((unreachables, all) as acc) = match entrypoints.name with | None -> ok @@ -5592,8 +5606,8 @@ let list_entrypoints ctxt (type full) (full : full ty) >|? fun unreachable_all -> (unreachable_all, true) in let rec fold_tree : - type t. - t ty -> + type t tc. + (t, tc) ty -> t entrypoints -> prim list -> bool -> @@ -5626,18 +5640,18 @@ let list_entrypoints ctxt (type full) (full : full ty) (* -- Unparsing data of any type -- *) -let comb_witness2 : type t. t ty -> (t, unit -> unit -> unit) comb_witness = - function +let comb_witness2 : + type t tc. (t, tc) ty -> (t, unit -> unit -> unit) comb_witness = function | Pair_t (_, Pair_t _, _, _) -> Comb_Pair (Comb_Pair Comb_Any) | Pair_t _ -> Comb_Pair Comb_Any | _ -> Comb_Any let[@coq_axiom_with_reason "gadt"] rec unparse_data : - type a. + type a ac. context -> stack_depth:int -> unparsing_mode -> - a ty -> + (a, ac) ty -> a -> (Script.node * context) tzresult Lwt.t = fun ctxt ~stack_depth mode ty a -> @@ -5819,12 +5833,12 @@ let[@coq_axiom_with_reason "gadt"] rec unparse_data : Script_timelock.chest_encoding and unparse_items : - type k v. + type k v vc. context -> stack_depth:int -> unparsing_mode -> k comparable_ty -> - v ty -> + (v, vc) ty -> (k * v) list -> (Script.node list * context) tzresult Lwt.t = fun ctxt ~stack_depth mode kt vt items -> @@ -6130,7 +6144,7 @@ type 'ty has_lazy_storage = the types, which happen to be literally written types, so the gas for them has already been paid. *) -let rec has_lazy_storage : type t. t ty -> t has_lazy_storage = +let rec has_lazy_storage : type t tc. (t, tc) ty -> t has_lazy_storage = fun ty -> let aux1 cons t = match has_lazy_storage t with False_f -> False_f | h -> cons h @@ -6187,13 +6201,13 @@ let rec has_lazy_storage : type t. t ty -> t has_lazy_storage = let[@coq_axiom_with_reason "gadt"] extract_lazy_storage_updates ctxt mode ~temporary ids_to_copy acc ty x = let rec aux : - type a. + type a ac. context -> unparsing_mode -> temporary:bool -> Lazy_storage.IdSet.t -> Lazy_storage.diffs -> - a ty -> + (a, ac) ty -> a -> has_lazy_storage:a has_lazy_storage -> (context * a * Lazy_storage.IdSet.t * Lazy_storage.diffs) tzresult Lwt.t = @@ -6297,11 +6311,11 @@ end [unit] type for [error] if you are in a case where errors are impossible. *) let[@coq_axiom_with_reason "gadt"] rec fold_lazy_storage : - type a error. + type a ac error. f:('acc, error) Fold_lazy_storage.result Lazy_storage.IdSet.fold_f -> init:'acc -> context -> - a ty -> + (a, ac) ty -> a -> has_lazy_storage:a has_lazy_storage -> (('acc, error) Fold_lazy_storage.result * context) tzresult = diff --git a/src/proto_alpha/lib_protocol/script_ir_translator.mli b/src/proto_alpha/lib_protocol/script_ir_translator.mli index abc745a7aa..190012ad8c 100644 --- a/src/proto_alpha/lib_protocol/script_ir_translator.mli +++ b/src/proto_alpha/lib_protocol/script_ir_translator.mli @@ -70,11 +70,11 @@ type ('ta, 'tb) eq = Eq : ('same, 'same) eq type ex_comparable_ty = | Ex_comparable_ty : 'a Script_typed_ir.comparable_ty -> ex_comparable_ty -type ex_ty = Ex_ty : 'a Script_typed_ir.ty -> ex_ty +type ex_ty = Ex_ty : ('a, _) Script_typed_ir.ty -> ex_ty type ex_parameter_ty_and_entrypoints = | Ex_parameter_ty_and_entrypoints : { - arg_type : 'a Script_typed_ir.ty; + arg_type : ('a, _) Script_typed_ir.ty; entrypoints : 'a Script_typed_ir.entrypoints; } -> ex_parameter_ty_and_entrypoints @@ -90,9 +90,9 @@ type ex_script = 'storage ) Script_typed_ir.pair ) Script_typed_ir.lambda; - arg_type : 'arg Script_typed_ir.ty; + arg_type : ('arg, _) Script_typed_ir.ty; storage : 'storage; - storage_type : 'storage Script_typed_ir.ty; + storage_type : ('storage, _) Script_typed_ir.ty; views : Script_typed_ir.view_map; entrypoints : 'arg Script_typed_ir.entrypoints; code_size : Cache_memory_helpers.sint; @@ -114,8 +114,8 @@ type ('arg, 'storage) code = 'storage ) Script_typed_ir.pair ) Script_typed_ir.lambda; - arg_type : 'arg Script_typed_ir.ty; - storage_type : 'storage Script_typed_ir.ty; + arg_type : ('arg, _) Script_typed_ir.ty; + storage_type : ('storage, _) Script_typed_ir.ty; views : Script_typed_ir.view_map; entrypoints : 'arg Script_typed_ir.entrypoints; code_size : Cache_memory_helpers.sint; @@ -181,7 +181,7 @@ type type_logger = (** Create an empty big_map *) val empty_big_map : 'a Script_typed_ir.comparable_ty -> - 'b Script_typed_ir.ty -> + ('b, _) Script_typed_ir.ty -> ('a, 'b) Script_typed_ir.big_map val big_map_mem : @@ -219,9 +219,11 @@ val big_map_get_and_update : val ty_eq : error_details:'error_trace error_details -> Script.location -> - 'a Script_typed_ir.ty -> - 'b Script_typed_ir.ty -> - (('a Script_typed_ir.ty, 'b Script_typed_ir.ty) eq, 'error_trace) Gas_monad.t + ('a, 'ac) Script_typed_ir.ty -> + ('b, 'bc) Script_typed_ir.ty -> + ( (('a, 'ac) Script_typed_ir.ty, ('b, 'bc) Script_typed_ir.ty) eq, + 'error_trace ) + Gas_monad.t (** {3 Parsing and Typechecking Michelson} *) val parse_comparable_data : @@ -236,14 +238,14 @@ val parse_data : context -> legacy:bool -> allow_forged:bool -> - 'a Script_typed_ir.ty -> + ('a, _) Script_typed_ir.ty -> Script.node -> ('a * context) tzresult Lwt.t val unparse_data : context -> unparsing_mode -> - 'a Script_typed_ir.ty -> + ('a, _) Script_typed_ir.ty -> 'a -> (Script.node * context) tzresult Lwt.t @@ -310,7 +312,7 @@ val parse_view_returning : ?type_logger:type_logger -> context -> legacy:bool -> - 'storage Script_typed_ir.ty -> + ('storage, _) Script_typed_ir.ty -> Script_typed_ir.view -> ('storage ex_view * context) tzresult Lwt.t @@ -318,7 +320,7 @@ val typecheck_views : ?type_logger:type_logger -> context -> legacy:bool -> - 'storage Script_typed_ir.ty -> + ('storage, _) Script_typed_ir.ty -> Script_typed_ir.view_map -> context tzresult Lwt.t @@ -344,7 +346,7 @@ val parse_ty : val unparse_ty : loc:'loc -> context -> - 'a Script_typed_ir.ty -> + ('a, _) Script_typed_ir.ty -> ('loc Script.michelson_node * context) tzresult val unparse_comparable_ty : @@ -354,7 +356,8 @@ val unparse_comparable_ty : ('loc Script.michelson_node * context) tzresult val ty_of_comparable_ty : - 'a Script_typed_ir.comparable_ty -> 'a Script_typed_ir.ty + 'a Script_typed_ir.comparable_ty -> + ('a, Script_typed_ir.to_be_replaced) Script_typed_ir.ty val parse_toplevel : context -> legacy:bool -> Script.expr -> (toplevel * context) tzresult Lwt.t @@ -362,7 +365,7 @@ val parse_toplevel : val unparse_parameter_ty : loc:'loc -> context -> - 'a Script_typed_ir.ty -> + ('a, _) Script_typed_ir.ty -> entrypoints:'a Script_typed_ir.entrypoints -> ('loc Script.michelson_node * context) tzresult @@ -378,7 +381,7 @@ val typecheck_code : Script.expr -> (type_map * context) tzresult Lwt.t -val serialize_ty_for_error : 'a Script_typed_ir.ty -> Script.expr +val serialize_ty_for_error : ('a, _) Script_typed_ir.ty -> Script.expr val parse_code : ?type_logger:type_logger -> @@ -392,7 +395,7 @@ val parse_storage : context -> legacy:bool -> allow_forged:bool -> - 'storage Script_typed_ir.ty -> + ('storage, _) Script_typed_ir.ty -> storage:Script.lazy_expr -> ('storage * context) tzresult Lwt.t @@ -412,7 +415,7 @@ val unparse_script : val parse_contract : context -> Script.location -> - 'a Script_typed_ir.ty -> + ('a, _) Script_typed_ir.ty -> Destination.t -> entrypoint:Entrypoint.t -> (context * 'a Script_typed_ir.typed_contract) tzresult Lwt.t @@ -420,7 +423,7 @@ val parse_contract : val parse_contract_for_script : context -> Script.location -> - 'a Script_typed_ir.ty -> + ('a, _) Script_typed_ir.ty -> Destination.t -> entrypoint:Entrypoint.t -> (context * 'a Script_typed_ir.typed_contract option) tzresult Lwt.t @@ -436,18 +439,18 @@ val parse_tx_rollup_deposit_parameters : existential. Typically, it will be used to go from the type of an entry-point to the full type of a contract. *) type 'a ex_ty_cstr = - | Ex_ty_cstr : 'b Script_typed_ir.ty * ('b -> 'a) -> 'a ex_ty_cstr + | Ex_ty_cstr : ('b, _) Script_typed_ir.ty * ('b -> 'a) -> 'a ex_ty_cstr val find_entrypoint : error_details:'error_trace error_details -> - 't Script_typed_ir.ty -> + ('t, _) Script_typed_ir.ty -> 't Script_typed_ir.entrypoints -> Entrypoint.t -> ('t ex_ty_cstr, 'error_trace) Gas_monad.t val list_entrypoints : context -> - 't Script_typed_ir.ty -> + ('t, _) Script_typed_ir.ty -> 't Script_typed_ir.entrypoints -> (Michelson_v1_primitives.prim list list * (Michelson_v1_primitives.prim list * Script.unlocated_michelson_node) @@ -455,7 +458,10 @@ val list_entrypoints : tzresult val pack_data : - context -> 'a Script_typed_ir.ty -> 'a -> (bytes * context) tzresult Lwt.t + context -> + ('a, _) Script_typed_ir.ty -> + 'a -> + (bytes * context) tzresult Lwt.t val hash_comparable_data : context -> @@ -465,7 +471,7 @@ val hash_comparable_data : val hash_data : context -> - 'a Script_typed_ir.ty -> + ('a, _) Script_typed_ir.ty -> 'a -> (Script_expr_hash.t * context) tzresult Lwt.t @@ -478,7 +484,7 @@ val no_lazy_storage_id : lazy_storage_ids *) val collect_lazy_storage : context -> - 'a Script_typed_ir.ty -> + ('a, _) Script_typed_ir.ty -> 'a -> (lazy_storage_ids * context) tzresult @@ -505,14 +511,14 @@ val extract_lazy_storage_diff : temporary:bool -> to_duplicate:lazy_storage_ids -> to_update:lazy_storage_ids -> - 'a Script_typed_ir.ty -> + ('a, _) Script_typed_ir.ty -> 'a -> ('a * Lazy_storage.diffs option * context) tzresult Lwt.t (* return [None] if none or more than one found *) val get_single_sapling_state : context -> - 'a Script_typed_ir.ty -> + ('a, _) Script_typed_ir.ty -> 'a -> (Sapling.Id.t option * context) tzresult diff --git a/src/proto_alpha/lib_protocol/script_tc_context.ml b/src/proto_alpha/lib_protocol/script_tc_context.ml index 2aab85e620..d0b4609e3b 100644 --- a/src/proto_alpha/lib_protocol/script_tc_context.ml +++ b/src/proto_alpha/lib_protocol/script_tc_context.ml @@ -29,8 +29,8 @@ type in_lambda = bool type callsite = | Toplevel : { - storage_type : 'sto ty; - param_type : 'param ty; + storage_type : ('sto, _) ty; + param_type : ('param, _) ty; entrypoints : 'param Script_typed_ir.entrypoints; } -> callsite diff --git a/src/proto_alpha/lib_protocol/script_tc_context.mli b/src/proto_alpha/lib_protocol/script_tc_context.mli index 4f4255a171..14f907133e 100644 --- a/src/proto_alpha/lib_protocol/script_tc_context.mli +++ b/src/proto_alpha/lib_protocol/script_tc_context.mli @@ -48,8 +48,8 @@ type in_lambda = bool instructions for example). *) type callsite = | Toplevel : { - storage_type : 'sto ty; - param_type : 'param ty; + storage_type : ('sto, _) ty; + param_type : ('param, _) ty; entrypoints : 'param Script_typed_ir.entrypoints; } -> callsite @@ -61,8 +61,8 @@ type t = {callsite : callsite; in_lambda : in_lambda} val init : callsite -> t val toplevel : - storage_type:'sto ty -> - param_type:'param ty -> + storage_type:('sto, _) ty -> + param_type:('param, _) ty -> entrypoints:'param Script_typed_ir.entrypoints -> t diff --git a/src/proto_alpha/lib_protocol/script_typed_ir.ml b/src/proto_alpha/lib_protocol/script_typed_ir.ml index ed6a521f49..95278748b6 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir.ml +++ b/src/proto_alpha/lib_protocol/script_typed_ir.ml @@ -311,6 +311,8 @@ type end_of_stack = empty_cell * empty_cell type 'a ty_metadata = {size : 'a Type_size.t} [@@unboxed] +type (_, _) eq = Eq : ('a, 'a) eq + type _ comparable_ty = | Unit_key : unit comparable_ty | Never_key : never comparable_ty @@ -627,7 +629,7 @@ type ('before_top, 'before, 'result_top, 'result) kinstr = | IEmpty_big_map : ('a, 's) kinfo * 'b comparable_ty - * 'c ty + * ('c, _) ty * (('b, 'c) big_map, 'a * 's, 'r, 'f) kinstr -> ('a, 's, 'r, 'f) kinstr | IBig_map_mem : @@ -837,7 +839,7 @@ type ('before_top, 'before, 'result_top, 'result) kinstr = -> ('a, ('a, 'b) lambda * 's, 'r, 'f) kinstr | IApply : ('a, ('a * 'b, 'c) lambda * 's) kinfo - * 'a ty + * ('a, _) ty * (('b, 'c) lambda, 's, 'r, 'f) kinstr -> ('a, ('a * 'b, 'c) lambda * 's, 'r, 'f) kinstr | ILambda : @@ -846,7 +848,7 @@ type ('before_top, 'before, 'result_top, 'result) kinstr = * (('b, 'c) lambda, 'a * 's, 'r, 'f) kinstr -> ('a, 's, 'r, 'f) kinstr | IFailwith : - ('a, 's) kinfo * Script.location * 'a ty + ('a, 's) kinfo * Script.location * ('a, _) ty -> ('a, 's, 'r, 'f) kinstr (* Comparison @@ -886,7 +888,7 @@ type ('before_top, 'before, 'result_top, 'result) kinstr = -> ('a typed_contract, 's, 'r, 'f) kinstr | IContract : (address, 's) kinfo - * 'a ty + * ('a, _) ty * Entrypoint.t * ('a typed_contract option, 's, 'r, 'f) kinstr -> (address, 's, 'r, 'f) kinstr @@ -904,8 +906,8 @@ type ('before_top, 'before, 'result_top, 'result) kinstr = -> (public_key_hash, 's, 'r, 'f) kinstr | ICreate_contract : { kinfo : (public_key_hash option, Tez.t * ('a * 's)) kinfo; - storage_type : 'a ty; - arg_type : 'b ty; + storage_type : ('a, _) ty; + arg_type : ('b, _) ty; lambda : ('b * 'a, operation boxed_list * 'a) lambda; views : view_map; entrypoints : 'b entrypoints; @@ -934,10 +936,10 @@ type ('before_top, 'before, 'result_top, 'result) kinstr = (public_key, 's) kinfo * (public_key_hash, 's, 'r, 'f) kinstr -> (public_key, 's, 'r, 'f) kinstr | IPack : - ('a, 's) kinfo * 'a ty * (bytes, 's, 'r, 'f) kinstr + ('a, 's) kinfo * ('a, _) ty * (bytes, 's, 'r, 'f) kinstr -> ('a, 's, 'r, 'f) kinstr | IUnpack : - (bytes, 's) kinfo * 'a ty * ('a option, 's, 'r, 'f) kinstr + (bytes, 's) kinfo * ('a, _) ty * ('a option, 's, 'r, 'f) kinstr -> (bytes, 's, 'r, 'f) kinstr | IBlake2b : (bytes, 's) kinfo * (bytes, 's, 'r, 'f) kinstr @@ -956,7 +958,7 @@ type ('before_top, 'before, 'result_top, 'result) kinstr = -> ('a, 's, 'r, 'f) kinstr | ISelf : ('a, 's) kinfo - * 'b ty + * ('b, _) ty * Entrypoint.t * ('b typed_contract, 'a * 's, 'r, 'f) kinstr -> ('a, 's, 'r, 'f) kinstr @@ -1143,7 +1145,7 @@ and ('arg, 'ret) lambda = and 'arg typed_contract = | Typed_contract : { - arg_ty : 'arg ty; + arg_ty : ('arg, _) ty; address : address; } -> 'arg typed_contract @@ -1226,58 +1228,74 @@ and logger = { and to_be_replaced = unit (* ---- Auxiliary types -----------------------------------------------------*) -and 'ty ty = - | Unit_t : unit ty - | Int_t : z num ty - | Nat_t : n num ty - | Signature_t : signature ty - | String_t : Script_string.t ty - | Bytes_t : bytes ty - | Mutez_t : Tez.t ty - | Key_hash_t : public_key_hash ty - | Key_t : public_key ty - | Timestamp_t : Script_timestamp.t ty - | Address_t : address ty - | Tx_rollup_l2_address_t : tx_rollup_l2_address ty - | Bool_t : bool ty +and ('ty, 'comparable) ty = + | Unit_t : (unit, to_be_replaced) ty + | Int_t : (z num, to_be_replaced) ty + | Nat_t : (n num, to_be_replaced) ty + | Signature_t : (signature, to_be_replaced) ty + | String_t : (Script_string.t, to_be_replaced) ty + | Bytes_t : (bytes, to_be_replaced) ty + | Mutez_t : (Tez.t, to_be_replaced) ty + | Key_hash_t : (public_key_hash, to_be_replaced) ty + | Key_t : (public_key, to_be_replaced) ty + | Timestamp_t : (Script_timestamp.t, to_be_replaced) ty + | Address_t : (address, to_be_replaced) ty + | Tx_rollup_l2_address_t : (tx_rollup_l2_address, to_be_replaced) ty + | Bool_t : (bool, to_be_replaced) ty | Pair_t : - 'a ty * 'b ty * ('a, 'b) pair ty_metadata * to_be_replaced - -> ('a, 'b) pair ty + ('a, to_be_replaced) ty + * ('b, to_be_replaced) ty + * ('a, 'b) pair ty_metadata + * to_be_replaced + -> (('a, 'b) pair, to_be_replaced) ty | Union_t : - 'a ty * 'b ty * ('a, 'b) union ty_metadata * to_be_replaced - -> ('a, 'b) union ty + ('a, to_be_replaced) ty + * ('b, to_be_replaced) ty + * ('a, 'b) union ty_metadata + * to_be_replaced + -> (('a, 'b) union, to_be_replaced) ty | Lambda_t : - 'arg ty * 'ret ty * ('arg, 'ret) lambda ty_metadata - -> ('arg, 'ret) lambda ty - | Option_t : 'v ty * 'v option ty_metadata * to_be_replaced -> 'v option ty - | List_t : 'v ty * 'v boxed_list ty_metadata -> 'v boxed_list ty - | Set_t : 'v comparable_ty * 'v set ty_metadata -> 'v set ty + ('arg, _) ty * ('ret, _) ty * ('arg, 'ret) lambda ty_metadata + -> (('arg, 'ret) lambda, to_be_replaced) ty + | Option_t : + ('v, to_be_replaced) ty * 'v option ty_metadata * to_be_replaced + -> ('v option, to_be_replaced) ty + | List_t : + ('v, _) ty * 'v boxed_list ty_metadata + -> ('v boxed_list, to_be_replaced) ty + | Set_t : 'v comparable_ty * 'v set ty_metadata -> ('v set, to_be_replaced) ty | Map_t : - 'k comparable_ty * 'v ty * ('k, 'v) map ty_metadata - -> ('k, 'v) map ty + 'k comparable_ty * ('v, _) ty * ('k, 'v) map ty_metadata + -> (('k, 'v) map, to_be_replaced) ty | Big_map_t : - 'k comparable_ty * 'v ty * ('k, 'v) big_map ty_metadata - -> ('k, 'v) big_map ty + 'k comparable_ty * ('v, _) ty * ('k, 'v) big_map ty_metadata + -> (('k, 'v) big_map, to_be_replaced) ty | Contract_t : - 'arg ty * 'arg typed_contract ty_metadata - -> 'arg typed_contract ty - | Sapling_transaction_t : Sapling.Memo_size.t -> Sapling.transaction ty + ('arg, _) ty * 'arg typed_contract ty_metadata + -> ('arg typed_contract, to_be_replaced) ty + | Sapling_transaction_t : + Sapling.Memo_size.t + -> (Sapling.transaction, to_be_replaced) ty | Sapling_transaction_deprecated_t : Sapling.Memo_size.t - -> Sapling.Legacy.transaction ty - | Sapling_state_t : Sapling.Memo_size.t -> Sapling.state ty - | Operation_t : operation ty - | Chain_id_t : Script_chain_id.t ty - | Never_t : never ty - | Bls12_381_g1_t : Script_bls.G1.t ty - | Bls12_381_g2_t : Script_bls.G2.t ty - | Bls12_381_fr_t : Script_bls.Fr.t ty - | Ticket_t : 'a comparable_ty * 'a ticket ty_metadata -> 'a ticket ty - | Chest_key_t : Script_timelock.chest_key ty - | Chest_t : Script_timelock.chest ty + -> (Sapling.Legacy.transaction, to_be_replaced) ty + | Sapling_state_t : Sapling.Memo_size.t -> (Sapling.state, to_be_replaced) ty + | Operation_t : (operation, to_be_replaced) ty + | Chain_id_t : (Script_chain_id.t, to_be_replaced) ty + | Never_t : (never, to_be_replaced) ty + | Bls12_381_g1_t : (Script_bls.G1.t, to_be_replaced) ty + | Bls12_381_g2_t : (Script_bls.G2.t, to_be_replaced) ty + | Bls12_381_fr_t : (Script_bls.Fr.t, to_be_replaced) ty + | Ticket_t : + 'a comparable_ty * 'a ticket ty_metadata + -> ('a ticket, to_be_replaced) ty + | Chest_key_t : (Script_timelock.chest_key, to_be_replaced) ty + | Chest_t : (Script_timelock.chest, to_be_replaced) ty and ('top_ty, 'resty) stack_ty = - | Item_t : 'ty ty * ('ty2, 'rest) stack_ty -> ('ty, 'ty2 * 'rest) stack_ty + | Item_t : + ('ty, _) ty * ('ty2, 'rest) stack_ty + -> ('ty, 'ty2 * 'rest) stack_ty | Bot_t : (empty_cell, empty_cell) stack_ty and ('key, 'value) big_map = @@ -1285,7 +1303,7 @@ and ('key, 'value) big_map = id : Big_map.Id.t option; diff : ('key, 'value) big_map_overlay; key_type : 'key comparable_ty; - value_type : 'value ty; + value_type : ('value, _) ty; } -> ('key, 'value) big_map @@ -1349,8 +1367,8 @@ and (_, _) dup_n_gadt_witness = and ('input, 'output) view_signature = | View_signature : { name : Script_string.t; - input_ty : 'input ty; - output_ty : 'output ty; + input_ty : ('input, _) ty; + output_ty : ('output, _) ty; } -> ('input, 'output) view_signature @@ -1358,7 +1376,7 @@ and 'kind manager_operation = | Transaction : { transaction : Alpha_context.transaction; location : Script.location; - parameters_ty : 'a ty; + parameters_ty : ('a, _) ty; parameters : 'a; } -> Kind.transaction manager_operation @@ -1766,7 +1784,7 @@ let kinstr_rewritek : let meta_basic = {size = Type_size.one} -let ty_metadata : type a. a ty -> a ty_metadata = function +let ty_metadata : type a ac. (a, ac) ty -> a ty_metadata = function | Unit_t | Never_t | Int_t | Nat_t | Signature_t | String_t | Bytes_t | Mutez_t | Bool_t | Key_hash_t | Key_t | Timestamp_t | Chain_id_t | Address_t | Tx_rollup_l2_address_t -> @@ -1795,11 +1813,48 @@ let comparable_ty_metadata : type a. a comparable_ty -> a ty_metadata = function | Union_key (_, _, meta) -> meta | Option_key (_, meta) -> meta -let ty_size t = (ty_metadata t).size +let ty_size : type v vc. (v, vc) ty -> v Type_size.t = + fun t -> (ty_metadata t).size let comparable_ty_size t = (comparable_ty_metadata t).size -type 'v ty_ex_c = Ty_ex_c : 'v ty -> 'v ty_ex_c [@@ocaml.unboxed] +let is_comparable : type v c. (v, c) ty -> (c, to_be_replaced) eq = function + | Never_t -> Eq + | Unit_t -> Eq + | Int_t -> Eq + | Nat_t -> Eq + | Signature_t -> Eq + | String_t -> Eq + | Bytes_t -> Eq + | Mutez_t -> Eq + | Bool_t -> Eq + | Key_hash_t -> Eq + | Key_t -> Eq + | Timestamp_t -> Eq + | Chain_id_t -> Eq + | Address_t -> Eq + | Tx_rollup_l2_address_t -> Eq + | Pair_t _ -> Eq + | Union_t _ -> Eq + | Option_t _ -> Eq + | Lambda_t _ -> Eq + | List_t _ -> Eq + | Set_t _ -> Eq + | Map_t _ -> Eq + | Big_map_t _ -> Eq + | Ticket_t _ -> Eq + | Contract_t _ -> Eq + | Sapling_transaction_t _ -> Eq + | Sapling_transaction_deprecated_t _ -> Eq + | Sapling_state_t _ -> Eq + | Operation_t -> Eq + | Bls12_381_g1_t -> Eq + | Bls12_381_g2_t -> Eq + | Bls12_381_fr_t -> Eq + | Chest_t -> Eq + | Chest_key_t -> Eq + +type 'v ty_ex_c = Ty_ex_c : ('v, _) ty -> 'v ty_ex_c [@@ocaml.unboxed] let unit_t = Unit_t @@ -1853,8 +1908,14 @@ let tx_rollup_l2_address_t = Tx_rollup_l2_address_t let tx_rollup_l2_address_key = Tx_rollup_l2_address_key -let pair_t loc l r = +let pair_t : + type a ac b bc. + Script.location -> (a, ac) ty -> (b, bc) ty -> (a, b) pair ty_ex_c tzresult + = + fun loc l r -> Type_size.compound2 loc (ty_size l) (ty_size r) >|? fun size -> + let Eq = is_comparable l in + let Eq = is_comparable r in Ty_ex_c (Pair_t (l, r, {size}, ())) let pair_key loc l r = @@ -1863,8 +1924,14 @@ let pair_key loc l r = let pair_3_key loc l m r = pair_key loc m r >>? fun r -> pair_key loc l r -let union_t loc l r = +let union_t : + type a ac b bc. + Script.location -> (a, ac) ty -> (b, bc) ty -> (a, b) union ty_ex_c tzresult + = + fun loc l r -> Type_size.compound2 loc (ty_size l) (ty_size r) >|? fun size -> + let Eq = is_comparable l in + let Eq = is_comparable r in Ty_ex_c (Union_t (l, r, {size}, ())) let union_bytes_bool_t = Union_t (bytes_t, bool_t, {size = Type_size.three}, ()) @@ -1877,8 +1944,13 @@ let lambda_t loc l r = Type_size.compound2 loc (ty_size l) (ty_size r) >|? fun size -> Lambda_t (l, r, {size}) -let option_t loc t = - Type_size.compound1 loc (ty_size t) >|? fun size -> Option_t (t, {size}, ()) +let option_t : + type v c. + Script.location -> (v, c) ty -> (v option, to_be_replaced) ty tzresult = + fun loc t -> + Type_size.compound1 loc (ty_size t) >|? fun size -> + let Eq = is_comparable t in + Option_t (t, {size}, ()) let option_mutez_t = Option_t (mutez_t, {size = Type_size.two}, ()) @@ -2159,7 +2231,7 @@ let kinstr_traverse i init f = aux init i (fun accu -> accu) type 'a ty_traverse = { - apply : 't. 'a -> 't ty -> 'a; + apply : 't 'tc. 'a -> ('t, 'tc) ty -> 'a; apply_comparable : 't. 'a -> 't comparable_ty -> 'a; } @@ -2188,11 +2260,11 @@ let (ty_traverse, comparable_ty_traverse) = | Union_key (ty1, ty2, _) -> (next2 [@ocaml.tailcall]) ty1 ty2 | Option_key (ty, _) -> (next [@ocaml.tailcall]) ty and aux' : - type ret t accu. accu ty_traverse -> accu -> t ty -> (accu -> ret) -> ret - = + type ret t tc accu. + accu ty_traverse -> accu -> (t, tc) ty -> (accu -> ret) -> ret = fun f accu ty continue -> let accu = f.apply accu ty in - match (ty : t ty) with + match (ty : (t, tc) ty) with | Unit_t | Int_t | Nat_t | Signature_t | String_t | Bytes_t | Mutez_t | Key_hash_t | Key_t | Timestamp_t | Address_t | Tx_rollup_l2_address_t | Bool_t | Sapling_transaction_t _ | Sapling_transaction_deprecated_t _ @@ -2218,15 +2290,20 @@ let (ty_traverse, comparable_ty_traverse) = (next' [@ocaml.tailcall]) f accu ty1 continue | Contract_t (ty1, _) -> (next' [@ocaml.tailcall]) f accu ty1 continue and next2' : - type a b ret accu. - accu ty_traverse -> accu -> a ty -> b ty -> (accu -> ret) -> ret = + type a ac b bc ret accu. + accu ty_traverse -> + accu -> + (a, ac) ty -> + (b, bc) ty -> + (accu -> ret) -> + ret = fun f accu ty1 ty2 continue -> (aux' [@ocaml.tailcall]) f accu ty1 @@ fun accu -> (aux' [@ocaml.tailcall]) f accu ty2 @@ fun accu -> (continue [@ocaml.tailcall]) accu and next' : - type a ret accu. accu ty_traverse -> accu -> a ty -> (accu -> ret) -> ret - = + type a ac ret accu. + accu ty_traverse -> accu -> (a, ac) ty -> (accu -> ret) -> ret = fun f accu ty1 continue -> (aux' [@ocaml.tailcall]) f accu ty1 @@ fun accu -> (continue [@ocaml.tailcall]) accu @@ -2248,13 +2325,14 @@ let stack_ty_traverse (type a t) (sty : (a, t) stack_ty) init f = aux init sty type 'a value_traverse = { - apply : 't. 'a -> 't ty -> 't -> 'a; + apply : 't 'tc. 'a -> ('t, 'tc) ty -> 't -> 'a; apply_comparable : 't. 'a -> 't comparable_ty -> 't -> 'a; } -let value_traverse (type t) (ty : (t ty, t comparable_ty) union) (x : t) init f - = - let rec aux : type ret t. 'accu -> t ty -> t -> ('accu -> ret) -> ret = +let value_traverse (type t tc) (ty : ((t, tc) ty, t comparable_ty) union) + (x : t) init f = + let rec aux : type ret t tc. 'accu -> (t, tc) ty -> t -> ('accu -> ret) -> ret + = fun accu ty x continue -> let accu = f.apply accu ty x in let next2 ty1 ty2 x1 x2 = @@ -2315,9 +2393,13 @@ let value_traverse (type t) (ty : (t ty, t comparable_ty) union) (x : t) init f (aux' [@ocaml.tailcall]) accu ty' x @@ fun accu -> (on_list' [@ocaml.tailcall]) accu ty' xs continue and on_bindings : - type ret k v. - 'accu -> k comparable_ty -> v ty -> ('accu -> ret) -> (k * v) list -> ret - = + type ret k v vc. + 'accu -> + k comparable_ty -> + (v, vc) ty -> + ('accu -> ret) -> + (k * v) list -> + ret = fun accu kty ty' continue xs -> match xs with | [] -> (continue [@ocaml.tailcall]) accu diff --git a/src/proto_alpha/lib_protocol/script_typed_ir.mli b/src/proto_alpha/lib_protocol/script_typed_ir.mli index b6ee0aca6e..e9ad3c83e4 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir.mli +++ b/src/proto_alpha/lib_protocol/script_typed_ir.mli @@ -186,6 +186,8 @@ end type 'a ty_metadata = {size : 'a Type_size.t} [@@unboxed] +type (_, _) eq = Eq : ('a, 'a) eq + type _ comparable_ty = | Unit_key : unit comparable_ty | Never_key : never comparable_ty @@ -594,7 +596,7 @@ type ('before_top, 'before, 'result_top, 'result) kinstr = | IEmpty_big_map : ('a, 's) kinfo * 'b comparable_ty - * 'c ty + * ('c, _) ty * (('b, 'c) big_map, 'a * 's, 'r, 'f) kinstr -> ('a, 's, 'r, 'f) kinstr | IBig_map_mem : @@ -800,7 +802,7 @@ type ('before_top, 'before, 'result_top, 'result) kinstr = -> ('a, ('a, 'b) lambda * 's, 'r, 'f) kinstr | IApply : ('a, ('a * 'b, 'c) lambda * 's) kinfo - * 'a ty + * ('a, _) ty * (('b, 'c) lambda, 's, 'r, 'f) kinstr -> ('a, ('a * 'b, 'c) lambda * 's, 'r, 'f) kinstr | ILambda : @@ -809,7 +811,7 @@ type ('before_top, 'before, 'result_top, 'result) kinstr = * (('b, 'c) lambda, 'a * 's, 'r, 'f) kinstr -> ('a, 's, 'r, 'f) kinstr | IFailwith : - ('a, 's) kinfo * Script.location * 'a ty + ('a, 's) kinfo * Script.location * ('a, _) ty -> ('a, 's, 'r, 'f) kinstr (* Comparison @@ -849,7 +851,7 @@ type ('before_top, 'before, 'result_top, 'result) kinstr = -> ('a typed_contract, 's, 'r, 'f) kinstr | IContract : (address, 's) kinfo - * 'a ty + * ('a, _) ty * Entrypoint.t * ('a typed_contract option, 's, 'r, 'f) kinstr -> (address, 's, 'r, 'f) kinstr @@ -867,8 +869,8 @@ type ('before_top, 'before, 'result_top, 'result) kinstr = -> (public_key_hash, 's, 'r, 'f) kinstr | ICreate_contract : { kinfo : (public_key_hash option, Tez.t * ('a * 's)) kinfo; - storage_type : 'a ty; - arg_type : 'b ty; + storage_type : ('a, _) ty; + arg_type : ('b, _) ty; lambda : ('b * 'a, operation boxed_list * 'a) lambda; views : view_map; entrypoints : 'b entrypoints; @@ -897,10 +899,10 @@ type ('before_top, 'before, 'result_top, 'result) kinstr = (public_key, 's) kinfo * (public_key_hash, 's, 'r, 'f) kinstr -> (public_key, 's, 'r, 'f) kinstr | IPack : - ('a, 's) kinfo * 'a ty * (bytes, 's, 'r, 'f) kinstr + ('a, 's) kinfo * ('a, _) ty * (bytes, 's, 'r, 'f) kinstr -> ('a, 's, 'r, 'f) kinstr | IUnpack : - (bytes, 's) kinfo * 'a ty * ('a option, 's, 'r, 'f) kinstr + (bytes, 's) kinfo * ('a, _) ty * ('a option, 's, 'r, 'f) kinstr -> (bytes, 's, 'r, 'f) kinstr | IBlake2b : (bytes, 's) kinfo * (bytes, 's, 'r, 'f) kinstr @@ -919,7 +921,7 @@ type ('before_top, 'before, 'result_top, 'result) kinstr = -> ('a, 's, 'r, 'f) kinstr | ISelf : ('a, 's) kinfo - * 'b ty + * ('b, _) ty * Entrypoint.t * ('b typed_contract, 'a * 's, 'r, 'f) kinstr -> ('a, 's, 'r, 'f) kinstr @@ -1151,7 +1153,7 @@ and ('arg, 'ret) lambda = and 'arg typed_contract = | Typed_contract : { - arg_ty : 'arg ty; + arg_ty : ('arg, _) ty; address : address; } -> 'arg typed_contract @@ -1330,58 +1332,74 @@ and logger = { and to_be_replaced = unit (* ---- Auxiliary types -----------------------------------------------------*) -and 'ty ty = - | Unit_t : unit ty - | Int_t : z num ty - | Nat_t : n num ty - | Signature_t : signature ty - | String_t : Script_string.t ty - | Bytes_t : bytes ty - | Mutez_t : Tez.t ty - | Key_hash_t : public_key_hash ty - | Key_t : public_key ty - | Timestamp_t : Script_timestamp.t ty - | Address_t : address ty - | Tx_rollup_l2_address_t : tx_rollup_l2_address ty - | Bool_t : bool ty +and ('ty, 'comparable) ty = + | Unit_t : (unit, to_be_replaced) ty + | Int_t : (z num, to_be_replaced) ty + | Nat_t : (n num, to_be_replaced) ty + | Signature_t : (signature, to_be_replaced) ty + | String_t : (Script_string.t, to_be_replaced) ty + | Bytes_t : (bytes, to_be_replaced) ty + | Mutez_t : (Tez.t, to_be_replaced) ty + | Key_hash_t : (public_key_hash, to_be_replaced) ty + | Key_t : (public_key, to_be_replaced) ty + | Timestamp_t : (Script_timestamp.t, to_be_replaced) ty + | Address_t : (address, to_be_replaced) ty + | Tx_rollup_l2_address_t : (tx_rollup_l2_address, to_be_replaced) ty + | Bool_t : (bool, to_be_replaced) ty | Pair_t : - 'a ty * 'b ty * ('a, 'b) pair ty_metadata * to_be_replaced - -> ('a, 'b) pair ty + ('a, to_be_replaced) ty + * ('b, to_be_replaced) ty + * ('a, 'b) pair ty_metadata + * to_be_replaced + -> (('a, 'b) pair, to_be_replaced) ty | Union_t : - 'a ty * 'b ty * ('a, 'b) union ty_metadata * to_be_replaced - -> ('a, 'b) union ty + ('a, to_be_replaced) ty + * ('b, to_be_replaced) ty + * ('a, 'b) union ty_metadata + * to_be_replaced + -> (('a, 'b) union, to_be_replaced) ty | Lambda_t : - 'arg ty * 'ret ty * ('arg, 'ret) lambda ty_metadata - -> ('arg, 'ret) lambda ty - | Option_t : 'v ty * 'v option ty_metadata * to_be_replaced -> 'v option ty - | List_t : 'v ty * 'v boxed_list ty_metadata -> 'v boxed_list ty - | Set_t : 'v comparable_ty * 'v set ty_metadata -> 'v set ty + ('arg, _) ty * ('ret, _) ty * ('arg, 'ret) lambda ty_metadata + -> (('arg, 'ret) lambda, to_be_replaced) ty + | Option_t : + ('v, to_be_replaced) ty * 'v option ty_metadata * to_be_replaced + -> ('v option, to_be_replaced) ty + | List_t : + ('v, _) ty * 'v boxed_list ty_metadata + -> ('v boxed_list, to_be_replaced) ty + | Set_t : 'v comparable_ty * 'v set ty_metadata -> ('v set, to_be_replaced) ty | Map_t : - 'k comparable_ty * 'v ty * ('k, 'v) map ty_metadata - -> ('k, 'v) map ty + 'k comparable_ty * ('v, _) ty * ('k, 'v) map ty_metadata + -> (('k, 'v) map, to_be_replaced) ty | Big_map_t : - 'k comparable_ty * 'v ty * ('k, 'v) big_map ty_metadata - -> ('k, 'v) big_map ty + 'k comparable_ty * ('v, _) ty * ('k, 'v) big_map ty_metadata + -> (('k, 'v) big_map, to_be_replaced) ty | Contract_t : - 'arg ty * 'arg typed_contract ty_metadata - -> 'arg typed_contract ty - | Sapling_transaction_t : Sapling.Memo_size.t -> Sapling.transaction ty + ('arg, _) ty * 'arg typed_contract ty_metadata + -> ('arg typed_contract, to_be_replaced) ty + | Sapling_transaction_t : + Sapling.Memo_size.t + -> (Sapling.transaction, to_be_replaced) ty | Sapling_transaction_deprecated_t : Sapling.Memo_size.t - -> Sapling.Legacy.transaction ty - | Sapling_state_t : Sapling.Memo_size.t -> Sapling.state ty - | Operation_t : operation ty - | Chain_id_t : Script_chain_id.t ty - | Never_t : never ty - | Bls12_381_g1_t : Script_bls.G1.t ty - | Bls12_381_g2_t : Script_bls.G2.t ty - | Bls12_381_fr_t : Script_bls.Fr.t ty - | Ticket_t : 'a comparable_ty * 'a ticket ty_metadata -> 'a ticket ty - | Chest_key_t : Script_timelock.chest_key ty - | Chest_t : Script_timelock.chest ty + -> (Sapling.Legacy.transaction, to_be_replaced) ty + | Sapling_state_t : Sapling.Memo_size.t -> (Sapling.state, to_be_replaced) ty + | Operation_t : (operation, to_be_replaced) ty + | Chain_id_t : (Script_chain_id.t, to_be_replaced) ty + | Never_t : (never, to_be_replaced) ty + | Bls12_381_g1_t : (Script_bls.G1.t, to_be_replaced) ty + | Bls12_381_g2_t : (Script_bls.G2.t, to_be_replaced) ty + | Bls12_381_fr_t : (Script_bls.Fr.t, to_be_replaced) ty + | Ticket_t : + 'a comparable_ty * 'a ticket ty_metadata + -> ('a ticket, to_be_replaced) ty + | Chest_key_t : (Script_timelock.chest_key, to_be_replaced) ty + | Chest_t : (Script_timelock.chest, to_be_replaced) ty and ('top_ty, 'resty) stack_ty = - | Item_t : 'ty ty * ('ty2, 'rest) stack_ty -> ('ty, 'ty2 * 'rest) stack_ty + | Item_t : + ('ty, _) ty * ('ty2, 'rest) stack_ty + -> ('ty, 'ty2 * 'rest) stack_ty | Bot_t : (empty_cell, empty_cell) stack_ty and ('key, 'value) big_map = @@ -1389,7 +1407,7 @@ and ('key, 'value) big_map = id : Big_map.Id.t option; diff : ('key, 'value) big_map_overlay; key_type : 'key comparable_ty; - value_type : 'value ty; + value_type : ('value, _) ty; } -> ('key, 'value) big_map @@ -1487,8 +1505,8 @@ and (_, _) dup_n_gadt_witness = and ('input, 'output) view_signature = | View_signature : { name : Script_string.t; - input_ty : 'input ty; - output_ty : 'output ty; + input_ty : ('input, _) ty; + output_ty : ('output, _) ty; } -> ('input, 'output) view_signature @@ -1501,7 +1519,7 @@ and 'kind manager_operation = ([Apply_results.internal_manager_operation]). *) transaction : Alpha_context.transaction; location : Script.location; - parameters_ty : 'a ty; + parameters_ty : ('a, _) ty; parameters : 'a; } -> Kind.transaction manager_operation @@ -1542,11 +1560,13 @@ type kinstr_rewritek = { val kinstr_rewritek : ('a, 's, 'r, 'f) kinstr -> kinstr_rewritek -> ('a, 's, 'r, 'f) kinstr -val ty_size : 'a ty -> 'a Type_size.t +val ty_size : ('a, _) ty -> 'a Type_size.t val comparable_ty_size : 'a comparable_ty -> 'a Type_size.t -type 'v ty_ex_c = Ty_ex_c : 'v ty -> 'v ty_ex_c [@@ocaml.unboxed] +val is_comparable : ('v, 'c) ty -> ('c, to_be_replaced) eq + +type 'v ty_ex_c = Ty_ex_c : ('v, _) ty -> 'v ty_ex_c [@@ocaml.unboxed] val unit_key : unit comparable_ty @@ -1600,101 +1620,120 @@ val union_key : val option_key : Script.location -> 'v comparable_ty -> 'v option comparable_ty tzresult -val unit_t : unit ty +val unit_t : (unit, to_be_replaced) ty -val int_t : z num ty +val int_t : (z num, to_be_replaced) ty -val nat_t : n num ty +val nat_t : (n num, to_be_replaced) ty -val signature_t : signature ty +val signature_t : (signature, to_be_replaced) ty -val string_t : Script_string.t ty +val string_t : (Script_string.t, to_be_replaced) ty -val bytes_t : Bytes.t ty +val bytes_t : (Bytes.t, to_be_replaced) ty -val mutez_t : Tez.t ty +val mutez_t : (Tez.t, to_be_replaced) ty -val key_hash_t : public_key_hash ty +val key_hash_t : (public_key_hash, to_be_replaced) ty -val key_t : public_key ty +val key_t : (public_key, to_be_replaced) ty -val timestamp_t : Script_timestamp.t ty +val timestamp_t : (Script_timestamp.t, to_be_replaced) ty -val address_t : address ty +val address_t : (address, to_be_replaced) ty -val tx_rollup_l2_address_t : tx_rollup_l2_address ty +val tx_rollup_l2_address_t : (tx_rollup_l2_address, to_be_replaced) ty -val bool_t : bool ty +val bool_t : (bool, to_be_replaced) ty -val pair_t : Script.location -> 'a ty -> 'b ty -> ('a, 'b) pair ty_ex_c tzresult +val pair_t : + Script.location -> ('a, _) ty -> ('b, _) ty -> ('a, 'b) pair ty_ex_c tzresult val union_t : - Script.location -> 'a ty -> 'b ty -> ('a, 'b) union ty_ex_c tzresult + Script.location -> ('a, _) ty -> ('b, _) ty -> ('a, 'b) union ty_ex_c tzresult -val union_bytes_bool_t : (Bytes.t, bool) union ty +val union_bytes_bool_t : ((Bytes.t, bool) union, to_be_replaced) ty val lambda_t : - Script.location -> 'arg ty -> 'ret ty -> ('arg, 'ret) lambda ty tzresult + Script.location -> + ('arg, _) ty -> + ('ret, _) ty -> + (('arg, 'ret) lambda, to_be_replaced) ty tzresult -val option_t : Script.location -> 'v ty -> 'v option ty tzresult +val option_t : + Script.location -> ('v, 'c) ty -> ('v option, to_be_replaced) ty tzresult -val option_mutez_t : Tez.t option ty +val option_mutez_t : (Tez.t option, to_be_replaced) ty -val option_string_t : Script_string.t option ty +val option_string_t : (Script_string.t option, to_be_replaced) ty -val option_bytes_t : Bytes.t option ty +val option_bytes_t : (Bytes.t option, to_be_replaced) ty -val option_nat_t : n num option ty +val option_nat_t : (n num option, to_be_replaced) ty -val option_pair_nat_nat_t : (n num, n num) pair option ty +val option_pair_nat_nat_t : ((n num, n num) pair option, to_be_replaced) ty -val option_pair_nat_mutez_t : (n num, Tez.t) pair option ty +val option_pair_nat_mutez_t : ((n num, Tez.t) pair option, to_be_replaced) ty -val option_pair_mutez_mutez_t : (Tez.t, Tez.t) pair option ty +val option_pair_mutez_mutez_t : ((Tez.t, Tez.t) pair option, to_be_replaced) ty -val option_pair_int_nat_t : (z num, n num) pair option ty +val option_pair_int_nat_t : ((z num, n num) pair option, to_be_replaced) ty -val list_t : Script.location -> 'v ty -> 'v boxed_list ty tzresult +val list_t : + Script.location -> ('v, _) ty -> ('v boxed_list, to_be_replaced) ty tzresult -val list_operation_t : operation boxed_list ty +val list_operation_t : (operation boxed_list, to_be_replaced) ty -val set_t : Script.location -> 'v comparable_ty -> 'v set ty tzresult +val set_t : + Script.location -> 'v comparable_ty -> ('v set, to_be_replaced) ty tzresult val map_t : - Script.location -> 'k comparable_ty -> 'v ty -> ('k, 'v) map ty tzresult + Script.location -> + 'k comparable_ty -> + ('v, _) ty -> + (('k, 'v) map, to_be_replaced) ty tzresult val big_map_t : - Script.location -> 'k comparable_ty -> 'v ty -> ('k, 'v) big_map ty tzresult + Script.location -> + 'k comparable_ty -> + ('v, _) ty -> + (('k, 'v) big_map, to_be_replaced) ty tzresult -val contract_t : Script.location -> 'arg ty -> 'arg typed_contract ty tzresult +val contract_t : + Script.location -> + ('arg, _) ty -> + ('arg typed_contract, to_be_replaced) ty tzresult -val contract_unit_t : unit typed_contract ty +val contract_unit_t : (unit typed_contract, to_be_replaced) ty val sapling_transaction_t : - memo_size:Sapling.Memo_size.t -> Sapling.transaction ty + memo_size:Sapling.Memo_size.t -> (Sapling.transaction, to_be_replaced) ty val sapling_transaction_deprecated_t : - memo_size:Sapling.Memo_size.t -> Sapling.Legacy.transaction ty + memo_size:Sapling.Memo_size.t -> + (Sapling.Legacy.transaction, to_be_replaced) ty -val sapling_state_t : memo_size:Sapling.Memo_size.t -> Sapling.state ty +val sapling_state_t : + memo_size:Sapling.Memo_size.t -> (Sapling.state, to_be_replaced) ty -val operation_t : operation ty +val operation_t : (operation, to_be_replaced) ty -val chain_id_t : Script_chain_id.t ty +val chain_id_t : (Script_chain_id.t, to_be_replaced) ty -val never_t : never ty +val never_t : (never, to_be_replaced) ty -val bls12_381_g1_t : Script_bls.G1.t ty +val bls12_381_g1_t : (Script_bls.G1.t, to_be_replaced) ty -val bls12_381_g2_t : Script_bls.G2.t ty +val bls12_381_g2_t : (Script_bls.G2.t, to_be_replaced) ty -val bls12_381_fr_t : Script_bls.Fr.t ty +val bls12_381_fr_t : (Script_bls.Fr.t, to_be_replaced) ty -val ticket_t : Script.location -> 'a comparable_ty -> 'a ticket ty tzresult +val ticket_t : + Script.location -> 'a comparable_ty -> ('a ticket, to_be_replaced) ty tzresult -val chest_key_t : Script_timelock.chest_key ty +val chest_key_t : (Script_timelock.chest_key, to_be_replaced) ty -val chest_t : Script_timelock.chest ty +val chest_t : (Script_timelock.chest, to_be_replaced) ty (** @@ -1723,13 +1762,13 @@ val kinstr_traverse : ('a, 'b, 'c, 'd) kinstr -> 'ret -> 'ret kinstr_traverse -> 'ret type 'a ty_traverse = { - apply : 't. 'a -> 't ty -> 'a; + apply : 't 'tc. 'a -> ('t, 'tc) ty -> 'a; apply_comparable : 't. 'a -> 't comparable_ty -> 'a; } val comparable_ty_traverse : 'a comparable_ty -> 'r -> 'r ty_traverse -> 'r -val ty_traverse : 'a ty -> 'r -> 'r ty_traverse -> 'r +val ty_traverse : ('a, _) ty -> 'r -> 'r ty_traverse -> 'r type 'accu stack_ty_traverse = { apply : 'ty 's. 'accu -> ('ty, 's) stack_ty -> 'accu; @@ -1738,11 +1777,11 @@ type 'accu stack_ty_traverse = { val stack_ty_traverse : ('a, 's) stack_ty -> 'r -> 'r stack_ty_traverse -> 'r type 'a value_traverse = { - apply : 't. 'a -> 't ty -> 't -> 'a; + apply : 't 'tc. 'a -> ('t, 'tc) ty -> 't -> 'a; apply_comparable : 't. 'a -> 't comparable_ty -> 't -> 'a; } val value_traverse : - ('t ty, 't comparable_ty) union -> 't -> 'r -> 'r value_traverse -> 'r + (('t, _) ty, 't comparable_ty) union -> 't -> 'r -> 'r value_traverse -> 'r val stack_top_ty : ('a, 'b * 's) stack_ty -> 'a ty_ex_c diff --git a/src/proto_alpha/lib_protocol/script_typed_ir_size.ml b/src/proto_alpha/lib_protocol/script_typed_ir_size.ml index 8ffaabc9a1..261db9ea7f 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir_size.ml +++ b/src/proto_alpha/lib_protocol/script_typed_ir_size.ml @@ -66,7 +66,7 @@ let ty_traverse_f = ret_succ_adding accu @@ (base_compound a +! (word_size *? 2)) | Option_key (_ty, a) -> ret_succ_adding accu @@ (base_compound a +! word_size) - and apply : type a. nodes_and_size -> a ty -> nodes_and_size = + and apply : type a ac. nodes_and_size -> (a, ac) ty -> nodes_and_size = fun accu ty -> match ty with | Unit_t -> ret_succ_adding accu base_basic @@ -123,7 +123,7 @@ let ty_traverse_f = let comparable_ty_size : type a. a comparable_ty -> nodes_and_size = fun cty -> comparable_ty_traverse cty zero ty_traverse_f -let ty_size : type a. a ty -> nodes_and_size = +let ty_size : type a ac. (a, ac) ty -> nodes_and_size = fun ty -> ty_traverse ty zero ty_traverse_f let stack_ty_size s = @@ -262,14 +262,14 @@ let kinfo_size {iloc = _; kstack_ty = _} = h2w cannot be nested. (See [big_map_size].) For this reason, these functions should not trigger stack overflows. *) let rec value_size : - type a. + type a ac. count_lambda_nodes:bool -> nodes_and_size -> - (a ty, a comparable_ty) union -> + ((a, ac) ty, a comparable_ty) union -> a -> nodes_and_size = fun ~count_lambda_nodes accu ty x -> - let apply : type a. nodes_and_size -> a ty -> a -> nodes_and_size = + let apply : type a ac. nodes_and_size -> (a, ac) ty -> a -> nodes_and_size = fun accu ty x -> match ty with | Unit_t -> ret_succ accu @@ -354,11 +354,11 @@ let rec value_size : [@@coq_axiom_with_reason "unreachable expressions '.' not handled for now"] and big_map_size : - type a b. + type a b bc. count_lambda_nodes:bool -> nodes_and_size -> a comparable_ty -> - b ty -> + (b, bc) ty -> (a, b) big_map -> nodes_and_size = fun ~count_lambda_nodes accu cty ty' (Big_map {id; diff; key_type; value_type}) -> diff --git a/src/proto_alpha/lib_protocol/script_typed_ir_size.mli b/src/proto_alpha/lib_protocol/script_typed_ir_size.mli index 9b51ba8b8c..26e4b38e9a 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir_size.mli +++ b/src/proto_alpha/lib_protocol/script_typed_ir_size.mli @@ -34,7 +34,7 @@ (** [value_size ty v] returns an overapproximation of the size of the in-memory representation of [v] of type [ty]. *) val value_size : - 'a Script_typed_ir.ty -> 'a -> Cache_memory_helpers.nodes_and_size + ('a, _) Script_typed_ir.ty -> 'a -> Cache_memory_helpers.nodes_and_size (** [lambda_size l] returns an overapproximation of the size of the internal IR for the Michelson lambda abstraction [l]. *) @@ -61,7 +61,8 @@ val zero : Cache_memory_helpers.nodes_and_size module Internal_for_tests : sig (** [ty_size ty] returns an overapproximation of the size of the in-memory representation of type [ty]. *) - val ty_size : 'a Script_typed_ir.ty -> Cache_memory_helpers.nodes_and_size + val ty_size : + ('a, _) Script_typed_ir.ty -> Cache_memory_helpers.nodes_and_size (** [comparable_ty_size cty] returns an overapproximation of the size of the in-memory representation of comparable type [cty]. *) diff --git a/src/proto_alpha/lib_protocol/test/helpers/script_big_map.mli b/src/proto_alpha/lib_protocol/test/helpers/script_big_map.mli index d387519582..29e7738520 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/script_big_map.mli +++ b/src/proto_alpha/lib_protocol/test/helpers/script_big_map.mli @@ -36,7 +36,7 @@ val update : *) val of_list : 'key Protocol.Script_typed_ir.comparable_ty -> - 'value Protocol.Script_typed_ir.ty -> + ('value, _) Protocol.Script_typed_ir.ty -> ('key * 'value) list -> Protocol.Alpha_context.t -> (('key, 'value) Protocol.Script_typed_ir.big_map * Protocol.Alpha_context.t) diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_script_cache.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_script_cache.ml index 60247caa35..cd0edb8952 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_script_cache.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_script_cache.ml @@ -86,7 +86,8 @@ let find ctxt addr = return (ctxt, identifier, script, Ex_script ir) let value_as_int : - type a. a Script_typed_ir.ty -> a -> Script_int_repr.z Script_int_repr.num = + type a ac. + (a, ac) Script_typed_ir.ty -> a -> Script_int_repr.z Script_int_repr.num = fun ty v -> match ty with Int_t -> v | _ -> Stdlib.failwith "value_as_int" let add_some_contracts k src block baker = diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_script_typed_ir_size.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_script_typed_ir_size.ml index 35f7f7dd07..2d66952a94 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_script_typed_ir_size.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_script_typed_ir_size.ml @@ -159,7 +159,7 @@ module Printers = struct Format.eprintf "@[Error: %a@]" pp_print_trace errs ; exit 1 - let string_of_value : type a. a Script_typed_ir.ty -> a -> string = + let string_of_value : type a ac. (a, ac) Script_typed_ir.ty -> a -> string = fun ty v -> string_of_something @@ fun ctxt -> Script_ir_translator.( @@ -284,7 +284,7 @@ module Tests = struct ~expected_ratios:(1., 0.05) let contains_exceptions ty = - let apply : type a. bool -> a Script_typed_ir.ty -> bool = + let apply : type a ac. bool -> (a, ac) Script_typed_ir.ty -> bool = fun accu -> function (* Boxed sets and maps point to a shared first class module. This is an overapproximation that we want to ignore in diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_typechecking.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_typechecking.ml index 90f03f0606..20c9d158ff 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_typechecking.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_typechecking.ml @@ -160,7 +160,8 @@ let location = function | Seq (loc, _) -> loc -let test_parse_ty (type exp) ctxt node (expected : exp Script_typed_ir.ty) = +let test_parse_ty (type exp expc) ctxt node + (expected : (exp, expc) Script_typed_ir.ty) = let legacy = false in let allow_lazy_storage = true in let allow_operation = true in @@ -454,11 +455,18 @@ let test_parse_comb_data () = Big_map {id = Some big_map_id; diff; key_type = nat_key_ty; value_type = nat_ty} in + let ty_equal : + type a ac1 ac2. + (a, ac1) Script_typed_ir.ty -> (a, ac2) Script_typed_ir.ty -> bool = + fun ty1 ty2 -> + match Script_typed_ir.(is_comparable ty1, is_comparable ty2) with + | (Eq, Eq) -> ty1 = ty2 + in let equal (nat1, Big_map big_map1) (nat2, Big_map big_map2) = (* Custom equal needed because big maps contain boxed maps containing functional values *) nat1 = nat2 && big_map1.id = big_map2.id && big_map1.key_type = big_map2.key_type - && big_map1.value_type = big_map2.value_type + && ty_equal big_map1.value_type big_map2.value_type && big_map1.diff.size = big_map2.diff.size && Big_map_overlay.bindings big_map1.diff.map = Big_map_overlay.bindings big_map2.diff.map diff --git a/src/proto_alpha/lib_protocol/ticket_costs.mli b/src/proto_alpha/lib_protocol/ticket_costs.mli index 6a216fd305..fa9745b185 100644 --- a/src/proto_alpha/lib_protocol/ticket_costs.mli +++ b/src/proto_alpha/lib_protocol/ticket_costs.mli @@ -52,7 +52,7 @@ val consume_gas_steps : (** [has_tickets_of_ty_cost ty] returns the cost of producing a [has_tickets], used internally in the [Ticket_scanner] module. *) val has_tickets_of_ty_cost : - 'a Script_typed_ir.ty -> Saturation_repr.may_saturate Saturation_repr.t + ('a, _) Script_typed_ir.ty -> Saturation_repr.may_saturate Saturation_repr.t (** [negate_cost z] returns the cost of negating the given value [z]. *) val negate_cost : Z.t -> Alpha_context.Gas.cost diff --git a/src/proto_alpha/lib_protocol/ticket_operations_diff.ml b/src/proto_alpha/lib_protocol/ticket_operations_diff.ml index 25810b64df..0fcc683b02 100644 --- a/src/proto_alpha/lib_protocol/ticket_operations_diff.ml +++ b/src/proto_alpha/lib_protocol/ticket_operations_diff.ml @@ -149,9 +149,10 @@ let parse_and_cache_script ctxt ~destination ~get_non_cached_script = Script_cache.insert ctxt destination (script, ex_script) size >>?= fun ctxt -> return (ex_script, ctxt) -let cast_transaction_parameter (type a b) ctxt location - (entry_arg_ty : a Script_typed_ir.ty) (parameters_ty : b Script_typed_ir.ty) - (parameters : b) : (a * context) tzresult Lwt.t = +let cast_transaction_parameter (type a ac b bc) ctxt location + (entry_arg_ty : (a, ac) Script_typed_ir.ty) + (parameters_ty : (b, bc) Script_typed_ir.ty) (parameters : b) : + (a * context) tzresult Lwt.t = Gas_monad.run ctxt (Script_ir_translator.ty_eq diff --git a/src/proto_alpha/lib_protocol/ticket_scanner.ml b/src/proto_alpha/lib_protocol/ticket_scanner.ml index 2130c27671..110e0c95fc 100644 --- a/src/proto_alpha/lib_protocol/ticket_scanner.ml +++ b/src/proto_alpha/lib_protocol/ticket_scanner.ml @@ -144,8 +144,8 @@ module Ticket_inspection = struct it collapses whole branches where no types embed tickets to [False_ht]. *) let rec has_tickets_of_ty : - type a ret. a Script_typed_ir.ty -> (a, ret) continuation -> ret tzresult - = + type a ac ret. + (a, ac) Script_typed_ir.ty -> (a, ret) continuation -> ret tzresult = fun ty k -> let open Script_typed_ir in match ty with @@ -220,9 +220,9 @@ module Ticket_inspection = struct | Chest_key_t -> (k [@ocaml.tailcall]) False_ht and has_tickets_of_pair : - type a b c ret. - a Script_typed_ir.ty -> - b Script_typed_ir.ty -> + type a ac b bc c ret. + (a, ac) Script_typed_ir.ty -> + (b, bc) Script_typed_ir.ty -> pair:(a has_tickets -> b has_tickets -> c has_tickets) -> (c, ret) continuation -> ret tzresult = @@ -232,9 +232,9 @@ module Ticket_inspection = struct (k [@ocaml.tailcall]) (pair_has_tickets pair ht1 ht2))) and has_tickets_of_key_and_value : - type k v t ret. + type k v vc t ret. k Script_typed_ir.comparable_ty -> - v Script_typed_ir.ty -> + (v, vc) Script_typed_ir.ty -> pair:(k has_tickets -> v has_tickets -> t has_tickets) -> (t, ret) continuation -> ret tzresult = @@ -308,11 +308,11 @@ module Ticket_collection = struct (tickets_of_comparable [@ocaml.tailcall]) ctxt key_ty acc k let rec tickets_of_value : - type a ret. + type a ac ret. include_lazy:bool -> Alpha_context.context -> a Ticket_inspection.has_tickets -> - a Script_typed_ir.ty -> + (a, ac) Script_typed_ir.ty -> a -> accumulator -> ret continuation -> @@ -406,11 +406,11 @@ module Ticket_collection = struct (k [@ocaml.tailcall]) ctxt (Ex_ticket (comp_ty, x) :: acc) and tickets_of_list : - type a ret. + type a ac ret. Alpha_context.context -> include_lazy:bool -> a Ticket_inspection.has_tickets -> - a Script_typed_ir.ty -> + (a, ac) Script_typed_ir.ty -> a list -> accumulator -> ret continuation -> @@ -438,11 +438,11 @@ module Ticket_collection = struct | [] -> (k [@ocaml.tailcall]) ctxt acc and tickets_of_map : - type k v ret. + type k v vc ret. include_lazy:bool -> Alpha_context.context -> v Ticket_inspection.has_tickets -> - v Script_typed_ir.ty -> + (v, vc) Script_typed_ir.ty -> (k, v) Script_typed_ir.map -> accumulator -> ret continuation -> @@ -515,7 +515,7 @@ end type 'a has_tickets = | Has_tickets : - 'a Ticket_inspection.has_tickets * 'a Script_typed_ir.ty + 'a Ticket_inspection.has_tickets * ('a, _) Script_typed_ir.ty -> 'a has_tickets let type_has_tickets ctxt ty = diff --git a/src/proto_alpha/lib_protocol/ticket_scanner.mli b/src/proto_alpha/lib_protocol/ticket_scanner.mli index fe405abe13..209c633ab7 100644 --- a/src/proto_alpha/lib_protocol/ticket_scanner.mli +++ b/src/proto_alpha/lib_protocol/ticket_scanner.mli @@ -46,7 +46,7 @@ type 'a has_tickets *) val type_has_tickets : Alpha_context.context -> - 'a Script_typed_ir.ty -> + ('a, _) Script_typed_ir.ty -> ('a has_tickets * Alpha_context.context) tzresult (** [tickets_of_value ctxt ~include_lazy ht value] extracts all tickets from From 377abf96d4d44ec9cc6bf2e4ad8eb27e2f5cde1c Mon Sep 17 00:00:00 2001 From: Mehdi Bouaziz Date: Mon, 4 Oct 2021 09:38:13 +0200 Subject: [PATCH 058/100] Proto/Michelson: add dependent bools --- src/proto_alpha/lib_protocol/TEZOS_PROTOCOL | 1 + .../lib_protocol/dependent_bool.ml | 64 ++++++++++++++++++ .../lib_protocol/dependent_bool.mli | 65 +++++++++++++++++++ src/proto_alpha/lib_protocol/dune.inc | 5 ++ .../lib_protocol/script_typed_ir.ml | 5 +- .../lib_protocol/script_typed_ir.mli | 3 +- 6 files changed, 138 insertions(+), 5 deletions(-) create mode 100644 src/proto_alpha/lib_protocol/dependent_bool.ml create mode 100644 src/proto_alpha/lib_protocol/dependent_bool.mli diff --git a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL index f799885d5d..0f4d060409 100644 --- a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL +++ b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL @@ -137,6 +137,7 @@ "Script_tc_errors", "Gas_monad", "Script_ir_annot", + "Dependent_bool", "Script_typed_ir", "Script_comparable", "Gas_comparable_input_size", diff --git a/src/proto_alpha/lib_protocol/dependent_bool.ml b/src/proto_alpha/lib_protocol/dependent_bool.ml new file mode 100644 index 0000000000..8fb3c49ec1 --- /dev/null +++ b/src/proto_alpha/lib_protocol/dependent_bool.ml @@ -0,0 +1,64 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type no = private DNo + +type yes = private DYes + +type _ dbool = No : no dbool | Yes : yes dbool + +type ('a, 'b, 'r) dand = + | NoNo : (no, no, no) dand + | NoYes : (no, yes, no) dand + | YesNo : (yes, no, no) dand + | YesYes : (yes, yes, yes) dand + +type ('a, 'b) ex_dand = Ex_dand : ('a, 'b, _) dand -> ('a, 'b) ex_dand +[@@unboxed] + +let dand : type a b. a dbool -> b dbool -> (a, b) ex_dand = + fun a b -> + match (a, b) with + | (No, No) -> Ex_dand NoNo + | (No, Yes) -> Ex_dand NoYes + | (Yes, No) -> Ex_dand YesNo + | (Yes, Yes) -> Ex_dand YesYes + +let dbool_of_dand : type a b r. (a, b, r) dand -> r dbool = function + | NoNo -> No + | NoYes -> No + | YesNo -> No + | YesYes -> Yes + +type (_, _) eq = Eq : ('a, 'a) eq + +let merge_dand : + type a b c1 c2. (a, b, c1) dand -> (a, b, c2) dand -> (c1, c2) eq = + fun w1 w2 -> + match (w1, w2) with + | (NoNo, NoNo) -> Eq + | (NoYes, NoYes) -> Eq + | (YesNo, YesNo) -> Eq + | (YesYes, YesYes) -> Eq diff --git a/src/proto_alpha/lib_protocol/dependent_bool.mli b/src/proto_alpha/lib_protocol/dependent_bool.mli new file mode 100644 index 0000000000..54416d9fd9 --- /dev/null +++ b/src/proto_alpha/lib_protocol/dependent_bool.mli @@ -0,0 +1,65 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Dependent booleans *) + +type no = private DNo + +type yes = private DYes + +(** + ['b dbool] is a boolean whose value depends on its type parameter ['b]. + [yes dbool] can only be [Yes]. [no dbool] can only be [No]. +*) +type _ dbool = No : no dbool | Yes : yes dbool + +(** + [('a, 'b, 'r) dand] is a witness of the logical conjunction of dependent + booleans. ['r] is the result of ['a] and ['b]. +*) +type ('a, 'b, 'r) dand = + | NoNo : (no, no, no) dand + | NoYes : (no, yes, no) dand + | YesNo : (yes, no, no) dand + | YesYes : (yes, yes, yes) dand + +type ('a, 'b) ex_dand = Ex_dand : ('a, 'b, _) dand -> ('a, 'b) ex_dand +[@@unboxed] + +(** Logical conjunction of dependent booleans. *) +val dand : 'a dbool -> 'b dbool -> ('a, 'b) ex_dand + +(** Result of the logical conjunction of dependent booleans. *) +val dbool_of_dand : ('a, 'b, 'r) dand -> 'r dbool + +(** Type equality witness. *) +type (_, _) eq = Eq : ('a, 'a) eq + +(** + [merge_dand] proves that the type [dand] represents a function, i.e. that + there is a unique ['r] such that [('a, 'b, 'r) dand] is inhabited for a + given ['a] and a given ['b]. +*) +val merge_dand : ('a, 'b, 'c1) dand -> ('a, 'b, 'c2) dand -> ('c1, 'c2) eq diff --git a/src/proto_alpha/lib_protocol/dune.inc b/src/proto_alpha/lib_protocol/dune.inc index f662b09503..de7d31cf75 100644 --- a/src/proto_alpha/lib_protocol/dune.inc +++ b/src/proto_alpha/lib_protocol/dune.inc @@ -153,6 +153,7 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end script_tc_errors.ml gas_monad.mli gas_monad.ml script_ir_annot.mli script_ir_annot.ml + dependent_bool.mli dependent_bool.ml script_typed_ir.mli script_typed_ir.ml script_comparable.mli script_comparable.ml gas_comparable_input_size.mli gas_comparable_input_size.ml @@ -329,6 +330,7 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end script_tc_errors.ml gas_monad.mli gas_monad.ml script_ir_annot.mli script_ir_annot.ml + dependent_bool.mli dependent_bool.ml script_typed_ir.mli script_typed_ir.ml script_comparable.mli script_comparable.ml gas_comparable_input_size.mli gas_comparable_input_size.ml @@ -505,6 +507,7 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end script_tc_errors.ml gas_monad.mli gas_monad.ml script_ir_annot.mli script_ir_annot.ml + dependent_bool.mli dependent_bool.ml script_typed_ir.mli script_typed_ir.ml script_comparable.mli script_comparable.ml gas_comparable_input_size.mli gas_comparable_input_size.ml @@ -703,6 +706,7 @@ include Tezos_raw_protocol_alpha.Main Script_tc_errors Gas_monad Script_ir_annot + Dependent_bool Script_typed_ir Script_comparable Gas_comparable_input_size @@ -920,6 +924,7 @@ include Tezos_raw_protocol_alpha.Main script_tc_errors.ml gas_monad.mli gas_monad.ml script_ir_annot.mli script_ir_annot.ml + dependent_bool.mli dependent_bool.ml script_typed_ir.mli script_typed_ir.ml script_comparable.mli script_comparable.ml gas_comparable_input_size.mli gas_comparable_input_size.ml diff --git a/src/proto_alpha/lib_protocol/script_typed_ir.ml b/src/proto_alpha/lib_protocol/script_typed_ir.ml index 95278748b6..670c8901ab 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir.ml +++ b/src/proto_alpha/lib_protocol/script_typed_ir.ml @@ -27,6 +27,7 @@ open Alpha_context open Script_int +open Dependent_bool (* @@ -220,7 +221,7 @@ type 'a ticket = {ticketer : Contract.t; contents : 'a; amount : n num} module type TYPE_SIZE = sig (* A type size represents the size of its type parameter. - This constraint is enforced inside this module (Script_type_ir), hence there + This constraint is enforced inside this module (Script_typed_ir), hence there should be no way to construct a type size outside of it. It allows keeping type metadata and types non-private. @@ -311,8 +312,6 @@ type end_of_stack = empty_cell * empty_cell type 'a ty_metadata = {size : 'a Type_size.t} [@@unboxed] -type (_, _) eq = Eq : ('a, 'a) eq - type _ comparable_ty = | Unit_key : unit comparable_ty | Never_key : never comparable_ty diff --git a/src/proto_alpha/lib_protocol/script_typed_ir.mli b/src/proto_alpha/lib_protocol/script_typed_ir.mli index e9ad3c83e4..f60adc7290 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir.mli +++ b/src/proto_alpha/lib_protocol/script_typed_ir.mli @@ -27,6 +27,7 @@ open Alpha_context open Script_int +open Dependent_bool type step_constants = { source : Contract.t; @@ -186,8 +187,6 @@ end type 'a ty_metadata = {size : 'a Type_size.t} [@@unboxed] -type (_, _) eq = Eq : ('a, 'a) eq - type _ comparable_ty = | Unit_key : unit comparable_ty | Never_key : never comparable_ty From 101de3710fab0de2fdecbf4530fd03b0a55a350f Mon Sep 17 00:00:00 2001 From: Mehdi Bouaziz Date: Mon, 4 Oct 2021 09:38:13 +0200 Subject: [PATCH 059/100] Proto/Michelson: constraint comparable character of ty Replace all `to_be_replaced` by a dependent boolean or conjunction. Once `ty` is correct, nothing else can go wrong. --- .../lib_benchmarks_proto/michelson_types.ml | 16 +- .../lib_protocol/script_ir_translator.ml | 16 +- .../lib_protocol/script_ir_translator.mli | 2 +- .../lib_protocol/script_typed_ir.ml | 214 +++++++++--------- .../lib_protocol/script_typed_ir.mli | 197 ++++++++-------- .../michelson/test_typechecking.ml | 11 +- 6 files changed, 226 insertions(+), 230 deletions(-) diff --git a/src/proto_alpha/lib_benchmarks_proto/michelson_types.ml b/src/proto_alpha/lib_benchmarks_proto/michelson_types.ml index 55504ceddb..efc4a09999 100644 --- a/src/proto_alpha/lib_benchmarks_proto/michelson_types.ml +++ b/src/proto_alpha/lib_benchmarks_proto/michelson_types.ml @@ -96,25 +96,17 @@ let set k = match set_t (-1) k with Error _ -> assert false | Ok t -> t let pair k1 k2 = match pair_t (-1) k1 k2 with Error _ -> assert false | Ok t -> t -(* (will become) comparable pair type constructor *) +(* comparable pair type constructor *) let cpair k1 k2 = - match pair_t (-1) k1 k2 with - | Error _ -> assert false - | Ok (Ty_ex_c t) -> - let Eq = is_comparable t in - (t : (_, to_be_replaced) ty) + match comparable_pair_t (-1) k1 k2 with Error _ -> assert false | Ok t -> t (* union type constructor*) let union k1 k2 = match union_t (-1) k1 k2 with Error _ -> assert false | Ok t -> t -(* (will become) comparable union type constructor *) +(* comparable union type constructor *) let cunion k1 k2 = - match union_t (-1) k1 k2 with - | Error _ -> assert false - | Ok (Ty_ex_c t) -> - let Eq = is_comparable t in - (t : (_, to_be_replaced) ty) + match comparable_union_t (-1) k1 k2 with Error _ -> assert false | Ok t -> t let lambda x y = match lambda_t (-1) x y with Error _ -> assert false | Ok t -> t diff --git a/src/proto_alpha/lib_protocol/script_ir_translator.ml b/src/proto_alpha/lib_protocol/script_ir_translator.ml index c37024e5c0..8e94d82db4 100644 --- a/src/proto_alpha/lib_protocol/script_ir_translator.ml +++ b/src/proto_alpha/lib_protocol/script_ir_translator.ml @@ -161,8 +161,8 @@ let check_kind kinds expr = (everything that cannot contain a lambda). The rest is located at the end of the file. *) -let rec ty_of_comparable_ty : type a. a comparable_ty -> (a, to_be_replaced) ty - = function +let rec ty_of_comparable_ty : + type a. a comparable_ty -> (a, Dependent_bool.yes) ty = function | Unit_key -> Unit_t | Never_key -> Never_t | Int_key -> Int_t @@ -179,10 +179,10 @@ let rec ty_of_comparable_ty : type a. a comparable_ty -> (a, to_be_replaced) ty | Tx_rollup_l2_address_key -> Tx_rollup_l2_address_t | Chain_id_key -> Chain_id_t | Pair_key (l, r, meta) -> - Pair_t (ty_of_comparable_ty l, ty_of_comparable_ty r, meta, ()) + Pair_t (ty_of_comparable_ty l, ty_of_comparable_ty r, meta, YesYes) | Union_key (l, r, meta) -> - Union_t (ty_of_comparable_ty l, ty_of_comparable_ty r, meta, ()) - | Option_key (t, meta) -> Option_t (ty_of_comparable_ty t, meta, ()) + Union_t (ty_of_comparable_ty l, ty_of_comparable_ty r, meta, YesYes) + | Option_key (t, meta) -> Option_t (ty_of_comparable_ty t, meta, Yes) let rec unparse_comparable_ty_uncarbonated : type a loc. loc:loc -> a comparable_ty -> loc Script.michelson_node = @@ -960,16 +960,18 @@ let ty_eq : let+ Eq = comparable_ty_eq ~error_details ea eb in (Eq : ((ta, tac) ty, (tb, tbc) ty) eq) | (Ticket_t _, _) -> not_equal () - | (Pair_t (tal, tar, meta1, _), Pair_t (tbl, tbr, meta2, _)) -> + | (Pair_t (tal, tar, meta1, cmp1), Pair_t (tbl, tbr, meta2, cmp2)) -> let* () = type_metadata_eq meta1 meta2 in let* Eq = help tal tbl in let+ Eq = help tar tbr in + let Eq = Dependent_bool.merge_dand cmp1 cmp2 in (Eq : ((ta, tac) ty, (tb, tbc) ty) eq) | (Pair_t _, _) -> not_equal () - | (Union_t (tal, tar, meta1, _), Union_t (tbl, tbr, meta2, _)) -> + | (Union_t (tal, tar, meta1, cmp1), Union_t (tbl, tbr, meta2, cmp2)) -> let* () = type_metadata_eq meta1 meta2 in let* Eq = help tal tbl in let+ Eq = help tar tbr in + let Eq = Dependent_bool.merge_dand cmp1 cmp2 in (Eq : ((ta, tac) ty, (tb, tbc) ty) eq) | (Union_t _, _) -> not_equal () | (Lambda_t (tal, tar, meta1), Lambda_t (tbl, tbr, meta2)) -> diff --git a/src/proto_alpha/lib_protocol/script_ir_translator.mli b/src/proto_alpha/lib_protocol/script_ir_translator.mli index 190012ad8c..3b2285ef5a 100644 --- a/src/proto_alpha/lib_protocol/script_ir_translator.mli +++ b/src/proto_alpha/lib_protocol/script_ir_translator.mli @@ -357,7 +357,7 @@ val unparse_comparable_ty : val ty_of_comparable_ty : 'a Script_typed_ir.comparable_ty -> - ('a, Script_typed_ir.to_be_replaced) Script_typed_ir.ty + ('a, Dependent_bool.yes) Script_typed_ir.ty val parse_toplevel : context -> legacy:bool -> Script.expr -> (toplevel * context) tzresult Lwt.t diff --git a/src/proto_alpha/lib_protocol/script_typed_ir.ml b/src/proto_alpha/lib_protocol/script_typed_ir.ml index 670c8901ab..728b37aa72 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir.ml +++ b/src/proto_alpha/lib_protocol/script_typed_ir.ml @@ -1224,72 +1224,64 @@ and logger = { get_log : unit -> execution_trace option tzresult Lwt.t; } -and to_be_replaced = unit - (* ---- Auxiliary types -----------------------------------------------------*) and ('ty, 'comparable) ty = - | Unit_t : (unit, to_be_replaced) ty - | Int_t : (z num, to_be_replaced) ty - | Nat_t : (n num, to_be_replaced) ty - | Signature_t : (signature, to_be_replaced) ty - | String_t : (Script_string.t, to_be_replaced) ty - | Bytes_t : (bytes, to_be_replaced) ty - | Mutez_t : (Tez.t, to_be_replaced) ty - | Key_hash_t : (public_key_hash, to_be_replaced) ty - | Key_t : (public_key, to_be_replaced) ty - | Timestamp_t : (Script_timestamp.t, to_be_replaced) ty - | Address_t : (address, to_be_replaced) ty - | Tx_rollup_l2_address_t : (tx_rollup_l2_address, to_be_replaced) ty - | Bool_t : (bool, to_be_replaced) ty + | Unit_t : (unit, yes) ty + | Int_t : (z num, yes) ty + | Nat_t : (n num, yes) ty + | Signature_t : (signature, yes) ty + | String_t : (Script_string.t, yes) ty + | Bytes_t : (bytes, yes) ty + | Mutez_t : (Tez.t, yes) ty + | Key_hash_t : (public_key_hash, yes) ty + | Key_t : (public_key, yes) ty + | Timestamp_t : (Script_timestamp.t, yes) ty + | Address_t : (address, yes) ty + | Tx_rollup_l2_address_t : (tx_rollup_l2_address, yes) ty + | Bool_t : (bool, yes) ty | Pair_t : - ('a, to_be_replaced) ty - * ('b, to_be_replaced) ty + ('a, 'ac) ty + * ('b, 'bc) ty * ('a, 'b) pair ty_metadata - * to_be_replaced - -> (('a, 'b) pair, to_be_replaced) ty + * ('ac, 'bc, 'rc) dand + -> (('a, 'b) pair, 'rc) ty | Union_t : - ('a, to_be_replaced) ty - * ('b, to_be_replaced) ty + ('a, 'ac) ty + * ('b, 'bc) ty * ('a, 'b) union ty_metadata - * to_be_replaced - -> (('a, 'b) union, to_be_replaced) ty + * ('ac, 'bc, 'rc) dand + -> (('a, 'b) union, 'rc) ty | Lambda_t : ('arg, _) ty * ('ret, _) ty * ('arg, 'ret) lambda ty_metadata - -> (('arg, 'ret) lambda, to_be_replaced) ty + -> (('arg, 'ret) lambda, no) ty | Option_t : - ('v, to_be_replaced) ty * 'v option ty_metadata * to_be_replaced - -> ('v option, to_be_replaced) ty - | List_t : - ('v, _) ty * 'v boxed_list ty_metadata - -> ('v boxed_list, to_be_replaced) ty - | Set_t : 'v comparable_ty * 'v set ty_metadata -> ('v set, to_be_replaced) ty + ('v, 'c) ty * 'v option ty_metadata * 'c dbool + -> ('v option, 'c) ty + | List_t : ('v, _) ty * 'v boxed_list ty_metadata -> ('v boxed_list, no) ty + | Set_t : 'v comparable_ty * 'v set ty_metadata -> ('v set, no) ty | Map_t : 'k comparable_ty * ('v, _) ty * ('k, 'v) map ty_metadata - -> (('k, 'v) map, to_be_replaced) ty + -> (('k, 'v) map, no) ty | Big_map_t : 'k comparable_ty * ('v, _) ty * ('k, 'v) big_map ty_metadata - -> (('k, 'v) big_map, to_be_replaced) ty + -> (('k, 'v) big_map, no) ty | Contract_t : ('arg, _) ty * 'arg typed_contract ty_metadata - -> ('arg typed_contract, to_be_replaced) ty - | Sapling_transaction_t : - Sapling.Memo_size.t - -> (Sapling.transaction, to_be_replaced) ty + -> ('arg typed_contract, no) ty + | Sapling_transaction_t : Sapling.Memo_size.t -> (Sapling.transaction, no) ty | Sapling_transaction_deprecated_t : Sapling.Memo_size.t - -> (Sapling.Legacy.transaction, to_be_replaced) ty - | Sapling_state_t : Sapling.Memo_size.t -> (Sapling.state, to_be_replaced) ty - | Operation_t : (operation, to_be_replaced) ty - | Chain_id_t : (Script_chain_id.t, to_be_replaced) ty - | Never_t : (never, to_be_replaced) ty - | Bls12_381_g1_t : (Script_bls.G1.t, to_be_replaced) ty - | Bls12_381_g2_t : (Script_bls.G2.t, to_be_replaced) ty - | Bls12_381_fr_t : (Script_bls.Fr.t, to_be_replaced) ty - | Ticket_t : - 'a comparable_ty * 'a ticket ty_metadata - -> ('a ticket, to_be_replaced) ty - | Chest_key_t : (Script_timelock.chest_key, to_be_replaced) ty - | Chest_t : (Script_timelock.chest, to_be_replaced) ty + -> (Sapling.Legacy.transaction, no) ty + | Sapling_state_t : Sapling.Memo_size.t -> (Sapling.state, no) ty + | Operation_t : (operation, no) ty + | Chain_id_t : (Script_chain_id.t, yes) ty + | Never_t : (never, yes) ty + | Bls12_381_g1_t : (Script_bls.G1.t, no) ty + | Bls12_381_g2_t : (Script_bls.G2.t, no) ty + | Bls12_381_fr_t : (Script_bls.Fr.t, no) ty + | Ticket_t : 'a comparable_ty * 'a ticket ty_metadata -> ('a ticket, no) ty + | Chest_key_t : (Script_timelock.chest_key, no) ty + | Chest_t : (Script_timelock.chest, no) ty and ('top_ty, 'resty) stack_ty = | Item_t : @@ -1817,41 +1809,41 @@ let ty_size : type v vc. (v, vc) ty -> v Type_size.t = let comparable_ty_size t = (comparable_ty_metadata t).size -let is_comparable : type v c. (v, c) ty -> (c, to_be_replaced) eq = function - | Never_t -> Eq - | Unit_t -> Eq - | Int_t -> Eq - | Nat_t -> Eq - | Signature_t -> Eq - | String_t -> Eq - | Bytes_t -> Eq - | Mutez_t -> Eq - | Bool_t -> Eq - | Key_hash_t -> Eq - | Key_t -> Eq - | Timestamp_t -> Eq - | Chain_id_t -> Eq - | Address_t -> Eq - | Tx_rollup_l2_address_t -> Eq - | Pair_t _ -> Eq - | Union_t _ -> Eq - | Option_t _ -> Eq - | Lambda_t _ -> Eq - | List_t _ -> Eq - | Set_t _ -> Eq - | Map_t _ -> Eq - | Big_map_t _ -> Eq - | Ticket_t _ -> Eq - | Contract_t _ -> Eq - | Sapling_transaction_t _ -> Eq - | Sapling_transaction_deprecated_t _ -> Eq - | Sapling_state_t _ -> Eq - | Operation_t -> Eq - | Bls12_381_g1_t -> Eq - | Bls12_381_g2_t -> Eq - | Bls12_381_fr_t -> Eq - | Chest_t -> Eq - | Chest_key_t -> Eq +let is_comparable : type v c. (v, c) ty -> c dbool = function + | Never_t -> Yes + | Unit_t -> Yes + | Int_t -> Yes + | Nat_t -> Yes + | Signature_t -> Yes + | String_t -> Yes + | Bytes_t -> Yes + | Mutez_t -> Yes + | Bool_t -> Yes + | Key_hash_t -> Yes + | Key_t -> Yes + | Timestamp_t -> Yes + | Chain_id_t -> Yes + | Address_t -> Yes + | Tx_rollup_l2_address_t -> Yes + | Pair_t (_, _, _, dand) -> dbool_of_dand dand + | Union_t (_, _, _, dand) -> dbool_of_dand dand + | Option_t (_, _, cmp) -> cmp + | Lambda_t _ -> No + | List_t _ -> No + | Set_t _ -> No + | Map_t _ -> No + | Big_map_t _ -> No + | Ticket_t _ -> No + | Contract_t _ -> No + | Sapling_transaction_t _ -> No + | Sapling_transaction_deprecated_t _ -> No + | Sapling_state_t _ -> No + | Operation_t -> No + | Bls12_381_g1_t -> No + | Bls12_381_g2_t -> No + | Bls12_381_fr_t -> No + | Chest_t -> No + | Chest_key_t -> No type 'v ty_ex_c = Ty_ex_c : ('v, _) ty -> 'v ty_ex_c [@@ocaml.unboxed] @@ -1913,9 +1905,12 @@ let pair_t : = fun loc l r -> Type_size.compound2 loc (ty_size l) (ty_size r) >|? fun size -> - let Eq = is_comparable l in - let Eq = is_comparable r in - Ty_ex_c (Pair_t (l, r, {size}, ())) + let (Ex_dand cmp) = dand (is_comparable l) (is_comparable r) in + Ty_ex_c (Pair_t (l, r, {size}, cmp)) + +let comparable_pair_t loc l r = + Type_size.compound2 loc (ty_size l) (ty_size r) >|? fun size -> + Pair_t (l, r, {size}, YesYes) let pair_key loc l r = Type_size.compound2 loc (comparable_ty_size l) (comparable_ty_size r) @@ -1929,11 +1924,15 @@ let union_t : = fun loc l r -> Type_size.compound2 loc (ty_size l) (ty_size r) >|? fun size -> - let Eq = is_comparable l in - let Eq = is_comparable r in - Ty_ex_c (Union_t (l, r, {size}, ())) + let (Ex_dand cmp) = dand (is_comparable l) (is_comparable r) in + Ty_ex_c (Union_t (l, r, {size}, cmp)) + +let comparable_union_t loc l r = + Type_size.compound2 loc (ty_size l) (ty_size r) >|? fun size -> + Union_t (l, r, {size}, YesYes) -let union_bytes_bool_t = Union_t (bytes_t, bool_t, {size = Type_size.three}, ()) +let union_bytes_bool_t = + Union_t (bytes_t, bool_t, {size = Type_size.three}, YesYes) let union_key loc l r = Type_size.compound2 loc (comparable_ty_size l) (comparable_ty_size r) @@ -1943,45 +1942,42 @@ let lambda_t loc l r = Type_size.compound2 loc (ty_size l) (ty_size r) >|? fun size -> Lambda_t (l, r, {size}) -let option_t : - type v c. - Script.location -> (v, c) ty -> (v option, to_be_replaced) ty tzresult = - fun loc t -> +let option_t loc t = Type_size.compound1 loc (ty_size t) >|? fun size -> - let Eq = is_comparable t in - Option_t (t, {size}, ()) + let cmp = is_comparable t in + Option_t (t, {size}, cmp) -let option_mutez_t = Option_t (mutez_t, {size = Type_size.two}, ()) +let option_mutez_t = Option_t (mutez_t, {size = Type_size.two}, Yes) -let option_string_t = Option_t (string_t, {size = Type_size.two}, ()) +let option_string_t = Option_t (string_t, {size = Type_size.two}, Yes) -let option_bytes_t = Option_t (bytes_t, {size = Type_size.two}, ()) +let option_bytes_t = Option_t (bytes_t, {size = Type_size.two}, Yes) -let option_nat_t = Option_t (nat_t, {size = Type_size.two}, ()) +let option_nat_t = Option_t (nat_t, {size = Type_size.two}, Yes) let option_pair_nat_nat_t = Option_t - ( Pair_t (nat_t, nat_t, {size = Type_size.three}, ()), + ( Pair_t (nat_t, nat_t, {size = Type_size.three}, YesYes), {size = Type_size.four}, - () ) + Yes ) let option_pair_nat_mutez_t = Option_t - ( Pair_t (nat_t, mutez_t, {size = Type_size.three}, ()), + ( Pair_t (nat_t, mutez_t, {size = Type_size.three}, YesYes), {size = Type_size.four}, - () ) + Yes ) let option_pair_mutez_mutez_t = Option_t - ( Pair_t (mutez_t, mutez_t, {size = Type_size.three}, ()), + ( Pair_t (mutez_t, mutez_t, {size = Type_size.three}, YesYes), {size = Type_size.four}, - () ) + Yes ) let option_pair_int_nat_t = Option_t - ( Pair_t (int_t, nat_t, {size = Type_size.three}, ()), + ( Pair_t (int_t, nat_t, {size = Type_size.three}, YesYes), {size = Type_size.four}, - () ) + Yes ) let option_key loc t = Type_size.compound1 loc (comparable_ty_size t) >|? fun size -> diff --git a/src/proto_alpha/lib_protocol/script_typed_ir.mli b/src/proto_alpha/lib_protocol/script_typed_ir.mli index f60adc7290..2f4af3843d 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir.mli +++ b/src/proto_alpha/lib_protocol/script_typed_ir.mli @@ -1328,72 +1328,64 @@ and logger = { produced. *) } -and to_be_replaced = unit - (* ---- Auxiliary types -----------------------------------------------------*) and ('ty, 'comparable) ty = - | Unit_t : (unit, to_be_replaced) ty - | Int_t : (z num, to_be_replaced) ty - | Nat_t : (n num, to_be_replaced) ty - | Signature_t : (signature, to_be_replaced) ty - | String_t : (Script_string.t, to_be_replaced) ty - | Bytes_t : (bytes, to_be_replaced) ty - | Mutez_t : (Tez.t, to_be_replaced) ty - | Key_hash_t : (public_key_hash, to_be_replaced) ty - | Key_t : (public_key, to_be_replaced) ty - | Timestamp_t : (Script_timestamp.t, to_be_replaced) ty - | Address_t : (address, to_be_replaced) ty - | Tx_rollup_l2_address_t : (tx_rollup_l2_address, to_be_replaced) ty - | Bool_t : (bool, to_be_replaced) ty + | Unit_t : (unit, yes) ty + | Int_t : (z num, yes) ty + | Nat_t : (n num, yes) ty + | Signature_t : (signature, yes) ty + | String_t : (Script_string.t, yes) ty + | Bytes_t : (bytes, yes) ty + | Mutez_t : (Tez.t, yes) ty + | Key_hash_t : (public_key_hash, yes) ty + | Key_t : (public_key, yes) ty + | Timestamp_t : (Script_timestamp.t, yes) ty + | Address_t : (address, yes) ty + | Tx_rollup_l2_address_t : (tx_rollup_l2_address, yes) ty + | Bool_t : (bool, yes) ty | Pair_t : - ('a, to_be_replaced) ty - * ('b, to_be_replaced) ty + ('a, 'ac) ty + * ('b, 'bc) ty * ('a, 'b) pair ty_metadata - * to_be_replaced - -> (('a, 'b) pair, to_be_replaced) ty + * ('ac, 'bc, 'rc) dand + -> (('a, 'b) pair, 'rc) ty | Union_t : - ('a, to_be_replaced) ty - * ('b, to_be_replaced) ty + ('a, 'ac) ty + * ('b, 'bc) ty * ('a, 'b) union ty_metadata - * to_be_replaced - -> (('a, 'b) union, to_be_replaced) ty + * ('ac, 'bc, 'rc) dand + -> (('a, 'b) union, 'rc) ty | Lambda_t : ('arg, _) ty * ('ret, _) ty * ('arg, 'ret) lambda ty_metadata - -> (('arg, 'ret) lambda, to_be_replaced) ty + -> (('arg, 'ret) lambda, no) ty | Option_t : - ('v, to_be_replaced) ty * 'v option ty_metadata * to_be_replaced - -> ('v option, to_be_replaced) ty - | List_t : - ('v, _) ty * 'v boxed_list ty_metadata - -> ('v boxed_list, to_be_replaced) ty - | Set_t : 'v comparable_ty * 'v set ty_metadata -> ('v set, to_be_replaced) ty + ('v, 'c) ty * 'v option ty_metadata * 'c dbool + -> ('v option, 'c) ty + | List_t : ('v, _) ty * 'v boxed_list ty_metadata -> ('v boxed_list, no) ty + | Set_t : 'v comparable_ty * 'v set ty_metadata -> ('v set, no) ty | Map_t : 'k comparable_ty * ('v, _) ty * ('k, 'v) map ty_metadata - -> (('k, 'v) map, to_be_replaced) ty + -> (('k, 'v) map, no) ty | Big_map_t : 'k comparable_ty * ('v, _) ty * ('k, 'v) big_map ty_metadata - -> (('k, 'v) big_map, to_be_replaced) ty + -> (('k, 'v) big_map, no) ty | Contract_t : ('arg, _) ty * 'arg typed_contract ty_metadata - -> ('arg typed_contract, to_be_replaced) ty - | Sapling_transaction_t : - Sapling.Memo_size.t - -> (Sapling.transaction, to_be_replaced) ty + -> ('arg typed_contract, no) ty + | Sapling_transaction_t : Sapling.Memo_size.t -> (Sapling.transaction, no) ty | Sapling_transaction_deprecated_t : Sapling.Memo_size.t - -> (Sapling.Legacy.transaction, to_be_replaced) ty - | Sapling_state_t : Sapling.Memo_size.t -> (Sapling.state, to_be_replaced) ty - | Operation_t : (operation, to_be_replaced) ty - | Chain_id_t : (Script_chain_id.t, to_be_replaced) ty - | Never_t : (never, to_be_replaced) ty - | Bls12_381_g1_t : (Script_bls.G1.t, to_be_replaced) ty - | Bls12_381_g2_t : (Script_bls.G2.t, to_be_replaced) ty - | Bls12_381_fr_t : (Script_bls.Fr.t, to_be_replaced) ty - | Ticket_t : - 'a comparable_ty * 'a ticket ty_metadata - -> ('a ticket, to_be_replaced) ty - | Chest_key_t : (Script_timelock.chest_key, to_be_replaced) ty - | Chest_t : (Script_timelock.chest, to_be_replaced) ty + -> (Sapling.Legacy.transaction, no) ty + | Sapling_state_t : Sapling.Memo_size.t -> (Sapling.state, no) ty + | Operation_t : (operation, no) ty + | Chain_id_t : (Script_chain_id.t, yes) ty + | Never_t : (never, yes) ty + | Bls12_381_g1_t : (Script_bls.G1.t, no) ty + | Bls12_381_g2_t : (Script_bls.G2.t, no) ty + | Bls12_381_fr_t : (Script_bls.Fr.t, no) ty + | Ticket_t : 'a comparable_ty * 'a ticket ty_metadata -> ('a ticket, no) ty + | Chest_key_t : (Script_timelock.chest_key, no) ty + | Chest_t : (Script_timelock.chest, no) ty and ('top_ty, 'resty) stack_ty = | Item_t : @@ -1563,7 +1555,7 @@ val ty_size : ('a, _) ty -> 'a Type_size.t val comparable_ty_size : 'a comparable_ty -> 'a Type_size.t -val is_comparable : ('v, 'c) ty -> ('c, to_be_replaced) eq +val is_comparable : ('v, 'c) ty -> 'c dbool type 'v ty_ex_c = Ty_ex_c : ('v, _) ty -> 'v ty_ex_c [@@ocaml.unboxed] @@ -1619,120 +1611,125 @@ val union_key : val option_key : Script.location -> 'v comparable_ty -> 'v option comparable_ty tzresult -val unit_t : (unit, to_be_replaced) ty +val unit_t : (unit, yes) ty -val int_t : (z num, to_be_replaced) ty +val int_t : (z num, yes) ty -val nat_t : (n num, to_be_replaced) ty +val nat_t : (n num, yes) ty -val signature_t : (signature, to_be_replaced) ty +val signature_t : (signature, yes) ty -val string_t : (Script_string.t, to_be_replaced) ty +val string_t : (Script_string.t, yes) ty -val bytes_t : (Bytes.t, to_be_replaced) ty +val bytes_t : (Bytes.t, yes) ty -val mutez_t : (Tez.t, to_be_replaced) ty +val mutez_t : (Tez.t, yes) ty -val key_hash_t : (public_key_hash, to_be_replaced) ty +val key_hash_t : (public_key_hash, yes) ty -val key_t : (public_key, to_be_replaced) ty +val key_t : (public_key, yes) ty -val timestamp_t : (Script_timestamp.t, to_be_replaced) ty +val timestamp_t : (Script_timestamp.t, yes) ty -val address_t : (address, to_be_replaced) ty +val address_t : (address, yes) ty -val tx_rollup_l2_address_t : (tx_rollup_l2_address, to_be_replaced) ty +val tx_rollup_l2_address_t : (tx_rollup_l2_address, yes) ty -val bool_t : (bool, to_be_replaced) ty +val bool_t : (bool, yes) ty val pair_t : Script.location -> ('a, _) ty -> ('b, _) ty -> ('a, 'b) pair ty_ex_c tzresult +val comparable_pair_t : + Script.location -> + ('a, yes) ty -> + ('b, yes) ty -> + (('a, 'b) pair, yes) ty tzresult + val union_t : Script.location -> ('a, _) ty -> ('b, _) ty -> ('a, 'b) union ty_ex_c tzresult -val union_bytes_bool_t : ((Bytes.t, bool) union, to_be_replaced) ty +val comparable_union_t : + Script.location -> + ('a, yes) ty -> + ('b, yes) ty -> + (('a, 'b) union, yes) ty tzresult + +val union_bytes_bool_t : ((Bytes.t, bool) union, yes) ty val lambda_t : Script.location -> ('arg, _) ty -> ('ret, _) ty -> - (('arg, 'ret) lambda, to_be_replaced) ty tzresult + (('arg, 'ret) lambda, no) ty tzresult -val option_t : - Script.location -> ('v, 'c) ty -> ('v option, to_be_replaced) ty tzresult +val option_t : Script.location -> ('v, 'c) ty -> ('v option, 'c) ty tzresult -val option_mutez_t : (Tez.t option, to_be_replaced) ty +val option_mutez_t : (Tez.t option, yes) ty -val option_string_t : (Script_string.t option, to_be_replaced) ty +val option_string_t : (Script_string.t option, yes) ty -val option_bytes_t : (Bytes.t option, to_be_replaced) ty +val option_bytes_t : (Bytes.t option, yes) ty -val option_nat_t : (n num option, to_be_replaced) ty +val option_nat_t : (n num option, yes) ty -val option_pair_nat_nat_t : ((n num, n num) pair option, to_be_replaced) ty +val option_pair_nat_nat_t : ((n num, n num) pair option, yes) ty -val option_pair_nat_mutez_t : ((n num, Tez.t) pair option, to_be_replaced) ty +val option_pair_nat_mutez_t : ((n num, Tez.t) pair option, yes) ty -val option_pair_mutez_mutez_t : ((Tez.t, Tez.t) pair option, to_be_replaced) ty +val option_pair_mutez_mutez_t : ((Tez.t, Tez.t) pair option, yes) ty -val option_pair_int_nat_t : ((z num, n num) pair option, to_be_replaced) ty +val option_pair_int_nat_t : ((z num, n num) pair option, yes) ty -val list_t : - Script.location -> ('v, _) ty -> ('v boxed_list, to_be_replaced) ty tzresult +val list_t : Script.location -> ('v, _) ty -> ('v boxed_list, no) ty tzresult -val list_operation_t : (operation boxed_list, to_be_replaced) ty +val list_operation_t : (operation boxed_list, no) ty -val set_t : - Script.location -> 'v comparable_ty -> ('v set, to_be_replaced) ty tzresult +val set_t : Script.location -> 'v comparable_ty -> ('v set, no) ty tzresult val map_t : Script.location -> 'k comparable_ty -> ('v, _) ty -> - (('k, 'v) map, to_be_replaced) ty tzresult + (('k, 'v) map, no) ty tzresult val big_map_t : Script.location -> 'k comparable_ty -> ('v, _) ty -> - (('k, 'v) big_map, to_be_replaced) ty tzresult + (('k, 'v) big_map, no) ty tzresult val contract_t : - Script.location -> - ('arg, _) ty -> - ('arg typed_contract, to_be_replaced) ty tzresult + Script.location -> ('arg, _) ty -> ('arg typed_contract, no) ty tzresult -val contract_unit_t : (unit typed_contract, to_be_replaced) ty +val contract_unit_t : (unit typed_contract, no) ty val sapling_transaction_t : - memo_size:Sapling.Memo_size.t -> (Sapling.transaction, to_be_replaced) ty + memo_size:Sapling.Memo_size.t -> (Sapling.transaction, no) ty val sapling_transaction_deprecated_t : - memo_size:Sapling.Memo_size.t -> - (Sapling.Legacy.transaction, to_be_replaced) ty + memo_size:Sapling.Memo_size.t -> (Sapling.Legacy.transaction, no) ty -val sapling_state_t : - memo_size:Sapling.Memo_size.t -> (Sapling.state, to_be_replaced) ty +val sapling_state_t : memo_size:Sapling.Memo_size.t -> (Sapling.state, no) ty -val operation_t : (operation, to_be_replaced) ty +val operation_t : (operation, no) ty -val chain_id_t : (Script_chain_id.t, to_be_replaced) ty +val chain_id_t : (Script_chain_id.t, yes) ty -val never_t : (never, to_be_replaced) ty +val never_t : (never, yes) ty -val bls12_381_g1_t : (Script_bls.G1.t, to_be_replaced) ty +val bls12_381_g1_t : (Script_bls.G1.t, no) ty -val bls12_381_g2_t : (Script_bls.G2.t, to_be_replaced) ty +val bls12_381_g2_t : (Script_bls.G2.t, no) ty -val bls12_381_fr_t : (Script_bls.Fr.t, to_be_replaced) ty +val bls12_381_fr_t : (Script_bls.Fr.t, no) ty val ticket_t : - Script.location -> 'a comparable_ty -> ('a ticket, to_be_replaced) ty tzresult + Script.location -> 'a comparable_ty -> ('a ticket, no) ty tzresult -val chest_key_t : (Script_timelock.chest_key, to_be_replaced) ty +val chest_key_t : (Script_timelock.chest_key, no) ty -val chest_t : (Script_timelock.chest, to_be_replaced) ty +val chest_t : (Script_timelock.chest, no) ty (** diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_typechecking.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_typechecking.ml index 20c9d158ff..5e9bf59630 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_typechecking.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_typechecking.ml @@ -460,7 +460,16 @@ let test_parse_comb_data () = (a, ac1) Script_typed_ir.ty -> (a, ac2) Script_typed_ir.ty -> bool = fun ty1 ty2 -> match Script_typed_ir.(is_comparable ty1, is_comparable ty2) with - | (Eq, Eq) -> ty1 = ty2 + | (Yes, Yes) -> ty1 = ty2 + | (No, No) -> ty1 = ty2 + | (Yes, No) -> assert false + | (No, Yes) -> assert false + (* + These last two cases can't happen because the comparable character of a + type is a function of its concrete type. + It is possible to write a function that proves it but it is not needed + in the protocol for the moment. + *) in let equal (nat1, Big_map big_map1) (nat2, Big_map big_map2) = (* Custom equal needed because big maps contain boxed maps containing functional values *) From c9453988c43cb31b63a6172906d8f5ec9d362288 Mon Sep 17 00:00:00 2001 From: Mehdi Bouaziz Date: Sat, 26 Feb 2022 22:05:53 +0100 Subject: [PATCH 060/100] Proto/Michelson: add parameters to Pair_key, Union_key, Option_key to match Pair_t, Union_t, Option_t --- .../lib_benchmark/test/test_distribution.ml | 6 +-- src/proto_alpha/lib_plugin/plugin.ml | 6 +-- .../lib_protocol/gas_comparable_input_size.ml | 6 +-- .../lib_protocol/michelson_v1_gas.ml | 6 +-- .../lib_protocol/script_comparable.ml | 8 ++-- .../lib_protocol/script_ir_translator.ml | 42 +++++++++---------- .../lib_protocol/script_typed_ir.ml | 36 +++++++++------- .../lib_protocol/script_typed_ir.mli | 12 ++++-- .../lib_protocol/script_typed_ir_size.ml | 17 ++++---- .../test/pbt/test_script_comparison.ml | 11 +++-- .../lib_protocol/ticket_scanner.ml | 12 +++--- 11 files changed, 89 insertions(+), 73 deletions(-) diff --git a/src/proto_alpha/lib_benchmark/test/test_distribution.ml b/src/proto_alpha/lib_benchmark/test/test_distribution.ml index 14cdb7a94c..74ad9d815f 100644 --- a/src/proto_alpha/lib_benchmark/test/test_distribution.ml +++ b/src/proto_alpha/lib_benchmark/test/test_distribution.ml @@ -120,15 +120,15 @@ and tnames_of_comparable_type : | Script_typed_ir.Chain_id_key -> `TChain_id :: acc | Script_typed_ir.Address_key -> `TAddress :: acc | Script_typed_ir.Tx_rollup_l2_address_key -> `TTx_rollup_l2_address :: acc - | Script_typed_ir.Pair_key (lty, rty, _) -> + | Script_typed_ir.Pair_key (lty, rty, _, YesYes) -> tnames_of_comparable_type lty (tnames_of_comparable_type rty (`TPair :: acc)) - | Script_typed_ir.Union_key (lty, rty, _) -> + | Script_typed_ir.Union_key (lty, rty, _, YesYes) -> tnames_of_comparable_type lty (tnames_of_comparable_type rty (`TUnion :: acc)) - | Script_typed_ir.Option_key (ty, _) -> + | Script_typed_ir.Option_key (ty, _, Yes) -> tnames_of_comparable_type ty (`TOption :: acc) module Crypto_samplers = Crypto_samplers.Make_finite_key_pool (struct diff --git a/src/proto_alpha/lib_plugin/plugin.ml b/src/proto_alpha/lib_plugin/plugin.ml index 8492f4e922..8e353635a1 100644 --- a/src/proto_alpha/lib_plugin/plugin.ml +++ b/src/proto_alpha/lib_plugin/plugin.ml @@ -2001,15 +2001,15 @@ module RPC = struct | Address_key -> Prim (loc, T_address, [], []) | Tx_rollup_l2_address_key -> Prim (loc, T_tx_rollup_l2_address, [], []) | Chain_id_key -> Prim (loc, T_chain_id, [], []) - | Pair_key (l, r, _meta) -> + | Pair_key (l, r, _meta, YesYes) -> let tl = unparse_comparable_ty ~loc l in let tr = unparse_comparable_ty ~loc r in Prim (loc, T_pair, [tl; tr], []) - | Union_key (l, r, _meta) -> + | Union_key (l, r, _meta, YesYes) -> let tl = unparse_comparable_ty ~loc l in let tr = unparse_comparable_ty ~loc r in Prim (loc, T_or, [tl; tr], []) - | Option_key (t, _meta) -> + | Option_key (t, _meta, Yes) -> Prim (loc, T_option, [unparse_comparable_ty ~loc t], []) let unparse_memo_size ~loc memo_size = diff --git a/src/proto_alpha/lib_protocol/gas_comparable_input_size.ml b/src/proto_alpha/lib_protocol/gas_comparable_input_size.ml index 9cbda6412b..040574b5c0 100644 --- a/src/proto_alpha/lib_protocol/gas_comparable_input_size.ml +++ b/src/proto_alpha/lib_protocol/gas_comparable_input_size.ml @@ -122,20 +122,20 @@ let rec size_of_comparable_value : | Timestamp_key -> timestamp v | Address_key -> address v | Tx_rollup_l2_address_key -> tx_rollup_l2_address v - | Pair_key (leaf, node, _) -> + | Pair_key (leaf, node, _, YesYes) -> let (lv, rv) = v in let size = size_of_comparable_value leaf lv + size_of_comparable_value node rv in size + 1 - | Union_key (left, right, _) -> + | Union_key (left, right, _, YesYes) -> let size = match v with | L v -> size_of_comparable_value left v | R v -> size_of_comparable_value right v in size + 1 - | Option_key (ty, _) -> ( + | Option_key (ty, _, Yes) -> ( match v with None -> 1 | Some x -> size_of_comparable_value ty x + 1) | Signature_key -> signature v | Key_key -> public_key v diff --git a/src/proto_alpha/lib_protocol/michelson_v1_gas.ml b/src/proto_alpha/lib_protocol/michelson_v1_gas.ml index 842cf0ba9f..39eb3d58ee 100644 --- a/src/proto_alpha/lib_protocol/michelson_v1_gas.ml +++ b/src/proto_alpha/lib_protocol/michelson_v1_gas.ml @@ -1419,7 +1419,7 @@ module Cost_of = struct | Tx_rollup_l2_address_key -> (apply [@tailcall]) Gas.(acc +@ compare_tx_rollup_l2_address) k | Chain_id_key -> (apply [@tailcall]) Gas.(acc +@ compare_chain_id) k - | Pair_key (tl, tr, _) -> + | Pair_key (tl, tr, _, YesYes) -> (* Reasonable over-approximation of the cost of lexicographic comparison. *) let (xl, xr) = x in let (yl, yr) = y in @@ -1429,7 +1429,7 @@ module Cost_of = struct yl Gas.(acc +@ compare_pair_tag) (Compare (tr, xr, yr, k)) - | Union_key (tl, tr, _) -> ( + | Union_key (tl, tr, _, YesYes) -> ( match (x, y) with | (L x, L y) -> (compare [@tailcall]) tl x y Gas.(acc +@ compare_union_tag) k @@ -1437,7 +1437,7 @@ module Cost_of = struct | (R _, L _) -> (apply [@tailcall]) Gas.(acc +@ compare_union_tag) k | (R x, R y) -> (compare [@tailcall]) tr x y Gas.(acc +@ compare_union_tag) k) - | Option_key (t, _) -> ( + | Option_key (t, _, Yes) -> ( match (x, y) with | (None, None) -> (apply [@tailcall]) Gas.(acc +@ compare_option_tag) k diff --git a/src/proto_alpha/lib_protocol/script_comparable.ml b/src/proto_alpha/lib_protocol/script_comparable.ml index d27805c044..cf152247ac 100644 --- a/src/proto_alpha/lib_protocol/script_comparable.ml +++ b/src/proto_alpha/lib_protocol/script_comparable.ml @@ -68,22 +68,22 @@ let compare_comparable : type a. a comparable_ty -> a -> a -> int = | (Bytes_key, x, y) -> (apply [@tailcall]) (Compare.Bytes.compare x y) k | (Chain_id_key, x, y) -> (apply [@tailcall]) (Script_chain_id.compare x y) k - | (Pair_key (tl, tr, _), (lx, rx), (ly, ry)) -> + | (Pair_key (tl, tr, _, YesYes), (lx, rx), (ly, ry)) -> (compare_comparable [@tailcall]) tl (Compare_comparable (tr, rx, ry, k)) lx ly - | (Union_key (tl, _, _), L x, L y) -> + | (Union_key (tl, _, _, YesYes), L x, L y) -> (compare_comparable [@tailcall]) tl k x y | (Union_key _, L _, R _) -> -1 | (Union_key _, R _, L _) -> 1 - | (Union_key (_, tr, _), R x, R y) -> + | (Union_key (_, tr, _, YesYes), R x, R y) -> (compare_comparable [@tailcall]) tr k x y | (Option_key _, None, None) -> (apply [@tailcall]) 0 k | (Option_key _, None, Some _) -> -1 | (Option_key _, Some _, None) -> 1 - | (Option_key (t, _), Some x, Some y) -> + | (Option_key (t, _, Yes), Some x, Some y) -> (compare_comparable [@tailcall]) t k x y and apply ret k = match (ret, k) with diff --git a/src/proto_alpha/lib_protocol/script_ir_translator.ml b/src/proto_alpha/lib_protocol/script_ir_translator.ml index 8e94d82db4..ee490f8b4a 100644 --- a/src/proto_alpha/lib_protocol/script_ir_translator.ml +++ b/src/proto_alpha/lib_protocol/script_ir_translator.ml @@ -178,11 +178,11 @@ let rec ty_of_comparable_ty : | Address_key -> Address_t | Tx_rollup_l2_address_key -> Tx_rollup_l2_address_t | Chain_id_key -> Chain_id_t - | Pair_key (l, r, meta) -> + | Pair_key (l, r, meta, YesYes) -> Pair_t (ty_of_comparable_ty l, ty_of_comparable_ty r, meta, YesYes) - | Union_key (l, r, meta) -> + | Union_key (l, r, meta, YesYes) -> Union_t (ty_of_comparable_ty l, ty_of_comparable_ty r, meta, YesYes) - | Option_key (t, meta) -> Option_t (ty_of_comparable_ty t, meta, Yes) + | Option_key (t, meta, Yes) -> Option_t (ty_of_comparable_ty t, meta, Yes) let rec unparse_comparable_ty_uncarbonated : type a loc. loc:loc -> a comparable_ty -> loc Script.michelson_node = @@ -202,7 +202,7 @@ let rec unparse_comparable_ty_uncarbonated : | Address_key -> Prim (loc, T_address, [], []) | Tx_rollup_l2_address_key -> Prim (loc, T_tx_rollup_l2_address, [], []) | Chain_id_key -> Prim (loc, T_chain_id, [], []) - | Pair_key (l, r, _meta) -> ( + | Pair_key (l, r, _meta, YesYes) -> ( let tl = unparse_comparable_ty_uncarbonated ~loc l in let tr = unparse_comparable_ty_uncarbonated ~loc r in (* Fold [pair a1 (pair ... (pair an-1 an))] into [pair a1 ... an] *) @@ -211,11 +211,11 @@ let rec unparse_comparable_ty_uncarbonated : match tr with | Prim (_, T_pair, ts, []) -> Prim (loc, T_pair, tl :: ts, []) | _ -> Prim (loc, T_pair, [tl; tr], [])) - | Union_key (l, r, _meta) -> + | Union_key (l, r, _meta, YesYes) -> let tl = unparse_comparable_ty_uncarbonated ~loc l in let tr = unparse_comparable_ty_uncarbonated ~loc r in Prim (loc, T_or, [tl; tr], []) - | Option_key (t, _meta) -> + | Option_key (t, _meta, Yes) -> Prim (loc, T_option, [unparse_comparable_ty_uncarbonated ~loc t], []) let unparse_memo_size ~loc memo_size = @@ -360,14 +360,14 @@ let[@coq_axiom_with_reason "gadt"] rec comparable_ty_of_ty : | Pair_t (l, r, pname, _) -> comparable_ty_of_ty ctxt loc l >>? fun (lty, ctxt) -> comparable_ty_of_ty ctxt loc r >|? fun (rty, ctxt) -> - (Pair_key (lty, rty, pname), ctxt) + (Pair_key (lty, rty, pname, YesYes), ctxt) | Union_t (l, r, meta, _) -> comparable_ty_of_ty ctxt loc l >>? fun (lty, ctxt) -> comparable_ty_of_ty ctxt loc r >|? fun (rty, ctxt) -> - (Union_key (lty, rty, meta), ctxt) + (Union_key (lty, rty, meta, YesYes), ctxt) | Option_t (tt, meta, _) -> comparable_ty_of_ty ctxt loc tt >|? fun (ty, ctxt) -> - (Option_key (ty, meta), ctxt) + (Option_key (ty, meta, Yes), ctxt) | Lambda_t _ | List_t _ | Ticket_t _ | Set_t _ | Map_t _ | Big_map_t _ | Contract_t _ | Operation_t | Bls12_381_fr_t | Bls12_381_g1_t | Bls12_381_g2_t | Sapling_state_t _ | Sapling_transaction_t _ @@ -589,7 +589,7 @@ let unparse_option ~loc unparse_v ctxt = function let comparable_comb_witness2 : type t. t comparable_ty -> (t, unit -> unit -> unit) comb_witness = function - | Pair_key (_, Pair_key _, _) -> Comb_Pair (Comb_Pair Comb_Any) + | Pair_key (_, Pair_key _, _, YesYes) -> Comb_Pair (Comb_Pair Comb_Any) | Pair_key _ -> Comb_Pair Comb_Any | _ -> Comb_Any @@ -629,16 +629,16 @@ let[@coq_axiom_with_reason "gadt"] rec unparse_comparable_data : | (Key_hash_key, k) -> Lwt.return @@ unparse_key_hash ~loc ctxt mode k | (Chain_id_key, chain_id) -> Lwt.return @@ unparse_chain_id ~loc ctxt mode chain_id - | (Pair_key (tl, tr, _), pair) -> + | (Pair_key (tl, tr, _, YesYes), pair) -> let r_witness = comparable_comb_witness2 tr in let unparse_l ctxt v = unparse_comparable_data ~loc ctxt mode tl v in let unparse_r ctxt v = unparse_comparable_data ~loc ctxt mode tr v in unparse_pair ~loc unparse_l unparse_r ctxt mode r_witness pair - | (Union_key (tl, tr, _), v) -> + | (Union_key (tl, tr, _, YesYes), v) -> let unparse_l ctxt v = unparse_comparable_data ~loc ctxt mode tl v in let unparse_r ctxt v = unparse_comparable_data ~loc ctxt mode tr v in unparse_union ~loc unparse_l unparse_r ctxt v - | (Option_key (t, _), v) -> + | (Option_key (t, _, Yes), v) -> let unparse_v ctxt v = unparse_comparable_data ~loc ctxt mode t v in unparse_option ~loc unparse_v ctxt v | (Never_key, _) -> . @@ -822,21 +822,21 @@ let rec comparable_ty_eq : | (Address_key, _) -> not_equal () | (Tx_rollup_l2_address_key, Tx_rollup_l2_address_key) -> return Eq | (Tx_rollup_l2_address_key, _) -> not_equal () - | (Pair_key (left_a, right_a, meta_a), Pair_key (left_b, right_b, meta_b)) - -> + | ( Pair_key (left_a, right_a, meta_a, YesYes), + Pair_key (left_b, right_b, meta_b, YesYes) ) -> let* () = type_metadata_eq meta_a meta_b in let* Eq = comparable_ty_eq ~error_details left_a left_b in let+ Eq = comparable_ty_eq ~error_details right_a right_b in (Eq : (ta comparable_ty, tb comparable_ty) eq) | (Pair_key _, _) -> not_equal () - | (Union_key (left_a, right_a, meta_a), Union_key (left_b, right_b, meta_b)) - -> + | ( Union_key (left_a, right_a, meta_a, YesYes), + Union_key (left_b, right_b, meta_b, YesYes) ) -> let* () = type_metadata_eq meta_a meta_b in let* Eq = comparable_ty_eq ~error_details left_a left_b in let+ Eq = comparable_ty_eq ~error_details right_a right_b in (Eq : (ta comparable_ty, tb comparable_ty) eq) | (Union_key _, _) -> not_equal () - | (Option_key (ta, meta_a), Option_key (tb, meta_b)) -> + | (Option_key (ta, meta_a, Yes), Option_key (tb, meta_b, Yes)) -> let* () = type_metadata_eq meta_a meta_b in let+ Eq = comparable_ty_eq ~error_details ta tb in (Eq : (ta comparable_ty, tb comparable_ty) eq) @@ -2490,16 +2490,16 @@ let[@coq_axiom_with_reason "gadt"] rec parse_comparable_data : Lwt.return @@ traced_no_lwt @@ parse_address ctxt expr | (Tx_rollup_l2_address_key, expr) -> Lwt.return @@ traced_no_lwt @@ parse_tx_rollup_l2_address ctxt expr - | (Pair_key (tl, tr, _), expr) -> + | (Pair_key (tl, tr, _, YesYes), expr) -> let r_witness = comparable_comb_witness1 tr in let parse_l ctxt v = parse_comparable_data ?type_logger ctxt tl v in let parse_r ctxt v = parse_comparable_data ?type_logger ctxt tr v in traced @@ parse_pair parse_l parse_r ctxt ~legacy r_witness expr - | (Union_key (tl, tr, _), expr) -> + | (Union_key (tl, tr, _, YesYes), expr) -> let parse_l ctxt v = parse_comparable_data ?type_logger ctxt tl v in let parse_r ctxt v = parse_comparable_data ?type_logger ctxt tr v in traced @@ parse_union parse_l parse_r ctxt ~legacy expr - | (Option_key (t, _), expr) -> + | (Option_key (t, _, Yes), expr) -> let parse_v ctxt v = parse_comparable_data ?type_logger ctxt t v in traced @@ parse_option parse_v ctxt ~legacy expr | (Never_key, expr) -> Lwt.return @@ traced_no_lwt @@ parse_never expr diff --git a/src/proto_alpha/lib_protocol/script_typed_ir.ml b/src/proto_alpha/lib_protocol/script_typed_ir.ml index 728b37aa72..8734cd25e5 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir.ml +++ b/src/proto_alpha/lib_protocol/script_typed_ir.ml @@ -329,13 +329,19 @@ type _ comparable_ty = | Address_key : address comparable_ty | Tx_rollup_l2_address_key : tx_rollup_l2_address comparable_ty | Pair_key : - 'a comparable_ty * 'b comparable_ty * ('a, 'b) pair ty_metadata + 'a comparable_ty + * 'b comparable_ty + * ('a, 'b) pair ty_metadata + * (yes, yes, yes) dand -> ('a, 'b) pair comparable_ty | Union_key : - 'a comparable_ty * 'b comparable_ty * ('a, 'b) union ty_metadata + 'a comparable_ty + * 'b comparable_ty + * ('a, 'b) union ty_metadata + * (yes, yes, yes) dand -> ('a, 'b) union comparable_ty | Option_key : - 'v comparable_ty * 'v option ty_metadata + 'v comparable_ty * 'v option ty_metadata * yes dbool -> 'v option comparable_ty (* @@ -1800,9 +1806,9 @@ let comparable_ty_metadata : type a. a comparable_ty -> a ty_metadata = function | Bytes_key | Mutez_key | Bool_key | Key_hash_key | Key_key | Timestamp_key | Chain_id_key | Address_key | Tx_rollup_l2_address_key -> meta_basic - | Pair_key (_, _, meta) -> meta - | Union_key (_, _, meta) -> meta - | Option_key (_, meta) -> meta + | Pair_key (_, _, meta, YesYes) -> meta + | Union_key (_, _, meta, YesYes) -> meta + | Option_key (_, meta, Yes) -> meta let ty_size : type v vc. (v, vc) ty -> v Type_size.t = fun t -> (ty_metadata t).size @@ -1914,7 +1920,7 @@ let comparable_pair_t loc l r = let pair_key loc l r = Type_size.compound2 loc (comparable_ty_size l) (comparable_ty_size r) - >|? fun size -> Pair_key (l, r, {size}) + >|? fun size -> Pair_key (l, r, {size}, YesYes) let pair_3_key loc l m r = pair_key loc m r >>? fun r -> pair_key loc l r @@ -1936,7 +1942,7 @@ let union_bytes_bool_t = let union_key loc l r = Type_size.compound2 loc (comparable_ty_size l) (comparable_ty_size r) - >|? fun size -> Union_key (l, r, {size}) + >|? fun size -> Union_key (l, r, {size}, YesYes) let lambda_t loc l r = Type_size.compound2 loc (ty_size l) (ty_size r) >|? fun size -> @@ -1981,7 +1987,7 @@ let option_pair_int_nat_t = let option_key loc t = Type_size.compound1 loc (comparable_ty_size t) >|? fun size -> - Option_key (t, {size}) + Option_key (t, {size}, Yes) let list_t loc t = Type_size.compound1 loc (ty_size t) >|? fun size -> List_t (t, {size}) @@ -2251,9 +2257,9 @@ let (ty_traverse, comparable_ty_traverse) = | Mutez_key | Key_hash_key | Key_key | Timestamp_key | Address_key | Tx_rollup_l2_address_key | Bool_key | Chain_id_key | Never_key -> (return [@ocaml.tailcall]) () - | Pair_key (ty1, ty2, _) -> (next2 [@ocaml.tailcall]) ty1 ty2 - | Union_key (ty1, ty2, _) -> (next2 [@ocaml.tailcall]) ty1 ty2 - | Option_key (ty, _) -> (next [@ocaml.tailcall]) ty + | Pair_key (ty1, ty2, _, YesYes) -> (next2 [@ocaml.tailcall]) ty1 ty2 + | Union_key (ty1, ty2, _, YesYes) -> (next2 [@ocaml.tailcall]) ty1 ty2 + | Option_key (ty, _, Yes) -> (next [@ocaml.tailcall]) ty and aux' : type ret t tc accu. accu ty_traverse -> accu -> (t, tc) ty -> (accu -> ret) -> ret = @@ -2421,13 +2427,13 @@ let value_traverse (type t tc) (ty : ((t, tc) ty, t comparable_ty) union) | Mutez_key | Key_hash_key | Key_key | Timestamp_key | Address_key | Tx_rollup_l2_address_key | Bool_key | Chain_id_key | Never_key -> (return [@ocaml.tailcall]) () - | Pair_key (ty1, ty2, _) -> + | Pair_key (ty1, ty2, _, YesYes) -> (next2 [@ocaml.tailcall]) ty1 ty2 (fst x) (snd x) - | Union_key (ty1, ty2, _) -> ( + | Union_key (ty1, ty2, _, YesYes) -> ( match x with | L l -> (next [@ocaml.tailcall]) ty1 l | R r -> (next [@ocaml.tailcall]) ty2 r) - | Option_key (ty, _) -> ( + | Option_key (ty, _, Yes) -> ( match x with | None -> (return [@ocaml.tailcall]) () | Some v -> (next [@ocaml.tailcall]) ty v) diff --git a/src/proto_alpha/lib_protocol/script_typed_ir.mli b/src/proto_alpha/lib_protocol/script_typed_ir.mli index 2f4af3843d..102d0a36b4 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir.mli +++ b/src/proto_alpha/lib_protocol/script_typed_ir.mli @@ -204,13 +204,19 @@ type _ comparable_ty = | Address_key : address comparable_ty | Tx_rollup_l2_address_key : tx_rollup_l2_address comparable_ty | Pair_key : - 'a comparable_ty * 'b comparable_ty * ('a, 'b) pair ty_metadata + 'a comparable_ty + * 'b comparable_ty + * ('a, 'b) pair ty_metadata + * (yes, yes, yes) dand -> ('a, 'b) pair comparable_ty | Union_key : - 'a comparable_ty * 'b comparable_ty * ('a, 'b) union ty_metadata + 'a comparable_ty + * 'b comparable_ty + * ('a, 'b) union ty_metadata + * (yes, yes, yes) dand -> ('a, 'b) union comparable_ty | Option_key : - 'v comparable_ty * 'v option ty_metadata + 'v comparable_ty * 'v option ty_metadata * yes dbool -> 'v option comparable_ty module type Boxed_set_OPS = sig diff --git a/src/proto_alpha/lib_protocol/script_typed_ir_size.ml b/src/proto_alpha/lib_protocol/script_typed_ir_size.ml index 261db9ea7f..43a3c8b836 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir_size.ml +++ b/src/proto_alpha/lib_protocol/script_typed_ir_size.ml @@ -60,12 +60,12 @@ let ty_traverse_f = | Bool_key -> ret_succ_adding accu base_basic | Chain_id_key -> ret_succ_adding accu base_basic | Never_key -> ret_succ_adding accu base_basic - | Pair_key (_ty1, _ty2, a) -> - ret_succ_adding accu @@ (base_compound a +! (word_size *? 2)) - | Union_key (_ty1, _ty2, a) -> + | Pair_key (_ty1, _ty2, a, YesYes) -> + ret_succ_adding accu @@ (base_compound a +! (word_size *? 3)) + | Union_key (_ty1, _ty2, a, YesYes) -> + ret_succ_adding accu @@ (base_compound a +! (word_size *? 3)) + | Option_key (_ty, a, Yes) -> ret_succ_adding accu @@ (base_compound a +! (word_size *? 2)) - | Option_key (_ty, a) -> - ret_succ_adding accu @@ (base_compound a +! word_size) and apply : type a ac. nodes_and_size -> (a, ac) ty -> nodes_and_size = fun accu ty -> match ty with @@ -344,9 +344,10 @@ let rec value_size : | Tx_rollup_l2_address_key -> ret_succ_adding accu (tx_rollup_l2_address_size x) | Bool_key -> ret_succ accu - | Pair_key (_, _, _) -> ret_succ_adding accu h2w - | Union_key (_, _, _) -> ret_succ_adding accu h1w - | Option_key (_, _) -> ret_succ_adding accu (option_size (fun _ -> !!0) x) + | Pair_key (_, _, _, YesYes) -> ret_succ_adding accu h2w + | Union_key (_, _, _, YesYes) -> ret_succ_adding accu h1w + | Option_key (_, _, Yes) -> + ret_succ_adding accu (option_size (fun _ -> !!0) x) | Chain_id_key -> ret_succ_adding accu chain_id_size | Never_key -> ( match x with _ -> .) in diff --git a/src/proto_alpha/lib_protocol/test/pbt/test_script_comparison.ml b/src/proto_alpha/lib_protocol/test/pbt/test_script_comparison.ml index ce05dc4465..12e3a4124e 100644 --- a/src/proto_alpha/lib_protocol/test/pbt/test_script_comparison.ml +++ b/src/proto_alpha/lib_protocol/test/pbt/test_script_comparison.ml @@ -68,17 +68,20 @@ let rec reference_compare_comparable : type a. a comparable_ty -> a -> a -> int normalize_compare @@ Script_comparable.compare_tx_rollup_l2_address x y | (Bytes_key, x, y) -> normalize_compare @@ Compare.Bytes.compare x y | (Chain_id_key, x, y) -> normalize_compare @@ Script_chain_id.compare x y - | (Pair_key (tl, tr, _), (lx, rx), (ly, ry)) -> + | (Pair_key (tl, tr, _, YesYes), (lx, rx), (ly, ry)) -> let cl = reference_compare_comparable tl lx ly in if Compare.Int.(cl = 0) then reference_compare_comparable tr rx ry else cl - | (Union_key (tl, _, _), L x, L y) -> reference_compare_comparable tl x y + | (Union_key (tl, _, _, YesYes), L x, L y) -> + reference_compare_comparable tl x y | (Union_key _, L _, R _) -> -1 | (Union_key _, R _, L _) -> 1 - | (Union_key (_, tr, _), R x, R y) -> reference_compare_comparable tr x y + | (Union_key (_, tr, _, YesYes), R x, R y) -> + reference_compare_comparable tr x y | (Option_key _, None, None) -> 0 | (Option_key _, None, Some _) -> -1 | (Option_key _, Some _, None) -> 1 - | (Option_key (t, _), Some x, Some y) -> reference_compare_comparable t x y + | (Option_key (t, _, Yes), Some x, Some y) -> + reference_compare_comparable t x y (* Generation of one to three values of the same comparable type. *) diff --git a/src/proto_alpha/lib_protocol/ticket_scanner.ml b/src/proto_alpha/lib_protocol/ticket_scanner.ml index 110e0c95fc..d024631f13 100644 --- a/src/proto_alpha/lib_protocol/ticket_scanner.ml +++ b/src/proto_alpha/lib_protocol/ticket_scanner.ml @@ -124,9 +124,9 @@ module Ticket_inspection = struct | Chain_id_key -> (k [@ocaml.tailcall]) False_ht | Address_key -> (k [@ocaml.tailcall]) False_ht | Tx_rollup_l2_address_key -> (k [@ocaml.tailcall]) False_ht - | Pair_key (_, _, _) -> (k [@ocaml.tailcall]) False_ht - | Union_key (_, _, _) -> (k [@ocaml.tailcall]) False_ht - | Option_key (_, _) -> (k [@ocaml.tailcall]) False_ht + | Pair_key (_, _, _, YesYes) -> (k [@ocaml.tailcall]) False_ht + | Union_key (_, _, _, YesYes) -> (k [@ocaml.tailcall]) False_ht + | Option_key (_, _, Yes) -> (k [@ocaml.tailcall]) False_ht (* Short circuit pairing of two [has_tickets] values. If neither left nor right branch contains a ticket, [False_ht] is @@ -289,9 +289,9 @@ module Ticket_collection = struct | Chain_id_key -> (k [@ocaml.tailcall]) ctxt acc | Address_key -> (k [@ocaml.tailcall]) ctxt acc | Tx_rollup_l2_address_key -> (k [@ocaml.tailcall]) ctxt acc - | Pair_key (_, _, _) -> (k [@ocaml.tailcall]) ctxt acc - | Union_key (_, _, _) -> (k [@ocaml.tailcall]) ctxt acc - | Option_key (_, _) -> (k [@ocaml.tailcall]) ctxt acc + | Pair_key (_, _, _, YesYes) -> (k [@ocaml.tailcall]) ctxt acc + | Union_key (_, _, _, YesYes) -> (k [@ocaml.tailcall]) ctxt acc + | Option_key (_, _, Yes) -> (k [@ocaml.tailcall]) ctxt acc let tickets_of_set : type a ret. From 98ab0053e10c23876aad74322b3c93962a61d6cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Proust?= Date: Tue, 15 Mar 2022 16:47:15 +0100 Subject: [PATCH 061/100] Proto-env,Proto-updater: Use local (rather than global) return/fail --- src/lib_protocol_environment/environment_protocol_T.ml | 2 +- src/lib_protocol_environment/test/test_cache.ml | 1 + src/lib_protocol_updater/registered_protocol.ml | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lib_protocol_environment/environment_protocol_T.ml b/src/lib_protocol_environment/environment_protocol_T.ml index 32bb6b922d..f134741bf7 100644 --- a/src/lib_protocol_environment/environment_protocol_T.ml +++ b/src/lib_protocol_environment/environment_protocol_T.ml @@ -92,7 +92,7 @@ module V0toV3 let value_of_key ~chain_id:_ ~predecessor_context:_ ~predecessor_timestamp:_ ~predecessor_level:_ ~predecessor_fitness:_ ~predecessor:_ ~timestamp:_ = - return (fun _ -> + Lwt.return_ok (fun _ -> Lwt.return (Error_monad.error_with "element_of_key called on environment protocol < V3")) diff --git a/src/lib_protocol_environment/test/test_cache.ml b/src/lib_protocol_environment/test/test_cache.ml index a798c66aea..b4d7afc91b 100644 --- a/src/lib_protocol_environment/test/test_cache.ml +++ b/src/lib_protocol_environment/test/test_cache.ml @@ -695,6 +695,7 @@ let load_cache_correctly_restores_cache_in_memory builder mode Context.Cache.Internal_for_tests.same_cache_domains ctxt0 ctxt1 let load_cache_correctly_restores_cache_in_memory_normal_case = + let open Lwt_result_syntax in let builder entries key = let value = Stdlib.List.assoc key entries in return (Int value) diff --git a/src/lib_protocol_updater/registered_protocol.ml b/src/lib_protocol_updater/registered_protocol.ml index 7ab308959f..2bb14299b1 100644 --- a/src/lib_protocol_updater/registered_protocol.ml +++ b/src/lib_protocol_updater/registered_protocol.ml @@ -203,6 +203,7 @@ let () = (fun hash -> Unregistered_protocol hash) let get_result hash = + let open Lwt_tzresult_syntax in match get hash with | Some hash -> return hash | None -> fail (Unregistered_protocol hash) From 117640eb6d9c6362948c4bf40ca3c3ecf591d9b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Proust?= Date: Tue, 15 Mar 2022 16:47:15 +0100 Subject: [PATCH 062/100] Protos: Use local (rather than global) return/fail Does not affect protos, only binaries and side libs. --- src/proto_000_Ps9mPmXa/lib_client/client_proto_main.ml | 7 ++----- .../lib_client/client_proto_multisig.ml | 2 +- .../lib_client/client_proto_multisig.ml | 4 ++-- .../lib_client/client_proto_multisig.ml | 4 ++-- .../lib_client/client_proto_multisig.ml | 4 ++-- .../lib_client/client_proto_multisig.ml | 4 ++-- .../test/helpers/liquidity_baking_machine.ml | 2 +- .../lib_client/client_proto_multisig.ml | 4 ++-- .../test/helpers/liquidity_baking_machine.ml | 2 +- src/proto_alpha/bin_tx_rollup_node/daemon.ml | 2 +- .../bin_tx_rollup_node/main_tx_rollup_node_alpha.ml | 4 +--- src/proto_alpha/lib_client/client_proto_multisig.ml | 4 ++-- .../test/helpers/liquidity_baking_machine.ml | 2 +- src/proto_genesis/lib_client/client_proto_main.ml | 10 +++------- .../lib_client/client_proto_main.ml | 10 +++------- 15 files changed, 26 insertions(+), 39 deletions(-) diff --git a/src/proto_000_Ps9mPmXa/lib_client/client_proto_main.ml b/src/proto_000_Ps9mPmXa/lib_client/client_proto_main.ml index 3798909f29..edd247c79f 100644 --- a/src/proto_000_Ps9mPmXa/lib_client/client_proto_main.ml +++ b/src/proto_000_Ps9mPmXa/lib_client/client_proto_main.ml @@ -77,8 +77,7 @@ let timestamp_arg = (Clic.parameter (fun _ t -> match Time.Protocol.of_notation t with | None -> - Error_monad.failwith - "Could not parse value provided to -timestamp option" + failwith "Could not parse value provided to -timestamp option" | Some t -> return t)) let test_delay_arg = @@ -89,9 +88,7 @@ let test_delay_arg = ~default:(Int64.to_string (Int64.mul 24L 3600L)) (Clic.parameter (fun _ t -> match Int64.of_string_opt t with - | None -> - Error_monad.failwith - "Could not parse value provided to -delay option" + | None -> failwith "Could not parse value provided to -delay option" | Some t -> return t)) let proto_param ~name ~desc t = diff --git a/src/proto_006_PsCARTHA/lib_client/client_proto_multisig.ml b/src/proto_006_PsCARTHA/lib_client/client_proto_multisig.ml index 223c3a612a..8db84c6123 100644 --- a/src/proto_006_PsCARTHA/lib_client/client_proto_multisig.ml +++ b/src/proto_006_PsCARTHA/lib_client/client_proto_multisig.ml @@ -492,7 +492,7 @@ let action_to_expr ~loc = function let action_of_expr e = let fail () = - Error_monad.fail + fail (Action_deserialisation_error (Tezos_micheline.Micheline.strip_locations e)) in diff --git a/src/proto_008_PtEdo2Zk/lib_client/client_proto_multisig.ml b/src/proto_008_PtEdo2Zk/lib_client/client_proto_multisig.ml index 760064efab..9de5516df8 100644 --- a/src/proto_008_PtEdo2Zk/lib_client/client_proto_multisig.ml +++ b/src/proto_008_PtEdo2Zk/lib_client/client_proto_multisig.ml @@ -691,7 +691,7 @@ let action_to_expr ~loc ~generic action = let action_of_expr_generic e = let fail () = - Error_monad.fail + fail (Action_deserialisation_error (Tezos_micheline.Micheline.strip_locations e)) in @@ -726,7 +726,7 @@ let action_of_expr_generic e = let action_of_expr_not_generic e = let fail () = - Error_monad.fail + fail (Action_deserialisation_error (Tezos_micheline.Micheline.strip_locations e)) in diff --git a/src/proto_009_PsFLoren/lib_client/client_proto_multisig.ml b/src/proto_009_PsFLoren/lib_client/client_proto_multisig.ml index 760064efab..9de5516df8 100644 --- a/src/proto_009_PsFLoren/lib_client/client_proto_multisig.ml +++ b/src/proto_009_PsFLoren/lib_client/client_proto_multisig.ml @@ -691,7 +691,7 @@ let action_to_expr ~loc ~generic action = let action_of_expr_generic e = let fail () = - Error_monad.fail + fail (Action_deserialisation_error (Tezos_micheline.Micheline.strip_locations e)) in @@ -726,7 +726,7 @@ let action_of_expr_generic e = let action_of_expr_not_generic e = let fail () = - Error_monad.fail + fail (Action_deserialisation_error (Tezos_micheline.Micheline.strip_locations e)) in diff --git a/src/proto_010_PtGRANAD/lib_client/client_proto_multisig.ml b/src/proto_010_PtGRANAD/lib_client/client_proto_multisig.ml index a687ffa89f..14c0667b99 100644 --- a/src/proto_010_PtGRANAD/lib_client/client_proto_multisig.ml +++ b/src/proto_010_PtGRANAD/lib_client/client_proto_multisig.ml @@ -674,7 +674,7 @@ let action_to_expr ~loc ~generic action = let action_of_expr_generic e = let fail () = - Error_monad.fail + fail (Action_deserialisation_error (Tezos_micheline.Micheline.strip_locations e)) in @@ -709,7 +709,7 @@ let action_of_expr_generic e = let action_of_expr_not_generic e = let fail () = - Error_monad.fail + fail (Action_deserialisation_error (Tezos_micheline.Micheline.strip_locations e)) in diff --git a/src/proto_011_PtHangz2/lib_client/client_proto_multisig.ml b/src/proto_011_PtHangz2/lib_client/client_proto_multisig.ml index a687ffa89f..14c0667b99 100644 --- a/src/proto_011_PtHangz2/lib_client/client_proto_multisig.ml +++ b/src/proto_011_PtHangz2/lib_client/client_proto_multisig.ml @@ -674,7 +674,7 @@ let action_to_expr ~loc ~generic action = let action_of_expr_generic e = let fail () = - Error_monad.fail + fail (Action_deserialisation_error (Tezos_micheline.Micheline.strip_locations e)) in @@ -709,7 +709,7 @@ let action_of_expr_generic e = let action_of_expr_not_generic e = let fail () = - Error_monad.fail + fail (Action_deserialisation_error (Tezos_micheline.Micheline.strip_locations e)) in diff --git a/src/proto_011_PtHangz2/lib_protocol/test/helpers/liquidity_baking_machine.ml b/src/proto_011_PtHangz2/lib_protocol/test/helpers/liquidity_baking_machine.ml index 15029f71a4..778eeb892f 100644 --- a/src/proto_011_PtHangz2/lib_protocol/test/helpers/liquidity_baking_machine.ml +++ b/src/proto_011_PtHangz2/lib_protocol/test/helpers/liquidity_baking_machine.ml @@ -727,7 +727,7 @@ module ConcreteBaseMachine : let fold_m = Environment.List.fold_left_es - let pure = Error_monad.return + let pure = return let get_xtz_balance contract blk = Context.Contract.balance (B blk) contract >>= fun x -> diff --git a/src/proto_012_Psithaca/lib_client/client_proto_multisig.ml b/src/proto_012_Psithaca/lib_client/client_proto_multisig.ml index 7ffb4f8830..4f55086fb1 100644 --- a/src/proto_012_Psithaca/lib_client/client_proto_multisig.ml +++ b/src/proto_012_Psithaca/lib_client/client_proto_multisig.ml @@ -674,7 +674,7 @@ let action_to_expr ~loc ~generic action = let action_of_expr_generic e = let fail () = - Error_monad.fail + fail (Action_deserialisation_error (Tezos_micheline.Micheline.strip_locations e)) in @@ -709,7 +709,7 @@ let action_of_expr_generic e = let action_of_expr_not_generic e = let fail () = - Error_monad.fail + fail (Action_deserialisation_error (Tezos_micheline.Micheline.strip_locations e)) in diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/liquidity_baking_machine.ml b/src/proto_012_Psithaca/lib_protocol/test/helpers/liquidity_baking_machine.ml index 0e19624e0c..025e97098f 100644 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/liquidity_baking_machine.ml +++ b/src/proto_012_Psithaca/lib_protocol/test/helpers/liquidity_baking_machine.ml @@ -727,7 +727,7 @@ module ConcreteBaseMachine : let fold_m = Environment.List.fold_left_es - let pure = Error_monad.return + let pure = return let get_xtz_balance contract blk = Context.Contract.balance (B blk) contract >>= fun x -> diff --git a/src/proto_alpha/bin_tx_rollup_node/daemon.ml b/src/proto_alpha/bin_tx_rollup_node/daemon.ml index 95f74db43b..d7241266c1 100644 --- a/src/proto_alpha/bin_tx_rollup_node/daemon.ml +++ b/src/proto_alpha/bin_tx_rollup_node/daemon.ml @@ -368,7 +368,7 @@ let rec connect ~delay cctxt = let open Lwt_syntax in let* res = Monitor_services.heads cctxt cctxt#chain in match res with - | Ok (stream, stopper) -> Error_monad.return (stream, stopper) + | Ok (stream, stopper) -> return_ok (stream, stopper) | Error _ -> let* () = Event.(emit cannot_connect) delay in let* () = Lwt_unix.sleep delay in diff --git a/src/proto_alpha/bin_tx_rollup_node/main_tx_rollup_node_alpha.ml b/src/proto_alpha/bin_tx_rollup_node/main_tx_rollup_node_alpha.ml index 006d538c3e..24455ed7c2 100644 --- a/src/proto_alpha/bin_tx_rollup_node/main_tx_rollup_node_alpha.ml +++ b/src/proto_alpha/bin_tx_rollup_node/main_tx_rollup_node_alpha.ml @@ -119,9 +119,7 @@ let group = title = "Commands related to the transaction rollup node"; } -let to_tzresult msg = function - | Some x -> Error_monad.return x - | None -> Error_monad.failwith msg +let to_tzresult msg = function Some x -> return x | None -> failwith msg let configuration_init_command = let open Clic in diff --git a/src/proto_alpha/lib_client/client_proto_multisig.ml b/src/proto_alpha/lib_client/client_proto_multisig.ml index 17b6261c98..ce080f0bdf 100644 --- a/src/proto_alpha/lib_client/client_proto_multisig.ml +++ b/src/proto_alpha/lib_client/client_proto_multisig.ml @@ -677,7 +677,7 @@ let action_to_expr ~loc ~generic action = let action_of_expr_generic e = let fail () = - Error_monad.fail + fail (Action_deserialisation_error (Tezos_micheline.Micheline.strip_locations e)) in @@ -712,7 +712,7 @@ let action_of_expr_generic e = let action_of_expr_not_generic e = let fail () = - Error_monad.fail + fail (Action_deserialisation_error (Tezos_micheline.Micheline.strip_locations e)) in diff --git a/src/proto_alpha/lib_protocol/test/helpers/liquidity_baking_machine.ml b/src/proto_alpha/lib_protocol/test/helpers/liquidity_baking_machine.ml index a43e6aca77..e01b2436df 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/liquidity_baking_machine.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/liquidity_baking_machine.ml @@ -728,7 +728,7 @@ module ConcreteBaseMachine : let fold_m = Environment.List.fold_left_es - let pure = Error_monad.return + let pure = return let get_xtz_balance contract blk = Context.Contract.balance (B blk) contract >>= fun x -> diff --git a/src/proto_genesis/lib_client/client_proto_main.ml b/src/proto_genesis/lib_client/client_proto_main.ml index fd8ea25d98..0478fd5f31 100644 --- a/src/proto_genesis/lib_client/client_proto_main.ml +++ b/src/proto_genesis/lib_client/client_proto_main.ml @@ -73,8 +73,7 @@ let timestamp_arg = (Clic.parameter (fun _ t -> match Time.System.of_notation_opt t with | None -> - Error_monad.failwith - "Could not parse value provided to -timestamp option" + failwith "Could not parse value provided to -timestamp option" | Some t -> return t)) let test_delay_arg = @@ -85,9 +84,7 @@ let test_delay_arg = ~default:(Int64.to_string (Int64.mul 24L 3600L)) (Clic.parameter (fun _ t -> match Int64.of_string_opt t with - | None -> - Error_monad.failwith - "Could not parse value provided to -delay option" + | None -> failwith "Could not parse value provided to -delay option" | Some t -> return t)) let proto_param ~name ~desc t = @@ -108,8 +105,7 @@ let commands () = (parameter (fun _ t -> match Time.Protocol.of_notation t with | None -> - Error_monad.failwith - "Could not parse value provided to -timestamp option" + failwith "Could not parse value provided to -timestamp option" | Some t -> return t))) in [ diff --git a/src/proto_genesis_carthagenet/lib_client/client_proto_main.ml b/src/proto_genesis_carthagenet/lib_client/client_proto_main.ml index 177d533839..6ace9b8d57 100644 --- a/src/proto_genesis_carthagenet/lib_client/client_proto_main.ml +++ b/src/proto_genesis_carthagenet/lib_client/client_proto_main.ml @@ -77,8 +77,7 @@ let timestamp_arg = (Clic.parameter (fun _ t -> match Time.System.of_notation_opt t with | None -> - Error_monad.failwith - "Could not parse value provided to -timestamp option" + failwith "Could not parse value provided to -timestamp option" | Some t -> return t)) let test_delay_arg = @@ -89,9 +88,7 @@ let test_delay_arg = ~default:(Int64.to_string (Int64.mul 24L 3600L)) (Clic.parameter (fun _ t -> match Int64.of_string_opt t with - | None -> - Error_monad.failwith - "Could not parse value provided to -delay option" + | None -> failwith "Could not parse value provided to -delay option" | Some t -> return t)) let proto_param ~name ~desc t = @@ -112,8 +109,7 @@ let commands () = (parameter (fun _ t -> match Time.Protocol.of_notation t with | None -> - Error_monad.failwith - "Could not parse value provided to -timestamp option" + failwith "Could not parse value provided to -timestamp option" | Some t -> return t))) in [ From b9044a8be305ecbca41eb6550380f46a2d92f2ef Mon Sep 17 00:00:00 2001 From: Arvid Jakobsson Date: Thu, 17 Mar 2022 15:14:08 +0100 Subject: [PATCH 063/100] Proto/Test: Expr_common: make ~loc argument optional --- .../lib_protocol/test/helpers/cpmm_repr.ml | 2 +- .../lib_protocol/test/helpers/expr_common.ml | 41 +++++++++++-------- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/proto_alpha/lib_protocol/test/helpers/cpmm_repr.ml b/src/proto_alpha/lib_protocol/test/helpers/cpmm_repr.ml index 0af1c8c6e2..b9cb8cb0ef 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/cpmm_repr.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/cpmm_repr.ml @@ -304,7 +304,7 @@ module Parameter = struct int ~loc maxTokensDeposited; timestamp ~loc deadline; ] - | Default () -> unit ~loc + | Default () -> unit ~loc () | RemoveLiquidity {to_; lqtBurned; minXtzWithdrawn; minTokensWithdrawn; deadline} -> comb diff --git a/src/proto_alpha/lib_protocol/test/helpers/expr_common.ml b/src/proto_alpha/lib_protocol/test/helpers/expr_common.ml index 1dd79eeba5..0833a9d1fe 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/expr_common.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/expr_common.ml @@ -28,41 +28,50 @@ open Alpha_context (* From OCaml values to Micheline expressions *) -let seq ~loc l = Tezos_micheline.Micheline.Seq (loc, l) +let seq ?(loc = 0) l = Tezos_micheline.Micheline.Seq (loc, l) -let pair ~loc a b = +let pair ?(loc = 0) a b = Tezos_micheline.Micheline.Prim (loc, Script.D_Pair, [a; b], []) -let comb ~loc es = Tezos_micheline.Micheline.Prim (loc, Script.D_Pair, es, []) +let pair_n ?(loc = 0) els = + Tezos_micheline.Micheline.Prim (loc, Script.D_Pair, els, []) -let none ~loc () = Tezos_micheline.Micheline.Prim (loc, Script.D_None, [], []) +let comb ?(loc = 0) es = + Tezos_micheline.Micheline.Prim (loc, Script.D_Pair, es, []) -let some ~loc a = Tezos_micheline.Micheline.Prim (loc, Script.D_Some, [a], []) +let none ?(loc = 0) () = + Tezos_micheline.Micheline.Prim (loc, Script.D_None, [], []) -let left ~loc a = Tezos_micheline.Micheline.Prim (loc, Script.D_Left, [a], []) +let some ?(loc = 0) a = + Tezos_micheline.Micheline.Prim (loc, Script.D_Some, [a], []) -let right ~loc b = Tezos_micheline.Micheline.Prim (loc, Script.D_Right, [b], []) +let left ?(loc = 0) a = + Tezos_micheline.Micheline.Prim (loc, Script.D_Left, [a], []) -let unit ~loc = Tezos_micheline.Micheline.Prim (loc, Script.D_Unit, [], []) +let right ?(loc = 0) b = + Tezos_micheline.Micheline.Prim (loc, Script.D_Right, [b], []) -let int ~loc i = Tezos_micheline.Micheline.Int (loc, i) +let unit ?(loc = 0) () = + Tezos_micheline.Micheline.Prim (loc, Script.D_Unit, [], []) -let bytes ~loc s = Tezos_micheline.Micheline.Bytes (loc, s) +let int ?(loc = 0) i = Tezos_micheline.Micheline.Int (loc, i) -let string ~loc s = Tezos_micheline.Micheline.String (loc, s) +let bytes ?(loc = 0) s = Tezos_micheline.Micheline.Bytes (loc, s) -let mutez ~loc m = int ~loc (Z.of_int64 (Tez.to_mutez m)) +let string ?(loc = 0) s = Tezos_micheline.Micheline.String (loc, s) + +let mutez ?(loc = 0) m = int ~loc (Z.of_int64 (Tez.to_mutez m)) (* Translate a timestamp to a Micheline expression in optimized form *) -let timestamp ~loc ts = int ~loc (Script_timestamp.to_zint ts) +let timestamp ?(loc = 0) ts = int ~loc (Script_timestamp.to_zint ts) -let address ~loc adr = +let address ?(loc = 0) adr = bytes ~loc @@ Data_encoding.Binary.to_bytes_exn Contract.encoding adr -let address_string ~loc adr = string ~loc @@ Contract.to_b58check adr +let address_string ?(loc = 0) adr = string ~loc @@ Contract.to_b58check adr -let big_map_id ~loc id = int ~loc @@ Big_map.Id.unparse_to_z id +let big_map_id ?(loc = 0) id = int ~loc @@ Big_map.Id.unparse_to_z id (* From Micheline expressions to OCaml values *) From 17bda1b55a6c47a87a2fffac69ac54c0b86db9ca Mon Sep 17 00:00:00 2001 From: Arvid Jakobsson Date: Fri, 18 Mar 2022 11:27:26 +0100 Subject: [PATCH 064/100] Tx_rollup: impose size limit on ticket contents in deposits --- src/proto_alpha/lib_client/mockup.ml | 20 +- .../lib_parameters/default_parameters.ml | 1 + .../lib_protocol/alpha_context.mli | 3 + src/proto_alpha/lib_protocol/apply.ml | 21 ++ .../lib_protocol/constants_repr.ml | 13 +- .../lib_protocol/constants_repr.mli | 2 + .../lib_protocol/constants_storage.ml | 4 + .../lib_protocol/constants_storage.mli | 2 + src/proto_alpha/lib_protocol/raw_context.ml | 1 + .../tx_rollup_deposit_pair_string.tz | 35 +++ .../contracts/tx_rollup_deposit_string.tz | 33 +++ .../integration/operations/test_tx_rollup.ml | 221 +++++++++++++++++- .../lib_protocol/tx_rollup_errors_repr.ml | 17 +- tests_python/tests_alpha/test_mockup.py | 1 + tezt/_regressions/rpc/alpha.client.others.out | 3 +- tezt/_regressions/rpc/alpha.light.others.out | 3 +- tezt/_regressions/rpc/alpha.proxy.others.out | 3 +- .../rpc/alpha.proxy_server.others.out | 3 +- 18 files changed, 367 insertions(+), 19 deletions(-) create mode 100644 src/proto_alpha/lib_protocol/test/integration/operations/contracts/tx_rollup_deposit_pair_string.tz create mode 100644 src/proto_alpha/lib_protocol/test/integration/operations/contracts/tx_rollup_deposit_string.tz diff --git a/src/proto_alpha/lib_client/mockup.ml b/src/proto_alpha/lib_client/mockup.ml index 64a8ab6c41..703507fa26 100644 --- a/src/proto_alpha/lib_client/mockup.ml +++ b/src/proto_alpha/lib_client/mockup.ml @@ -83,6 +83,7 @@ module Protocol_constants_overrides = struct tx_rollup_max_messages_per_inbox : int option; tx_rollup_max_finalized_levels : int option; tx_rollup_cost_per_byte_ema_factor : int option; + tx_rollup_max_ticket_payload_size : int option; sc_rollup_enable : bool option; sc_rollup_origination_size : int option; sc_rollup_challenge_window_in_blocks : int option; @@ -145,7 +146,8 @@ module Protocol_constants_overrides = struct c.tx_rollup_withdraw_period, c.tx_rollup_max_messages_per_inbox ), ( c.tx_rollup_max_finalized_levels, - c.tx_rollup_cost_per_byte_ema_factor ) ), + c.tx_rollup_cost_per_byte_ema_factor, + c.tx_rollup_max_ticket_payload_size ) ), ( c.sc_rollup_enable, c.sc_rollup_origination_size, c.sc_rollup_challenge_window_in_blocks ) ) ) ) ) ) )) @@ -197,7 +199,8 @@ module Protocol_constants_overrides = struct tx_rollup_withdraw_period, tx_rollup_max_messages_per_inbox ), ( tx_rollup_max_finalized_levels, - tx_rollup_cost_per_byte_ema_factor ) ), + tx_rollup_cost_per_byte_ema_factor, + tx_rollup_max_ticket_payload_size ) ), ( sc_rollup_enable, sc_rollup_origination_size, sc_rollup_challenge_window_in_blocks ) ) ) ) ) ) ) -> @@ -248,6 +251,7 @@ module Protocol_constants_overrides = struct tx_rollup_max_messages_per_inbox; tx_rollup_max_finalized_levels; tx_rollup_cost_per_byte_ema_factor; + tx_rollup_max_ticket_payload_size; sc_rollup_enable; sc_rollup_origination_size; sc_rollup_challenge_window_in_blocks; @@ -321,9 +325,10 @@ module Protocol_constants_overrides = struct (opt "tx_rollup_max_unfinalized_levels" int31) (opt "tx_rollup_withdraw_period" int31) (opt "tx_rollup_max_messages_per_inbox" int31)) - (obj2 + (obj3 (opt "tx_rollup_max_finalized_levels" int31) - (opt "tx_rollup_cost_per_byte_ema_factor" int31))) + (opt "tx_rollup_cost_per_byte_ema_factor" int31) + (opt "tx_rollup_max_ticket_payload_size" int31))) (obj3 (opt "sc_rollup_enable" bool) (opt "sc_rollup_origination_size" int31) @@ -407,6 +412,8 @@ module Protocol_constants_overrides = struct Some parametric.tx_rollup_max_finalized_levels; tx_rollup_cost_per_byte_ema_factor = Some parametric.tx_rollup_cost_per_byte_ema_factor; + tx_rollup_max_ticket_payload_size = + Some parametric.tx_rollup_max_ticket_payload_size; sc_rollup_enable = Some parametric.sc_rollup_enable; sc_rollup_origination_size = Some parametric.sc_rollup_origination_size; sc_rollup_challenge_window_in_blocks = @@ -467,6 +474,7 @@ module Protocol_constants_overrides = struct tx_rollup_max_messages_per_inbox = None; tx_rollup_max_finalized_levels = None; tx_rollup_cost_per_byte_ema_factor = None; + tx_rollup_max_ticket_payload_size = None; sc_rollup_enable = None; sc_rollup_origination_size = None; sc_rollup_challenge_window_in_blocks = None; @@ -916,6 +924,10 @@ module Protocol_constants_overrides = struct Option.value ~default:c.tx_rollup_cost_per_byte_ema_factor o.tx_rollup_cost_per_byte_ema_factor; + tx_rollup_max_ticket_payload_size = + Option.value + ~default:c.tx_rollup_max_ticket_payload_size + o.tx_rollup_max_ticket_payload_size; sc_rollup_enable = Option.value ~default:c.sc_rollup_enable o.sc_rollup_enable; sc_rollup_origination_size = diff --git a/src/proto_alpha/lib_parameters/default_parameters.ml b/src/proto_alpha/lib_parameters/default_parameters.ml index 43efa29ddb..3743a583c9 100644 --- a/src/proto_alpha/lib_parameters/default_parameters.ml +++ b/src/proto_alpha/lib_parameters/default_parameters.ml @@ -117,6 +117,7 @@ let constants_mainnet = (* Must be greater than the withdraw period. *) tx_rollup_max_finalized_levels = tx_rollup_withdraw_period + 100; tx_rollup_cost_per_byte_ema_factor = 120; + tx_rollup_max_ticket_payload_size = 10_240; sc_rollup_enable = false; (* The following value is chosen to prevent spam. *) sc_rollup_origination_size = 6_314; diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index 0b48f65763..de8ca91097 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -802,6 +802,7 @@ module Constants : sig tx_rollup_max_messages_per_inbox : int; tx_rollup_max_finalized_levels : int; tx_rollup_cost_per_byte_ema_factor : int; + tx_rollup_max_ticket_payload_size : int; sc_rollup_enable : bool; sc_rollup_origination_size : int; sc_rollup_challenge_window_in_blocks : int; @@ -904,6 +905,8 @@ module Constants : sig val tx_rollup_max_finalized_levels : context -> int + val tx_rollup_max_ticket_payload_size : context -> int + val sc_rollup_enable : context -> bool val sc_rollup_origination_size : context -> int diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index 8264047966..49284944c6 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -1059,6 +1059,27 @@ let apply_transaction_to_rollup ~consume_deserialization_gas ~ctxt ~parameters >>?= fun (parameters, ctxt) -> Script_ir_translator.parse_tx_rollup_deposit_parameters ctxt parameters >>?= fun (Tx_rollup.{ticketer; contents; ty; amount; destination}, ctxt) -> + let (ty_nodes, ty_size) = Script_typed_ir_size.node_size ty in + let (content_nodes, content_size) = + Script_typed_ir_size.node_size contents + in + let content_size = Saturation_repr.to_int content_size in + let ty_size = Saturation_repr.to_int ty_size in + let limit = + Alpha_context.Constants.tx_rollup_max_ticket_payload_size ctxt + in + let content_size_cost = + Script_typed_ir_size_costs.nodes_cost ~nodes:content_nodes + in + let ty_size_cost = Script_typed_ir_size_costs.nodes_cost ~nodes:ty_nodes in + Gas.consume ctxt content_size_cost >>?= fun ctxt -> + Gas.consume ctxt ty_size_cost >>?= fun ctxt -> + let payload_size = ty_size + content_size in + fail_when + Compare.Int.(payload_size > limit) + (Tx_rollup_errors_repr.Ticket_payload_size_limit_exceeded + {payload_size; limit}) + >>=? fun () -> Tx_rollup.hash_ticket ctxt dst_rollup ~contents ~ticketer ~ty >>?= fun (ticket_hash, ctxt) -> (* If the ticket deposit fails on L2 for some reason diff --git a/src/proto_alpha/lib_protocol/constants_repr.ml b/src/proto_alpha/lib_protocol/constants_repr.ml index 1052a6528f..51d7cd88fb 100644 --- a/src/proto_alpha/lib_protocol/constants_repr.ml +++ b/src/proto_alpha/lib_protocol/constants_repr.ml @@ -170,6 +170,7 @@ type parametric = { tx_rollup_max_messages_per_inbox : int; tx_rollup_max_finalized_levels : int; tx_rollup_cost_per_byte_ema_factor : int; + tx_rollup_max_ticket_payload_size : int; sc_rollup_enable : bool; sc_rollup_origination_size : int; sc_rollup_challenge_window_in_blocks : int; @@ -225,7 +226,8 @@ let parametric_encoding = c.tx_rollup_max_unfinalized_levels, c.tx_rollup_max_messages_per_inbox ), ( c.tx_rollup_max_finalized_levels, - c.tx_rollup_cost_per_byte_ema_factor ) ), + c.tx_rollup_cost_per_byte_ema_factor, + c.tx_rollup_max_ticket_payload_size ) ), ( c.sc_rollup_enable, c.sc_rollup_origination_size, c.sc_rollup_challenge_window_in_blocks ) ) ) ) ) ) )) @@ -275,7 +277,8 @@ let parametric_encoding = tx_rollup_max_unfinalized_levels, tx_rollup_max_messages_per_inbox ), ( tx_rollup_max_finalized_levels, - tx_rollup_cost_per_byte_ema_factor ) ), + tx_rollup_cost_per_byte_ema_factor, + tx_rollup_max_ticket_payload_size ) ), ( sc_rollup_enable, sc_rollup_origination_size, sc_rollup_challenge_window_in_blocks ) ) ) ) ) ) ) -> @@ -327,6 +330,7 @@ let parametric_encoding = tx_rollup_max_messages_per_inbox; tx_rollup_max_finalized_levels; tx_rollup_cost_per_byte_ema_factor; + tx_rollup_max_ticket_payload_size; sc_rollup_enable; sc_rollup_origination_size; sc_rollup_challenge_window_in_blocks; @@ -395,9 +399,10 @@ let parametric_encoding = (req "tx_rollup_withdraw_period" int31) (req "tx_rollup_max_unfinalized_levels" int31) (req "tx_rollup_max_messages_per_inbox" int31)) - (obj2 + (obj3 (req "tx_rollup_max_finalized_levels" int31) - (req "tx_rollup_cost_per_byte_ema_factor" int31))) + (req "tx_rollup_cost_per_byte_ema_factor" int31) + (req "tx_rollup_max_ticket_payload_size" int31))) (obj3 (req "sc_rollup_enable" bool) (req "sc_rollup_origination_size" int31) diff --git a/src/proto_alpha/lib_protocol/constants_repr.mli b/src/proto_alpha/lib_protocol/constants_repr.mli index 0926eee41d..eb60dc7b2e 100644 --- a/src/proto_alpha/lib_protocol/constants_repr.mli +++ b/src/proto_alpha/lib_protocol/constants_repr.mli @@ -147,6 +147,8 @@ type parametric = { (* The number of blocks used to compute the ema factor determining the cost per byte for new messages in the inbox. *) tx_rollup_cost_per_byte_ema_factor : int; + (* maximum size, in bytes, of the contents given in deposited tickets. *) + tx_rollup_max_ticket_payload_size : int; sc_rollup_enable : bool; sc_rollup_origination_size : int; sc_rollup_challenge_window_in_blocks : int; diff --git a/src/proto_alpha/lib_protocol/constants_storage.ml b/src/proto_alpha/lib_protocol/constants_storage.ml index ba9c808da1..361611fd2b 100644 --- a/src/proto_alpha/lib_protocol/constants_storage.ml +++ b/src/proto_alpha/lib_protocol/constants_storage.ml @@ -190,6 +190,10 @@ let tx_rollup_cost_per_byte_ema_factor c = let constants = Raw_context.constants c in constants.tx_rollup_cost_per_byte_ema_factor +let tx_rollup_max_ticket_payload_size c = + let constants = Raw_context.constants c in + constants.tx_rollup_max_ticket_payload_size + let ratio_of_frozen_deposits_slashed_per_double_endorsement c = let constants = Raw_context.constants c in constants.ratio_of_frozen_deposits_slashed_per_double_endorsement diff --git a/src/proto_alpha/lib_protocol/constants_storage.mli b/src/proto_alpha/lib_protocol/constants_storage.mli index cc33776b3a..ad3fbb1f10 100644 --- a/src/proto_alpha/lib_protocol/constants_storage.mli +++ b/src/proto_alpha/lib_protocol/constants_storage.mli @@ -106,6 +106,8 @@ val tx_rollup_max_finalized_levels : Raw_context.t -> int val tx_rollup_cost_per_byte_ema_factor : Raw_context.t -> int +val tx_rollup_max_ticket_payload_size : Raw_context.t -> int + val ratio_of_frozen_deposits_slashed_per_double_endorsement : Raw_context.t -> Constants_repr.ratio diff --git a/src/proto_alpha/lib_protocol/raw_context.ml b/src/proto_alpha/lib_protocol/raw_context.ml index 191147f2f3..ed71e6e70b 100644 --- a/src/proto_alpha/lib_protocol/raw_context.ml +++ b/src/proto_alpha/lib_protocol/raw_context.ml @@ -916,6 +916,7 @@ let prepare_first_block ~level ~timestamp ctxt = tx_rollup_max_finalized_levels = tx_rollup_withdraw_period + 100; (* The default ema factor is [120] blocks, so about one hour. *) tx_rollup_cost_per_byte_ema_factor = 120; + tx_rollup_max_ticket_payload_size = 10_240; sc_rollup_enable = false; (* The following value is chosen to prevent spam. *) sc_rollup_origination_size = 6_314; diff --git a/src/proto_alpha/lib_protocol/test/integration/operations/contracts/tx_rollup_deposit_pair_string.tz b/src/proto_alpha/lib_protocol/test/integration/operations/contracts/tx_rollup_deposit_pair_string.tz new file mode 100644 index 0000000000..de50754c46 --- /dev/null +++ b/src/proto_alpha/lib_protocol/test/integration/operations/contracts/tx_rollup_deposit_pair_string.tz @@ -0,0 +1,35 @@ +parameter (pair address tx_rollup_l2_address string); +storage (unit); +code { + # cast the address to contract type + CAR; + UNPAIR; + CONTRACT %deposit (pair (ticket (pair unit string)) tx_rollup_l2_address); + + IF_SOME { + SWAP; + UNPAIR; SWAP; + + # create a ticket + PUSH nat 10; + SWAP; + UNIT; + PAIR; + TICKET; + PAIR; + + # amount for transfering + PUSH mutez 0; + SWAP; + + # deposit + TRANSFER_TOKENS; + + DIP { NIL operation }; + CONS; + + DIP { PUSH unit Unit }; + PAIR; + } + { FAIL ; } + } diff --git a/src/proto_alpha/lib_protocol/test/integration/operations/contracts/tx_rollup_deposit_string.tz b/src/proto_alpha/lib_protocol/test/integration/operations/contracts/tx_rollup_deposit_string.tz new file mode 100644 index 0000000000..af81b322b5 --- /dev/null +++ b/src/proto_alpha/lib_protocol/test/integration/operations/contracts/tx_rollup_deposit_string.tz @@ -0,0 +1,33 @@ +parameter (pair address tx_rollup_l2_address string); +storage (unit); +code { + # cast the address to contract type + CAR; + UNPAIR; + CONTRACT %deposit (pair (ticket string) tx_rollup_l2_address); + + IF_SOME { + SWAP; + UNPAIR; SWAP; + + # create a ticket + PUSH nat 10; + SWAP; + TICKET; + PAIR; + + # amount for transfering + PUSH mutez 0; + SWAP; + + # deposit + TRANSFER_TOKENS; + + DIP { NIL operation }; + CONS; + + DIP { PUSH unit Unit }; + PAIR; + } + { FAIL ; } + } diff --git a/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml b/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml index 8c2625f969..0fe2d435fb 100644 --- a/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml +++ b/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml @@ -132,6 +132,9 @@ let parsing_tests = let message_hash_testable : Tx_rollup_message.hash Alcotest.testable = Alcotest.testable Tx_rollup_message.pp_hash ( = ) +let sint_testable : _ Saturation_repr.t Alcotest.testable = + Alcotest.testable Saturation_repr.pp ( = ) + let wrap m = m >|= Environment.wrap_tzresult (** [inbox_burn state size] computes the burn (per byte of message) @@ -165,7 +168,8 @@ let check_batch_in_inbox : (** [context_init n] initializes a context with no consensus rewards to not interfere with balances prediction. It returns the created context and [n] contracts. *) -let context_init ?(tx_rollup_max_unfinalized_levels = 2100) n = +let context_init ?(tx_rollup_max_unfinalized_levels = 2100) + ?(tx_rollup_max_ticket_payload_size = 10_240) n = Context.init_with_constants { Context.default_test_contants with @@ -178,22 +182,33 @@ let context_init ?(tx_rollup_max_unfinalized_levels = 2100) n = endorsing_reward_per_slot = Tez.zero; baking_reward_bonus_per_slot = Tez.zero; baking_reward_fixed_portion = Tez.zero; + tx_rollup_max_ticket_payload_size; } n (** [context_init1] initializes a context with no consensus rewards to not interfere with balances prediction. It returns the created context and 1 contract. *) -let context_init1 () = - context_init 1 >|=? function +let context_init1 ?tx_rollup_max_unfinalized_levels + ?tx_rollup_max_ticket_payload_size () = + context_init + ?tx_rollup_max_unfinalized_levels + ?tx_rollup_max_ticket_payload_size + 1 + >|=? function | (b, contract_1 :: _) -> (b, contract_1) | (_, _) -> assert false (** [context_init2] initializes a context with no consensus rewards to not interfere with balances prediction. It returns the created context and 2 contracts. *) -let context_init2 () = - context_init 2 >|=? function +let context_init2 ?tx_rollup_max_unfinalized_levels + ?tx_rollup_max_ticket_payload_size () = + context_init + ?tx_rollup_max_unfinalized_levels + ?tx_rollup_max_ticket_payload_size + 2 + >|=? function | (b, contract_1 :: contract_2 :: _) -> (b, contract_1, contract_2) | (_, _) -> assert false @@ -825,6 +840,190 @@ let test_invalid_deposit_not_ticket () = | _ -> false)) >>=? fun _ -> return_unit +let string_ticket_of_size expected_size = + if expected_size < 0 && expected_size mod 8 <> 0 then + Alcotest.fail + (Format.asprintf + "string_ticket_of_size: argument [expected_size] must be positive and \ + a multiple of 8") ; + let ticket_contents_ty = + Tezos_micheline.Micheline.Prim (0, Michelson_v1_primitives.T_string, [], []) + in + let (_, ticket_contents_ty_size) = + Script_typed_ir_size.node_size ticket_contents_ty + in + Alcotest.( + check + (option sint_testable) + "Expected size of ticket_contents type" + (Saturation_repr.of_int_opt 40) + (Some ticket_contents_ty_size)) ; + let (_, empty_string_size) = + Script_typed_ir_size.node_size (Expr_common.string "") + in + let ticket_contents = + Expr_common.string + (String.make + (expected_size + - Saturation_repr.to_int ticket_contents_ty_size + - Saturation_repr.to_int empty_string_size) + 'a') + in + let (_, ticket_contents_size) = + Script_typed_ir_size.node_size ticket_contents + in + Alcotest.( + check + (option sint_testable) + "Expected size of ticket_contents type + ticket_contents" + (Saturation_repr.of_int_opt expected_size) + (Some Saturation_repr.(add ticket_contents_ty_size ticket_contents_size))) ; + ticket_contents + +(** [test_invalid_deposit_too_big_ticket] tests that depositing a ticket that + has a content whose size exceeds [tx_rollup_max_ticket_payload_size] fails.*) +let test_invalid_deposit_too_big_ticket () = + let (_, _, pkh) = gen_l2_account () in + context_init1 () >>=? fun (b, account) -> + Context.get_constants (B b) >>=? fun constant -> + let tx_rollup_max_ticket_payload_size = + constant.parametric.tx_rollup_max_ticket_payload_size + in + originate b account >>=? fun (b, tx_rollup) -> + Contract_helpers.originate_contract + "contracts/tx_rollup_deposit_string.tz" + "Unit" + account + b + (is_implicit_exn account) + >>=? fun (contract, b) -> + Incremental.begin_construction b >>=? fun i -> + let ticket_contents = + string_ticket_of_size (tx_rollup_max_ticket_payload_size + 8) + in + let parameters = + Expr_common.( + pair_n + [ + string (Tx_rollup.to_b58check tx_rollup); + string (Tx_rollup_l2_address.to_b58check pkh); + ticket_contents; + ]) + |> Tezos_micheline.Micheline.strip_locations |> Script.lazy_expr + in + let fee = Test_tez.of_int 10 in + Op.transaction + ~counter:(Z.of_int 2) + ~fee + (B b) + account + contract + Tez.zero + ~parameters + >>=? fun op -> + Incremental.add_operation + i + op + ~expect_failure: + (check_proto_error_f (function + | Tx_rollup_errors_repr.Ticket_payload_size_limit_exceeded _ -> true + | _ -> false)) + >>=? fun _ -> return_unit + +(** [test_invalid_deposit_too_big_ticket_type] tests that depositing a + ticket that has a content and type whose summed size exceeds + [tx_rollup_max_ticket_payload_size] fails.*) +let test_invalid_deposit_too_big_ticket_type () = + let (_, _, pkh) = gen_l2_account () in + context_init1 () >>=? fun (b, account) -> + Context.get_constants (B b) >>=? fun constant -> + let tx_rollup_max_ticket_payload_size = + constant.parametric.tx_rollup_max_ticket_payload_size + in + originate b account >>=? fun (b, tx_rollup) -> + Contract_helpers.originate_contract + "contracts/tx_rollup_deposit_pair_string.tz" + "Unit" + account + b + (is_implicit_exn account) + >>=? fun (contract, b) -> + Incremental.begin_construction b >>=? fun i -> + let ticket_contents = + string_ticket_of_size tx_rollup_max_ticket_payload_size + in + let parameters = + Expr_common.( + pair_n + [ + string (Tx_rollup.to_b58check tx_rollup); + string (Tx_rollup_l2_address.to_b58check pkh); + ticket_contents; + ]) + |> Tezos_micheline.Micheline.strip_locations |> Script.lazy_expr + in + let fee = Test_tez.of_int 10 in + Op.transaction + ~counter:(Z.of_int 2) + ~fee + (B b) + account + contract + Tez.zero + ~parameters + >>=? fun op -> + Incremental.add_operation + i + op + ~expect_failure: + (check_proto_error_f (function + | Tx_rollup_errors_repr.Ticket_payload_size_limit_exceeded _ -> true + | _ -> false)) + >>=? fun _ -> return_unit + +(** [test_valid_deposit_big_ticket] tests that depositing a ticket whose size is exactly + [tx_rollup_max_ticket_payload_size] succeeds.*) +let test_valid_deposit_big_ticket () = + let (_, _, pkh) = gen_l2_account () in + context_init1 () >>=? fun (b, account) -> + Context.get_constants (B b) >>=? fun constant -> + let tx_rollup_max_ticket_payload_size = + constant.parametric.tx_rollup_max_ticket_payload_size + in + originate b account >>=? fun (b, tx_rollup) -> + Contract_helpers.originate_contract + "contracts/tx_rollup_deposit_string.tz" + "Unit" + account + b + (is_implicit_exn account) + >>=? fun (contract, b) -> + Incremental.begin_construction b >>=? fun i -> + let ticket_contents = + string_ticket_of_size tx_rollup_max_ticket_payload_size + in + let parameters = + Expr_common.( + pair_n + [ + string (Tx_rollup.to_b58check tx_rollup); + string (Tx_rollup_l2_address.to_b58check pkh); + ticket_contents; + ]) + |> Tezos_micheline.Micheline.strip_locations |> Script.lazy_expr + in + let fee = Test_tez.of_int 10 in + Op.transaction + ~counter:(Z.of_int 2) + ~fee + (B b) + account + contract + Tez.zero + ~parameters + >>=? fun op -> + Incremental.add_operation i op >>=? fun _ -> return_unit + (** [test_invalid_entrypoint] checks that a transaction to an invalid entrypoint of a transaction rollup fails. *) let test_invalid_entrypoint () = @@ -2550,6 +2749,18 @@ let tests = "Test deposit with invalid parameter" `Quick test_invalid_deposit_not_ticket; + Tztest.tztest + "Test deposit with too big ticket" + `Quick + test_invalid_deposit_too_big_ticket; + Tztest.tztest + "Test deposit with too big ticket type" + `Quick + test_invalid_deposit_too_big_ticket_type; + Tztest.tztest + "Test valid deposit with big ticket" + `Quick + test_valid_deposit_big_ticket; Tztest.tztest "Test valid deposit to inexistant rollup" `Quick diff --git a/src/proto_alpha/lib_protocol/tx_rollup_errors_repr.ml b/src/proto_alpha/lib_protocol/tx_rollup_errors_repr.ml index 7ebf1530eb..cdf38070e4 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_errors_repr.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_errors_repr.ml @@ -77,7 +77,7 @@ type error += computed : Tx_rollup_commitment_repr.Message_result_hash.t; expected : Tx_rollup_commitment_repr.Message_result_hash.t; } - | Ticket_content_size_limit_exceeded of {content_size : int; limit : int} + | Ticket_payload_size_limit_exceeded of {payload_size : int; limit : int} let () = let open Data_encoding in @@ -511,4 +511,17 @@ let () = Some (provided, computed, expected) | _ -> None) (fun (provided, computed, expected) -> - Wrong_rejection_hashes {provided; computed; expected}) + Wrong_rejection_hashes {provided; computed; expected}) ; + (* ticket_payload_size_limit_exceeded *) + register_error_kind + `Permanent + ~id:"tx_rollup_ticket_payload_size_limit_exceeded" + ~title:"The payload of the deposited ticket exceeded the size limit" + ~description:"The payload of the deposited ticket exceeded the size limit" + (obj2 (req "payload_size" int31) (req "limit" int31)) + (function + | Ticket_payload_size_limit_exceeded {payload_size; limit} -> + Some (payload_size, limit) + | _ -> None) + (fun (payload_size, limit) -> + Ticket_payload_size_limit_exceeded {payload_size; limit}) diff --git a/tests_python/tests_alpha/test_mockup.py b/tests_python/tests_alpha/test_mockup.py index 3abfe55566..07e742a2c0 100644 --- a/tests_python/tests_alpha/test_mockup.py +++ b/tests_python/tests_alpha/test_mockup.py @@ -666,6 +666,7 @@ def _test_create_mockup_init_show_roundtrip( "tx_rollup_max_messages_per_inbox": 1010, "tx_rollup_max_finalized_levels": 60_100, "tx_rollup_cost_per_byte_ema_factor": 321, + "tx_rollup_max_ticket_payload_size": 10_240, "sc_rollup_enable": False, "sc_rollup_origination_size": 6_314, "sc_rollup_challenge_window_in_blocks": 20_160, diff --git a/tezt/_regressions/rpc/alpha.client.others.out b/tezt/_regressions/rpc/alpha.client.others.out index 63d54391ce..842ec3b964 100644 --- a/tezt/_regressions/rpc/alpha.client.others.out +++ b/tezt/_regressions/rpc/alpha.client.others.out @@ -37,7 +37,8 @@ tezt/_regressions/rpc/alpha.client.others.out "tx_rollup_max_unfinalized_levels": 2100, "tx_rollup_max_messages_per_inbox": 1010, "tx_rollup_max_finalized_levels": 60100, - "tx_rollup_cost_per_byte_ema_factor": 120, "sc_rollup_enable": false, + "tx_rollup_cost_per_byte_ema_factor": 120, + "tx_rollup_max_ticket_payload_size": 10240, "sc_rollup_enable": false, "sc_rollup_origination_size": 6314, "sc_rollup_challenge_window_in_blocks": 20160 } diff --git a/tezt/_regressions/rpc/alpha.light.others.out b/tezt/_regressions/rpc/alpha.light.others.out index cb3a8b94d2..b844d3f937 100644 --- a/tezt/_regressions/rpc/alpha.light.others.out +++ b/tezt/_regressions/rpc/alpha.light.others.out @@ -37,7 +37,8 @@ tezt/_regressions/rpc/alpha.light.others.out "tx_rollup_max_unfinalized_levels": 2100, "tx_rollup_max_messages_per_inbox": 1010, "tx_rollup_max_finalized_levels": 60100, - "tx_rollup_cost_per_byte_ema_factor": 120, "sc_rollup_enable": false, + "tx_rollup_cost_per_byte_ema_factor": 120, + "tx_rollup_max_ticket_payload_size": 10240, "sc_rollup_enable": false, "sc_rollup_origination_size": 6314, "sc_rollup_challenge_window_in_blocks": 20160 } protocol of light mode unspecified, using the node's protocol: ProtoGenesisGenesisGenesisGenesisGenesisGenesk612im diff --git a/tezt/_regressions/rpc/alpha.proxy.others.out b/tezt/_regressions/rpc/alpha.proxy.others.out index 2b23310c01..248e7b1775 100644 --- a/tezt/_regressions/rpc/alpha.proxy.others.out +++ b/tezt/_regressions/rpc/alpha.proxy.others.out @@ -37,7 +37,8 @@ tezt/_regressions/rpc/alpha.proxy.others.out "tx_rollup_max_unfinalized_levels": 2100, "tx_rollup_max_messages_per_inbox": 1010, "tx_rollup_max_finalized_levels": 60100, - "tx_rollup_cost_per_byte_ema_factor": 120, "sc_rollup_enable": false, + "tx_rollup_cost_per_byte_ema_factor": 120, + "tx_rollup_max_ticket_payload_size": 10240, "sc_rollup_enable": false, "sc_rollup_origination_size": 6314, "sc_rollup_challenge_window_in_blocks": 20160 } protocol of proxy unspecified, using the node's protocol: ProtoGenesisGenesisGenesisGenesisGenesisGenesk612im diff --git a/tezt/_regressions/rpc/alpha.proxy_server.others.out b/tezt/_regressions/rpc/alpha.proxy_server.others.out index a63aeb4cde..1c21198355 100644 --- a/tezt/_regressions/rpc/alpha.proxy_server.others.out +++ b/tezt/_regressions/rpc/alpha.proxy_server.others.out @@ -37,7 +37,8 @@ tezt/_regressions/rpc/alpha.proxy_server.others.out "tx_rollup_max_unfinalized_levels": 2100, "tx_rollup_max_messages_per_inbox": 1010, "tx_rollup_max_finalized_levels": 60100, - "tx_rollup_cost_per_byte_ema_factor": 120, "sc_rollup_enable": false, + "tx_rollup_cost_per_byte_ema_factor": 120, + "tx_rollup_max_ticket_payload_size": 10240, "sc_rollup_enable": false, "sc_rollup_origination_size": 6314, "sc_rollup_challenge_window_in_blocks": 20160 } From fc524e93306e65350f167f13af53458b685cd5a5 Mon Sep 17 00:00:00 2001 From: "iguerNL@Functori" Date: Thu, 17 Mar 2022 16:44:22 +0100 Subject: [PATCH 065/100] Proto/Tx-rollup: bound the number of withdrawals per L2 message --- src/proto_alpha/bin_tx_rollup_node/daemon.ml | 6 +-- src/proto_alpha/bin_tx_rollup_node/state.ml | 15 +++++- src/proto_alpha/bin_tx_rollup_node/state.mli | 1 + src/proto_alpha/lib_client/mockup.ml | 14 ++++- .../lib_parameters/default_parameters.ml | 4 ++ .../lib_protocol/alpha_context.mli | 3 ++ .../lib_protocol/constants_repr.ml | 7 ++- .../lib_protocol/constants_repr.mli | 2 + .../lib_protocol/constants_storage.ml | 4 ++ .../lib_protocol/constants_storage.mli | 2 + src/proto_alpha/lib_protocol/raw_context.ml | 1 + .../test/unit/test_tx_rollup_l2_apply.ml | 51 +++++++++++-------- .../lib_protocol/tx_rollup_l2_apply.ml | 49 ++++++++++++++---- .../lib_protocol/tx_rollup_l2_apply.mli | 17 +++++-- tests_python/tests_alpha/test_mockup.py | 1 + tezt/_regressions/rpc/alpha.client.others.out | 1 + tezt/_regressions/rpc/alpha.light.others.out | 1 + tezt/_regressions/rpc/alpha.proxy.others.out | 1 + .../rpc/alpha.proxy_server.others.out | 1 + 19 files changed, 139 insertions(+), 42 deletions(-) diff --git a/src/proto_alpha/bin_tx_rollup_node/daemon.ml b/src/proto_alpha/bin_tx_rollup_node/daemon.ml index d7241266c1..07df2de32b 100644 --- a/src/proto_alpha/bin_tx_rollup_node/daemon.ml +++ b/src/proto_alpha/bin_tx_rollup_node/daemon.ml @@ -38,12 +38,12 @@ let checkout_context (state : State.t) ctxt_hash = let+ context = Context.checkout state.context_index ctxt_hash in Option.to_result ~none:[Tx_rollup_cannot_checkout_context ctxt_hash] context -let interp_messages ctxt messages cumulated_size = +let interp_messages ctxt parameters messages cumulated_size = let open Lwt_syntax in let+ (ctxt, _ctxt_hash, rev_contents) = List.fold_left_s (fun (ctxt, ctxt_hash, acc) message -> - let+ apply_res = Apply.apply_message ctxt message in + let+ apply_res = Apply.apply_message ctxt parameters message in let (ctxt, ctxt_hash, result) = match apply_res with | Ok (ctxt, result) -> @@ -268,7 +268,7 @@ let process_messages_and_inboxes (state : State.t) | Some context -> return context in let*! (context, inbox) = - interp_messages predecessor_context messages cumulated_size + interp_messages predecessor_context state.parameters messages cumulated_size in match inbox with | None -> diff --git a/src/proto_alpha/bin_tx_rollup_node/state.ml b/src/proto_alpha/bin_tx_rollup_node/state.ml index 10ee326690..5fbbb0bc31 100644 --- a/src/proto_alpha/bin_tx_rollup_node/state.ml +++ b/src/proto_alpha/bin_tx_rollup_node/state.ml @@ -37,6 +37,7 @@ type t = { context_index : Context.index; rollup : Tx_rollup.t; rollup_origination : rollup_origination; + parameters : Protocol.Tx_rollup_l2_apply.parameters; } (* Stands for the manager operation pass, in which the rollup transactions are @@ -198,10 +199,22 @@ let init_context ~data_dir = let*! index = Context.init (Node_data.context_dir data_dir) in return index +let init_parameters cctxt = + let open Lwt_result_syntax in + let* {parametric; _} = + Protocol.Constants_services.all cctxt (cctxt#chain, cctxt#block) + in + return + { + Protocol.Tx_rollup_l2_apply.tx_rollup_max_withdrawals_per_batch = + parametric.tx_rollup_max_withdrawals_per_batch; + } + let init ~data_dir ~context ?rollup_genesis rollup = let open Lwt_result_syntax in let store_orig = init_store ~data_dir ~context ?rollup_genesis rollup in let context_index = init_context ~data_dir in let* (store, rollup_origination) = store_orig in let* context_index = context_index in - return {store; context_index; rollup; rollup_origination} + let* parameters = init_parameters context in + return {store; context_index; rollup; rollup_origination; parameters} diff --git a/src/proto_alpha/bin_tx_rollup_node/state.mli b/src/proto_alpha/bin_tx_rollup_node/state.mli index ece18c9290..bcab229514 100644 --- a/src/proto_alpha/bin_tx_rollup_node/state.mli +++ b/src/proto_alpha/bin_tx_rollup_node/state.mli @@ -38,6 +38,7 @@ type t = private { context_index : Context.index; rollup : Tx_rollup.t; rollup_origination : rollup_origination; + parameters : Protocol.Tx_rollup_l2_apply.parameters; } (** [init ~data_dir ~context ~rollup_genesis rollup] creates a new state for the diff --git a/src/proto_alpha/lib_client/mockup.ml b/src/proto_alpha/lib_client/mockup.ml index 703507fa26..1954e48e55 100644 --- a/src/proto_alpha/lib_client/mockup.ml +++ b/src/proto_alpha/lib_client/mockup.ml @@ -76,6 +76,7 @@ module Protocol_constants_overrides = struct tx_rollup_origination_size : int option; tx_rollup_hard_size_limit_per_inbox : int option; tx_rollup_hard_size_limit_per_message : int option; + tx_rollup_max_withdrawals_per_batch : int option; tx_rollup_commitment_bond : Tez.t option; tx_rollup_finality_period : int option; tx_rollup_max_unfinalized_levels : int option; @@ -140,6 +141,7 @@ module Protocol_constants_overrides = struct c.tx_rollup_origination_size, c.tx_rollup_hard_size_limit_per_inbox, c.tx_rollup_hard_size_limit_per_message, + c.tx_rollup_max_withdrawals_per_batch, c.tx_rollup_commitment_bond, c.tx_rollup_finality_period, c.tx_rollup_max_unfinalized_levels, @@ -193,6 +195,7 @@ module Protocol_constants_overrides = struct tx_rollup_origination_size, tx_rollup_hard_size_limit_per_inbox, tx_rollup_hard_size_limit_per_message, + tx_rollup_max_withdrawals_per_batch, tx_rollup_commitment_bond, tx_rollup_finality_period, tx_rollup_max_unfinalized_levels, @@ -244,6 +247,7 @@ module Protocol_constants_overrides = struct tx_rollup_origination_size; tx_rollup_hard_size_limit_per_inbox; tx_rollup_hard_size_limit_per_message; + tx_rollup_max_withdrawals_per_batch; tx_rollup_commitment_bond; tx_rollup_finality_period; tx_rollup_max_unfinalized_levels; @@ -313,13 +317,14 @@ module Protocol_constants_overrides = struct (opt "cache_sampler_state_cycles" int8)) (merge_objs (merge_objs - (obj9 + (obj10 (opt "tx_rollup_enable" Data_encoding.bool) (opt "tx_rollup_origination_size" int31) (opt "tx_rollup_hard_size_limit_per_inbox" int31) (opt "tx_rollup_hard_size_limit_per_message" int31) + (opt "tx_rollup_max_withdrawals_per_batch" int31) (opt "tx_rollup_commitment_bond" Tez.encoding) (opt "tx_rollup_finality_period" int31) (opt "tx_rollup_max_unfinalized_levels" int31) @@ -401,6 +406,8 @@ module Protocol_constants_overrides = struct Some parametric.tx_rollup_hard_size_limit_per_inbox; tx_rollup_hard_size_limit_per_message = Some parametric.tx_rollup_hard_size_limit_per_message; + tx_rollup_max_withdrawals_per_batch = + Some parametric.tx_rollup_max_withdrawals_per_batch; tx_rollup_commitment_bond = Some parametric.tx_rollup_commitment_bond; tx_rollup_finality_period = Some parametric.tx_rollup_finality_period; tx_rollup_max_unfinalized_levels = @@ -467,6 +474,7 @@ module Protocol_constants_overrides = struct tx_rollup_origination_size = None; tx_rollup_hard_size_limit_per_inbox = None; tx_rollup_hard_size_limit_per_message = None; + tx_rollup_max_withdrawals_per_batch = None; tx_rollup_commitment_bond = None; tx_rollup_finality_period = None; tx_rollup_max_unfinalized_levels = None; @@ -896,6 +904,10 @@ module Protocol_constants_overrides = struct Option.value ~default:c.tx_rollup_hard_size_limit_per_message o.tx_rollup_hard_size_limit_per_message; + tx_rollup_max_withdrawals_per_batch = + Option.value + ~default:c.tx_rollup_max_withdrawals_per_batch + o.tx_rollup_max_withdrawals_per_batch; tx_rollup_commitment_bond = Option.value ~default:c.tx_rollup_commitment_bond diff --git a/src/proto_alpha/lib_parameters/default_parameters.ml b/src/proto_alpha/lib_parameters/default_parameters.ml index 3743a583c9..875646612a 100644 --- a/src/proto_alpha/lib_parameters/default_parameters.ml +++ b/src/proto_alpha/lib_parameters/default_parameters.ml @@ -108,6 +108,10 @@ let constants_mainnet = (* Transaction rollup’s size limits are expressed in number of bytes *) tx_rollup_hard_size_limit_per_inbox = 100_000; tx_rollup_hard_size_limit_per_message = 5_000; + (* We limit the number of withdraws per message to avoid costly + allocations/iterations in the accounting mechanism used for each + withdraw claiming in L1 and cleaned when removing a commitment. *) + tx_rollup_max_withdrawals_per_batch = 255; tx_rollup_commitment_bond = Tez.of_mutez_exn 10_000_000_000L; tx_rollup_finality_period = 2_000; tx_rollup_max_unfinalized_levels = 2_100; diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index de8ca91097..cf947263bc 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -795,6 +795,7 @@ module Constants : sig tx_rollup_origination_size : int; tx_rollup_hard_size_limit_per_inbox : int; tx_rollup_hard_size_limit_per_message : int; + tx_rollup_max_withdrawals_per_batch : int; tx_rollup_commitment_bond : Tez.t; tx_rollup_finality_period : int; tx_rollup_withdraw_period : int; @@ -895,6 +896,8 @@ module Constants : sig val tx_rollup_hard_size_limit_per_message : context -> int + val tx_rollup_max_withdrawals_per_batch : context -> int + val tx_rollup_commitment_bond : context -> Tez.t val tx_rollup_finality_period : context -> int diff --git a/src/proto_alpha/lib_protocol/constants_repr.ml b/src/proto_alpha/lib_protocol/constants_repr.ml index 51d7cd88fb..c00b6e21c2 100644 --- a/src/proto_alpha/lib_protocol/constants_repr.ml +++ b/src/proto_alpha/lib_protocol/constants_repr.ml @@ -163,6 +163,7 @@ type parametric = { tx_rollup_origination_size : int; tx_rollup_hard_size_limit_per_inbox : int; tx_rollup_hard_size_limit_per_message : int; + tx_rollup_max_withdrawals_per_batch : int; tx_rollup_commitment_bond : Tez_repr.t; tx_rollup_finality_period : int; tx_rollup_withdraw_period : int; @@ -220,6 +221,7 @@ let parametric_encoding = c.tx_rollup_origination_size, c.tx_rollup_hard_size_limit_per_inbox, c.tx_rollup_hard_size_limit_per_message, + c.tx_rollup_max_withdrawals_per_batch, c.tx_rollup_commitment_bond, c.tx_rollup_finality_period, c.tx_rollup_withdraw_period, @@ -271,6 +273,7 @@ let parametric_encoding = tx_rollup_origination_size, tx_rollup_hard_size_limit_per_inbox, tx_rollup_hard_size_limit_per_message, + tx_rollup_max_withdrawals_per_batch, tx_rollup_commitment_bond, tx_rollup_finality_period, tx_rollup_withdraw_period, @@ -323,6 +326,7 @@ let parametric_encoding = tx_rollup_origination_size; tx_rollup_hard_size_limit_per_inbox; tx_rollup_hard_size_limit_per_message; + tx_rollup_max_withdrawals_per_batch; tx_rollup_commitment_bond; tx_rollup_finality_period; tx_rollup_withdraw_period; @@ -389,11 +393,12 @@ let parametric_encoding = (req "cache_sampler_state_cycles" int8)) (merge_objs (merge_objs - (obj9 + (obj10 (req "tx_rollup_enable" bool) (req "tx_rollup_origination_size" int31) (req "tx_rollup_hard_size_limit_per_inbox" int31) (req "tx_rollup_hard_size_limit_per_message" int31) + (req "tx_rollup_max_withdrawals_per_batch" int31) (req "tx_rollup_commitment_bond" Tez_repr.encoding) (req "tx_rollup_finality_period" int31) (req "tx_rollup_withdraw_period" int31) diff --git a/src/proto_alpha/lib_protocol/constants_repr.mli b/src/proto_alpha/lib_protocol/constants_repr.mli index eb60dc7b2e..88341a1139 100644 --- a/src/proto_alpha/lib_protocol/constants_repr.mli +++ b/src/proto_alpha/lib_protocol/constants_repr.mli @@ -128,6 +128,8 @@ type parametric = { tx_rollup_hard_size_limit_per_inbox : int; (* the maximum amount of bytes one batch can allocate in an inbox *) tx_rollup_hard_size_limit_per_message : int; + (* the maximum number of allowed "L2-to-L1" withdraws per batch *) + tx_rollup_max_withdrawals_per_batch : int; (* the amount of tez to bond a tx rollup commitment *) tx_rollup_commitment_bond : Tez_repr.t; (* the number of blocks before a tx rollup block is final *) diff --git a/src/proto_alpha/lib_protocol/constants_storage.ml b/src/proto_alpha/lib_protocol/constants_storage.ml index 361611fd2b..b431575429 100644 --- a/src/proto_alpha/lib_protocol/constants_storage.ml +++ b/src/proto_alpha/lib_protocol/constants_storage.ml @@ -162,6 +162,10 @@ let tx_rollup_hard_size_limit_per_message c = let constants = Raw_context.constants c in constants.tx_rollup_hard_size_limit_per_message +let tx_rollup_max_withdrawals_per_batch c = + let constants = Raw_context.constants c in + constants.tx_rollup_max_withdrawals_per_batch + let tx_rollup_commitment_bond c = let constants = Raw_context.constants c in constants.tx_rollup_commitment_bond diff --git a/src/proto_alpha/lib_protocol/constants_storage.mli b/src/proto_alpha/lib_protocol/constants_storage.mli index ad3fbb1f10..0ac4f5b3e2 100644 --- a/src/proto_alpha/lib_protocol/constants_storage.mli +++ b/src/proto_alpha/lib_protocol/constants_storage.mli @@ -92,6 +92,8 @@ val tx_rollup_hard_size_limit_per_inbox : Raw_context.t -> int val tx_rollup_hard_size_limit_per_message : Raw_context.t -> int +val tx_rollup_max_withdrawals_per_batch : Raw_context.t -> int + val tx_rollup_commitment_bond : Raw_context.t -> Tez_repr.t val tx_rollup_finality_period : Raw_context.t -> int diff --git a/src/proto_alpha/lib_protocol/raw_context.ml b/src/proto_alpha/lib_protocol/raw_context.ml index ed71e6e70b..8ff9fe29f3 100644 --- a/src/proto_alpha/lib_protocol/raw_context.ml +++ b/src/proto_alpha/lib_protocol/raw_context.ml @@ -904,6 +904,7 @@ let prepare_first_block ~level ~timestamp ctxt = tx_rollup_origination_size = 60_000; tx_rollup_hard_size_limit_per_inbox = 100_000; tx_rollup_hard_size_limit_per_message = 5_000; + tx_rollup_max_withdrawals_per_batch = 255; tx_rollup_commitment_bond = Tez_repr.of_mutez_exn 10_000_000_000L; tx_rollup_finality_period = 2_000; tx_rollup_withdraw_period; diff --git a/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml b/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml index 537e71ebb9..070143c9c9 100644 --- a/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml +++ b/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml @@ -419,6 +419,14 @@ let test_returned_deposit () = | (Deposit_success _result, _) -> fail_msg "Did not expect overflowing deposit to be succesful" +let apply_l2_parameters : Protocol.Tx_rollup_l2_apply.parameters = + {maximum_withdraws_per_message = 5} + +let apply_l2_batch ctxt batch = + Batch_V1.apply_batch ctxt apply_l2_parameters batch + +let apply_l2_message ctxt msg = apply_message ctxt apply_l2_parameters msg + (** Test that all values used in a transaction creates indexes and they are packed in the final indexes. *) let test_indexes_creation () = @@ -493,7 +501,7 @@ let test_indexes_creation () = in let* (_ctxt, Batch_result {indexes; _}, _withdrawals) = - Batch_V1.apply_batch ctxt batch + apply_l2_batch ctxt batch in let* () = @@ -550,7 +558,7 @@ let test_indexes_creation_bad () = in let* (ctxt, Batch_result {results; indexes}, _withdrawals) = - Batch_V1.apply_batch ctxt batch + apply_l2_batch ctxt batch in (* Only the indexes from the second transaction should exist, the first @@ -598,7 +606,7 @@ let test_simple_l2_transaction () = let batch = create_batch_v1 [transaction] [[sk1; sk2]] in let* (ctxt, Batch_result {results; _}, _withdrawals) = - Batch_V1.apply_batch ctxt batch + apply_l2_batch ctxt batch in let status = nth_exn results 0 |> snd in @@ -668,7 +676,7 @@ let test_l2_transaction_l2_addr_signer_good () = let signature = sign_transaction [sk1] transfer in let batch = batch signature [transfer] in let* (_ctxt, Batch_result {results; indexes = _}, _withdrawals) = - Batch_V1.apply_batch ctxt batch + apply_l2_batch ctxt batch in let status = nth_exn results 0 in match status with @@ -691,7 +699,7 @@ let test_l2_transaction_l2_addr_signer_bad () = let* () = expect_error ~msg_if_valid:"The check should fail with an unknown address" - (Batch_V1.apply_batch ctxt batch) + (apply_l2_batch ctxt batch) (Tx_rollup_l2_apply.Unknown_address addr1) in (* Now we add the index but the metadata is still missing *) @@ -699,7 +707,7 @@ let test_l2_transaction_l2_addr_signer_bad () = let* () = expect_error ~msg_if_valid:"The check should fail with unknown metadata" - (Batch_V1.apply_batch ctxt batch) + (apply_l2_batch ctxt batch) (Tx_rollup_l2_apply.Unallocated_metadata 0l) in (* Finally we add the metadata and the test pass *) @@ -709,7 +717,7 @@ let test_l2_transaction_l2_addr_signer_bad () = Ticket_ledger.credit ctxt tidx idx1 (Tx_rollup_l2_qty.of_int64_exn 100L) in let* (_ctxt, Batch_result {results; indexes = _}, _withdrawals) = - Batch_V1.apply_batch ctxt batch + apply_l2_batch ctxt batch in let status = nth_exn results 0 in match status with @@ -738,7 +746,7 @@ let test_simple_l1_transaction () = let batch = create_batch_v1 [transaction] [[sk1]] in let* (ctxt, Batch_result {results; _}, withdrawals) = - Batch_V1.apply_batch ctxt batch + apply_l2_batch ctxt batch in let status = nth_exn results 0 |> snd in @@ -789,7 +797,7 @@ let test_l1_transaction_inexistant_ticket () = let batch = create_batch_v1 [transaction] [[sk1]] in let* (_ctxt, Batch_result {results; _}, withdrawals) = - Batch_V1.apply_batch ctxt batch + apply_l2_batch ctxt batch in (* Expect no withdrawals *) @@ -829,7 +837,7 @@ let test_l1_transaction_inexistant_signer () = let batch = create_batch_v1 [transaction] [[sk_unknown]] in let* (_ctxt, Batch_result {results; _}, withdrawals) = - Batch_V1.apply_batch ctxt batch + apply_l2_batch ctxt batch in (* Expect no withdrawals *) @@ -871,7 +879,7 @@ let test_l1_transaction_overdraft () = let batch = create_batch_v1 [transaction] [[sk1]] in let* (ctxt, Batch_result {results; _}, withdrawals) = - Batch_V1.apply_batch ctxt batch + apply_l2_batch ctxt batch in (* Expect no withdrawals *) @@ -953,7 +961,7 @@ let test_l1_transaction_zero () = let batch = create_batch_v1 [transaction] [[sk1]] in let* (ctxt, Batch_result {results; _}, withdrawals) = - Batch_V1.apply_batch ctxt batch + apply_l2_batch ctxt batch in (* Expect one zero-withdrawal *) @@ -1037,7 +1045,7 @@ let test_l1_transaction_partial () = let batch = create_batch_v1 [transaction] [[sk1]] in let* (ctxt, Batch_result {results; _}, withdrawals) = - Batch_V1.apply_batch ctxt batch + apply_l2_batch ctxt batch in (* Expect one partial withdrawal *) @@ -1171,7 +1179,7 @@ let test_transaction_with_unknown_indexable () = let batch = batch signatures [transaction] in let* (ctxt, Batch_result {results; _}, withdrawals) = - Batch_V1.apply_batch ctxt batch + apply_l2_batch ctxt batch in let status = nth_exn results 0 |> snd in @@ -1252,7 +1260,7 @@ let test_invalid_transaction () = let batch = create_batch_v1 [transaction] [[sk1; sk2]] in let* (ctxt, Batch_result {results; _}, _withdrawals) = - Batch_V1.apply_batch ctxt batch + apply_l2_batch ctxt batch in let status = nth_exn results 0 |> snd in @@ -1301,7 +1309,7 @@ let test_invalid_counter () = let batch = create_batch_v1 [transaction] [[sk1]] in let* (_ctxt, Batch_result {results; _}, _withdrawals) = - Batch_V1.apply_batch ctxt batch + apply_l2_batch ctxt batch in let status = nth_exn results 0 |> snd in @@ -1341,7 +1349,7 @@ let test_update_counter () = in let* (ctxt, Batch_result {results; _}, withdrawals) = - Batch_V1.apply_batch ctxt batch + apply_l2_batch ctxt batch in let status = nth_exn results 0 |> snd in @@ -1439,7 +1447,7 @@ let test_apply_message_batch () = (V1 batch)) in - let* (_ctxt, result) = apply_message ctxt msg in + let* (_ctxt, result) = apply_l2_message ctxt msg in match result with | (Message_result.Batch_V1_result _, []) -> @@ -1512,7 +1520,7 @@ let test_apply_message_batch_withdrawals () = (V1 batch)) in - let* (ctxt, result) = apply_message ctxt msg in + let* (ctxt, result) = apply_l2_message ctxt msg in match result with | ( Message_result.Batch_V1_result @@ -1625,7 +1633,7 @@ let test_apply_message_deposit () = (Tx_rollup_l2_qty.of_int64_exn amount) in - let* (_ctxt, result) = apply_message ctxt msg in + let* (_ctxt, result) = apply_l2_message ctxt msg in match result with | (Message_result.Deposit_result _, []) -> @@ -1637,7 +1645,6 @@ let test_apply_message_deposit () = let test_transfer_to_self () = let open Context_l2.Syntax in let* (ctxt, _, accounts) = with_initial_setup [ticket1] [[(ticket1, 10L)]] in - let (sk1, pk1, addr1, _idx1, _) = nth_exn accounts 0 in let transaction = [transfer ~signer:(signer_pk pk1) ~dest:addr1 ~ticket:ticket1 1L] @@ -1645,7 +1652,7 @@ let test_transfer_to_self () = let batch = create_batch_v1 [transaction] [[sk1]] in let* (_ctxt, Batch_result {results; _}, _withdrawals) = - Batch_V1.apply_batch ctxt batch + apply_l2_batch ctxt batch in let status = nth_exn results 0 in diff --git a/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.ml b/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.ml index 3a89a64b3b..802df653f7 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.ml @@ -45,6 +45,7 @@ type error += | Unknown_address of Tx_rollup_l2_address.t | Invalid_self_transfer | Invalid_zero_transfer + | Maximum_withdraws_per_message_exceeded of {current : int; maximum : int} let () = let open Data_encoding in @@ -162,7 +163,21 @@ let () = ~description:"A transfer's amount must be greater than zero." empty (function Invalid_zero_transfer -> Some () | _ -> None) - (function () -> Invalid_zero_transfer) + (function () -> Invalid_zero_transfer) ; + (* Maximum_withdraws_per_message_exceeded *) + register_error_kind + `Permanent + ~id:"tx_rollup_maximum_withdraws_per_message_exceeded" + ~title:"Maximum tx-rollup withdraws per message exceeded" + ~description: + "The maximum number of withdraws allowed per tx-rollup message exceeded" + (obj2 (req "current" int31) (req "limit" int31)) + (function + | Maximum_withdraws_per_message_exceeded {current; maximum} -> + Some (current, maximum) + | _ -> None) + (fun (current, maximum) -> + Maximum_withdraws_per_message_exceeded {current; maximum}) module Address_indexes = Map.Make (Tx_rollup_l2_address) module Ticket_indexes = Map.Make (Ticket_hash) @@ -323,6 +338,11 @@ module Message_result = struct tup2 message_result_encoding (list Tx_rollup_withdraw.encoding)) end +type parameters = { + (* Maximum number of allowed L2-to-L1 withdraws per batch *) + tx_rollup_max_withdrawals_per_batch : int; +} + module Make (Context : CONTEXT) = struct open Context open Syntax @@ -746,10 +766,11 @@ module Make (Context : CONTEXT) = struct let apply_batch : ctxt -> + parameters -> (Indexable.unknown, Indexable.unknown) t -> (ctxt * Message_result.Batch_V1.t * Tx_rollup_withdraw.withdrawal list) m = - fun ctxt batch -> + fun ctxt parameters batch -> let* (ctxt, indexes, batch) = check_signature ctxt batch in let {contents; _} = batch in let* (ctxt, indexes, rev_results, withdrawals) = @@ -767,11 +788,17 @@ module Make (Context : CONTEXT) = struct (ctxt, indexes, [], []) contents in - let results = List.rev rev_results in - return - ( ctxt, - Message_result.Batch_V1.Batch_result {results; indexes}, - withdrawals ) + let limit = parameters.tx_rollup_max_withdrawals_per_batch in + if Compare.List_length_with.(withdrawals > limit) then + fail + (Maximum_withdraws_per_message_exceeded + {current = List.length withdrawals; maximum = limit}) + else + let results = List.rev rev_results in + return + ( ctxt, + Message_result.Batch_V1.Batch_result {results; indexes}, + withdrawals ) end let apply_deposit : @@ -804,9 +831,9 @@ module Make (Context : CONTEXT) = struct in return (initial_ctxt, Deposit_failure reason, Some withdrawal)) - let apply_message : ctxt -> Tx_rollup_message.t -> (ctxt * Message_result.t) m - = - fun ctxt msg -> + let apply_message : + ctxt -> parameters -> Tx_rollup_message.t -> (ctxt * Message_result.t) m = + fun ctxt parameters msg -> let open Tx_rollup_message in match msg with | Deposit deposit -> @@ -819,7 +846,7 @@ module Make (Context : CONTEXT) = struct match batch with | Some (V1 batch) -> let* (ctxt, result, withdrawals) = - Batch_V1.apply_batch ctxt batch + Batch_V1.apply_batch ctxt parameters batch in return (ctxt, (Batch_V1_result result, withdrawals)) | None -> fail Invalid_batch_encoding) diff --git a/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.mli b/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.mli index 1f922a43e6..f8f6bdb7eb 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.mli +++ b/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.mli @@ -64,6 +64,7 @@ type error += | Unknown_address of Tx_rollup_l2_address.t | Invalid_self_transfer | Invalid_zero_transfer + | Maximum_withdraws_per_message_exceeded of {current : int; maximum : int} module Address_indexes : Map.S with type key = Tx_rollup_l2_address.t @@ -122,6 +123,12 @@ module Message_result : sig val encoding : t Data_encoding.t end +(** The record of parameters used during the application of messages. *) +type parameters = { + (* Maximum number of allowed L2-to-L1 withdraws per batch *) + tx_rollup_max_withdrawals_per_batch : int; +} + module Make (Context : CONTEXT) : sig open Context @@ -133,7 +140,8 @@ module Make (Context : CONTEXT) : sig module Batch_V1 : sig open Tx_rollup_l2_batch.V1 - (** [apply_batch ctxt batch] interprets the batch {Tx_rollup_l2_batch.V1.t}. + (** [apply_batch ctxt parameters batch] interprets the batch + {Tx_rollup_l2_batch.V1.t}. By construction, a failing transaction will not affect the [ctxt] and other transactions will still be interpreted. @@ -151,6 +159,7 @@ module Make (Context : CONTEXT) : sig *) val apply_batch : ctxt -> + parameters -> (Indexable.unknown, Indexable.unknown) t -> (ctxt * Message_result.Batch_V1.t * Tx_rollup_withdraw.withdrawal list) m @@ -204,7 +213,8 @@ module Make (Context : CONTEXT) : sig * Tx_rollup_withdraw.withdrawal option) m - (** [apply_message ctxt message] interpets the [message] in the [ctxt]. + (** [apply_message ctxt parameters message] interprets the [message] in the + [ctxt]. That is, @@ -221,7 +231,8 @@ module Make (Context : CONTEXT) : sig The list of withdrawals in the message result followed the ordering of the contents in the message. *) - val apply_message : ctxt -> Tx_rollup_message.t -> (ctxt * Message_result.t) m + val apply_message : + ctxt -> parameters -> Tx_rollup_message.t -> (ctxt * Message_result.t) m end module Internal_for_tests : sig diff --git a/tests_python/tests_alpha/test_mockup.py b/tests_python/tests_alpha/test_mockup.py index 07e742a2c0..8797d05530 100644 --- a/tests_python/tests_alpha/test_mockup.py +++ b/tests_python/tests_alpha/test_mockup.py @@ -664,6 +664,7 @@ def _test_create_mockup_init_show_roundtrip( "tx_rollup_withdraw_period": 123456, "tx_rollup_max_unfinalized_levels": 2100, "tx_rollup_max_messages_per_inbox": 1010, + 'tx_rollup_max_withdrawals_per_batch': 255, "tx_rollup_max_finalized_levels": 60_100, "tx_rollup_cost_per_byte_ema_factor": 321, "tx_rollup_max_ticket_payload_size": 10_240, diff --git a/tezt/_regressions/rpc/alpha.client.others.out b/tezt/_regressions/rpc/alpha.client.others.out index 842ec3b964..79289afef7 100644 --- a/tezt/_regressions/rpc/alpha.client.others.out +++ b/tezt/_regressions/rpc/alpha.client.others.out @@ -32,6 +32,7 @@ tezt/_regressions/rpc/alpha.client.others.out "tx_rollup_enable": false, "tx_rollup_origination_size": 60000, "tx_rollup_hard_size_limit_per_inbox": 100000, "tx_rollup_hard_size_limit_per_message": 5000, + "tx_rollup_max_withdrawals_per_batch": 255, "tx_rollup_commitment_bond": "10000000000", "tx_rollup_finality_period": 2000, "tx_rollup_withdraw_period": 60000, "tx_rollup_max_unfinalized_levels": 2100, diff --git a/tezt/_regressions/rpc/alpha.light.others.out b/tezt/_regressions/rpc/alpha.light.others.out index b844d3f937..58f933c90d 100644 --- a/tezt/_regressions/rpc/alpha.light.others.out +++ b/tezt/_regressions/rpc/alpha.light.others.out @@ -32,6 +32,7 @@ tezt/_regressions/rpc/alpha.light.others.out "tx_rollup_enable": false, "tx_rollup_origination_size": 60000, "tx_rollup_hard_size_limit_per_inbox": 100000, "tx_rollup_hard_size_limit_per_message": 5000, + "tx_rollup_max_withdrawals_per_batch": 255, "tx_rollup_commitment_bond": "10000000000", "tx_rollup_finality_period": 2000, "tx_rollup_withdraw_period": 60000, "tx_rollup_max_unfinalized_levels": 2100, diff --git a/tezt/_regressions/rpc/alpha.proxy.others.out b/tezt/_regressions/rpc/alpha.proxy.others.out index 248e7b1775..d581518fc2 100644 --- a/tezt/_regressions/rpc/alpha.proxy.others.out +++ b/tezt/_regressions/rpc/alpha.proxy.others.out @@ -32,6 +32,7 @@ tezt/_regressions/rpc/alpha.proxy.others.out "tx_rollup_enable": false, "tx_rollup_origination_size": 60000, "tx_rollup_hard_size_limit_per_inbox": 100000, "tx_rollup_hard_size_limit_per_message": 5000, + "tx_rollup_max_withdrawals_per_batch": 255, "tx_rollup_commitment_bond": "10000000000", "tx_rollup_finality_period": 2000, "tx_rollup_withdraw_period": 60000, "tx_rollup_max_unfinalized_levels": 2100, diff --git a/tezt/_regressions/rpc/alpha.proxy_server.others.out b/tezt/_regressions/rpc/alpha.proxy_server.others.out index 1c21198355..3434898536 100644 --- a/tezt/_regressions/rpc/alpha.proxy_server.others.out +++ b/tezt/_regressions/rpc/alpha.proxy_server.others.out @@ -32,6 +32,7 @@ tezt/_regressions/rpc/alpha.proxy_server.others.out "tx_rollup_enable": false, "tx_rollup_origination_size": 60000, "tx_rollup_hard_size_limit_per_inbox": 100000, "tx_rollup_hard_size_limit_per_message": 5000, + "tx_rollup_max_withdrawals_per_batch": 255, "tx_rollup_commitment_bond": "10000000000", "tx_rollup_finality_period": 2000, "tx_rollup_withdraw_period": 60000, "tx_rollup_max_unfinalized_levels": 2100, From c9dcc5550ef496f8ceb5537b7f44fee494a2422e Mon Sep 17 00:00:00 2001 From: "iguerNL@Functori" Date: Fri, 18 Mar 2022 11:28:39 +0100 Subject: [PATCH 066/100] Tests/Tx_rollup: add units tests for maximum withdrawals per batch --- .../test/unit/test_tx_rollup_l2_apply.ml | 73 ++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml b/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml index 070143c9c9..afa0144e7f 100644 --- a/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml +++ b/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml @@ -420,7 +420,7 @@ let test_returned_deposit () = fail_msg "Did not expect overflowing deposit to be succesful" let apply_l2_parameters : Protocol.Tx_rollup_l2_apply.parameters = - {maximum_withdraws_per_message = 5} + {tx_rollup_max_withdrawals_per_batch = 5} let apply_l2_batch ctxt batch = Batch_V1.apply_batch ctxt apply_l2_parameters batch @@ -779,6 +779,71 @@ let test_simple_l1_transaction () = | (Transaction_success, _) -> fail_msg "Expected exactly one withdrawal" | (Transaction_failure _, _) -> fail_msg "The transaction should be a success" +let rec repeat n f acc = if n <= 0 then acc else repeat (n - 1) f (f n acc) + +(** This function crafts a batch containing [nb_withdraws]. Then, it applies it + on an L2 context, and checks the status, depending on the value of + [should_succeed] *) +let helper_test_withdrawal_limits_per_batch nb_withdraws ~should_succeed = + let open Context_l2.Syntax in + (* create sufficiently many accounts *) + let accounts = repeat nb_withdraws (fun _i l -> [(ticket1, 2L)] :: l) [] in + let* (ctxt, _tidxs, accounts) = + with_initial_setup [ticket1] ([] :: accounts) + in + (* destination of withdrawals *) + let (_skD, _pkD, _addrD, _idxD, pkhD) = nth_exn accounts 0 in + (* transfer 1 ticket from [nb_withdraws] accounts to the dest *) + let (transactions, sks) = + repeat + nb_withdraws + (fun i (transactions, sks) -> + let (sk, pk, _addr, _idx, _pkh) = nth_exn accounts i in + let withdraw = + withdraw ~signer:(signer_pk pk) ~dest:pkhD ~ticket:ticket1 1L + in + (withdraw :: transactions, sk :: sks)) + ([], []) + in + let batch = create_batch_v1 [transactions] [sks] in + (* apply the batch, and handle the success and error cases *) + Irmin_storage.Syntax.catch + (apply_l2_batch ctxt batch) + (fun _success -> + if should_succeed then return_unit + else fail_msg "The transaction should fail") + (fun error -> + let expected_error = "Maximum tx-rollup withdraws per message exceeded" in + let ({title = error_title; _} as _error_info) = + Error_monad.find_info_of_error (Environment.wrap_tzerror error) + in + if should_succeed then + fail_msg + ("The transaction should be a success, but failed: " ^ error_title) + else if error_title <> expected_error then + fail_msg + @@ Format.sprintf + "Expected error %s but got %s" + expected_error + error_title + else return_unit) + +(* Three tests that use the helper above *) +let nb_withdrawals_per_batch_below_limit () = + helper_test_withdrawal_limits_per_batch + (apply_l2_parameters.tx_rollup_max_withdrawals_per_batch - 1) + ~should_succeed:true + +let nb_withdrawals_per_batch_equals_limit () = + helper_test_withdrawal_limits_per_batch + apply_l2_parameters.tx_rollup_max_withdrawals_per_batch + ~should_succeed:true + +let nb_withdrawals_per_batch_above_limit () = + helper_test_withdrawal_limits_per_batch + (apply_l2_parameters.tx_rollup_max_withdrawals_per_batch + 1) + ~should_succeed:false + (** Test that [Missing_ticket] is raised if a transfer is attempted to a ticket absent from the rollup. *) let test_l1_transaction_inexistant_ticket () = @@ -1696,4 +1761,10 @@ let tests = test_apply_message_batch_withdrawals ); ("apply deposit from message", test_apply_message_deposit); ("test transfer to self fail", test_transfer_to_self); + ( "nb withdrawals per batch below limit", + nb_withdrawals_per_batch_below_limit ); + ( "nb withdrawals per batch equals limit", + nb_withdrawals_per_batch_equals_limit ); + ( "nb withdrawals per batch above limit", + nb_withdrawals_per_batch_above_limit ); ] From 7669a688cd9fc749c30eb51fc2fa3fbe70667bd1 Mon Sep 17 00:00:00 2001 From: Sventimir Date: Thu, 10 Mar 2022 15:10:07 +0100 Subject: [PATCH 067/100] Proto Alpha: refactor patched contracts tests for re-usability. - Decouples the tests from the concrete patches being tested. - Allows them to exist and compile when they're not needed. - Makes re-using them in the future as simple as single functor application. --- src/proto_alpha/lib_protocol/init_storage.ml | 100 +------ .../legacy_script_patches_for_J.ml | 78 ++++- .../michelson/test_patched_contracts.ml | 275 ++++++++++-------- 3 files changed, 235 insertions(+), 218 deletions(-) diff --git a/src/proto_alpha/lib_protocol/init_storage.ml b/src/proto_alpha/lib_protocol/init_storage.ml index 51ce990378..c6248d8813 100644 --- a/src/proto_alpha/lib_protocol/init_storage.ml +++ b/src/proto_alpha/lib_protocol/init_storage.ml @@ -26,99 +26,7 @@ (*****************************************************************************) module Patch_legacy_contracts_for_J = struct - open Legacy_script_patches_for_J - - let contract_patches = - [ - ( "KT1MzfYSbq18fYr4f44aQRoZBQN72BAtiz5j", - exprtgpMFzTtyg1STJqANLQsjsMXmkf8UuJTuczQh8GPtqfw18x6Lc ); - ( "KT1Kfbk3B6NYPCPohPBDU3Hxf5Xeyy9PdkNp", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT1JW6PwhfaEJu6U3ENsxUeja48AdtqSoekd", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT1VsSxSXUkgw6zkBGgUuDXXuJs9ToPqkrCg", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT1TcAHw5gpejyemwRtdNyFKGBLc4qwA5gtw", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT1FN5fcNNcgieGjzxbVEPWUpJGwZEpzNGA8", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT1Um7ieBEytZtumecLqGeL56iY6BuWoBgio", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT1QuofAgnsWffHzLA7D78rxytJruGHDe7XG", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT1CSKPf2jeLpMmrgKquN2bCjBTkAcAdRVDy", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT1D5NmtDtgCwPxYNb2ZK2But6dhNLs1T1bV", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT1VvXEpeBpreAVpfp4V8ZujqWu2gVykwXBJ", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT1TzamC1SCj68ia2E4q2GWZeT24yRHvUZay", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT1LZFMGrdnPjRLsCZ1aEDUAF5myA5Eo4rQe", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT1PDAELuX7CypUHinUgFgGFskKs7ytwh5Vw", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT19xDbLsvQKnp9xqfDNPWJbKJJmV93dHDUa", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT1Cz7TyVFvHxXpxLS57RFePrhTGisUpPhvD", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT1LQ99RfGcmFe98PiBcGXuyjBkWzAcoXXhW", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT1Gow8VzXZx3Akn5kvjACqnjnyYBxQpzSKr", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT1DnfT4hfikoMY3uiPE9mQV4y3Xweramb2k", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT1FuFDZGdw86p6krdBUKoZfEMkcUmezqX5o", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT1SLWhfqPtQq7f4zLomh8BNgDeprF9B6d2M", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT1THsDNgHtN56ew9VVCAUWnqPC81pqAxCEp", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT1CM1g1o9RKDdtDKgcBWE59X2KgTc2TcYtC", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT1W148mcjmfvr9J2RvWcGHxsAFApq9mcfgT", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT1HvwFnXteMbphi7mfPDhCWkZSDvXEz8iyv", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT1RUT25eGgo9KKWXfLhj1xYjghAY1iZ2don", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT1EWLAQGPMF2uhtVRPaCH2vtFVN36Njdr6z", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT1WPEis2WhAc2FciM2tZVn8qe6pCBe9HkDp", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT1Msatnmdy24sQt6knzpALs4tvHfSPPduA2", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT1A56dh8ivKNvLiLVkjYPyudmnY2Ti5Sba3", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT1KRyTaxCAM3YRquifEe29BDbUKNhJ6hdtx", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT1FL3C6t9Lyfskyb6rQrCRQTnf7M9t587VM", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT1Q1kfbvzteafLvnGz92DGvkdypXfTGfEA3", - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw ); - ( "KT1CjfCztmRpsyUee1nLa9Wcpfr7vgwqRZmk", - expruqNpURkmjQk5RGHjLrnS1U3DZnEsQCvQQNLSpN1powRmJeQgoJ ); - ( "KT1MHDHRLugz3A4qP6KqZDpa7FFmZfcJauV4", - expruwujdJkc5y4iPzr83Sd3KrJhzxSUb67JdCZmXNKiTTNvEkMrRU ); - ( "KT1BvVxWM6cjFuJNet4R9m64VDCN2iMvjuGE", - expruZKjVy3JbWcJmjtnvMGvRamkDhMgM3urGGdne3pkN9VKgK7VnD ); - ( "KT1PyX9b8WmShQjqNgDQsvxqj9UYdmHLr3xg", - exprv98vtze1uwbDXdpb27R8RQabWZMZDXGNAwaAZwCg6WSvXu8fw3 ); - ( "KT1XTXBsEauzcv3uPvVXW92mVqrx99UGsb9T", - expru1ukk6ZqdA32rFYFG7j1eGjfsatbdUZWz8Mi1kXWZYRZm4FZVe ); - ( "KT1Puc9St8wdNoGtLiD2WXaHbWU7styaxYhD", - expru1ukk6ZqdA32rFYFG7j1eGjfsatbdUZWz8Mi1kXWZYRZm4FZVe ); - ( "KT19c8n5mWrqpxMcR3J687yssHxotj88nGhZ", - expru1ukk6ZqdA32rFYFG7j1eGjfsatbdUZWz8Mi1kXWZYRZm4FZVe ); - ( "KT1DrJV8vhkdLEj76h1H9Q4irZDqAkMPo1Qf", - expru1ukk6ZqdA32rFYFG7j1eGjfsatbdUZWz8Mi1kXWZYRZm4FZVe ); - ( "KT1D68BvUm9N1fcq6uaZnyZvmBkBvj9biyPu", - expru1ukk6ZqdA32rFYFG7j1eGjfsatbdUZWz8Mi1kXWZYRZm4FZVe ); - ( "KT1CT7S2b9hXNRxRrEcany9sak1qe4aaFAZJ", - exprubv5oQmAUP8BwktmDgMWqTizYDJVhzHhJESGZhJ2GkHESZ1VWg ); - ] - - let patch_script (address, {legacy_script_hash; patched_code}) ctxt = + let patch_script (address, legacy_script_hash, patched_code) ctxt = Contract_repr.of_b58check address >>?= fun contract -> Storage.Contract.Code.find ctxt contract >>=? fun (ctxt, code_opt) -> Logging.log Notice "Patching %s... " address ; @@ -260,8 +168,10 @@ let prepare_first_block ctxt ~typecheck ~level ~timestamp = Receipt_repr.group_balance_updates balance_updates >>?= fun balance_updates -> Storage.Pending_migration.Balance_updates.add ctxt balance_updates >>= fun ctxt -> - Patch_legacy_contracts_for_J.( - List.fold_right_es patch_script contract_patches ctxt) + List.fold_right_es + Patch_legacy_contracts_for_J.patch_script + Legacy_script_patches_for_J.addresses_to_patch + ctxt >>=? fun ctxt -> return ctxt let prepare ctxt ~level ~predecessor_timestamp ~timestamp = diff --git a/src/proto_alpha/lib_protocol/legacy_script_patches_for_J.ml b/src/proto_alpha/lib_protocol/legacy_script_patches_for_J.ml index a11c2ed6d5..f4693d11f5 100644 --- a/src/proto_alpha/lib_protocol/legacy_script_patches_for_J.ml +++ b/src/proto_alpha/lib_protocol/legacy_script_patches_for_J.ml @@ -23,11 +23,20 @@ (* *) (*****************************************************************************) -type patched_script = { +type t = { legacy_script_hash : Script_expr_hash.t; patched_code : Michelson_v1_primitives.prim Micheline.canonical; + addresses : string list; } +type patched_script = t + +let script_hash : patched_script -> Script_expr_hash.t = + fun {legacy_script_hash; _} -> legacy_script_hash + +let code : patched_script -> Michelson_v1_primitives.prim Micheline.canonical = + fun {patched_code; _} -> patched_code + let bin_expr_exn hex = match Option.bind @@ -43,6 +52,7 @@ let exprtgpMFzTtyg1STJqANLQsjsMXmkf8UuJTuczQh8GPtqfw18x6Lc = legacy_script_hash = Script_expr_hash.of_b58check_exn "exprtgpMFzTtyg1STJqANLQsjsMXmkf8UuJTuczQh8GPtqfw18x6Lc"; + addresses = ["KT1MzfYSbq18fYr4f44aQRoZBQN72BAtiz5j"]; patched_code = bin_expr_exn "02000001d305000764085e036c055f036d0000000325646f046c000000082564656661756c7405010765035d036e050202000001a303210316072e02000000930743036a00000313020000001e020000000403190325072c020000000002000000090200000004034f0327020000000b051f02000000020321034c03170316031e0354034802000000490319033c072c020000002a034807430368010000001b4f6e6c7920746865206f776e65722063616e206f7065726174652e03420327020000000f034f0326051f0200000002031703420200000100051f0200000006031703210317034202000000c203170321053d036d0200000014051f020000000b051f02000000020321034c034c0200000017051f0200000010051f0200000009051f02000000020320055507640563036e076407650563036e0563036a0764036a076407650563036e0563036a036e020000002e072f020000002207430368010000001742616420636f6e747261637420696e2073746f72616765032702000000000313034803460533076407650563036e0563036a0764036a076407650563036e0563036a036e034d031b0342034c0316034c0200000012020000000d03210316051f02000000020317051f0200000004034c03420342"; @@ -53,6 +63,41 @@ let exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw = legacy_script_hash = Script_expr_hash.of_b58check_exn "exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw"; + addresses = + [ + "KT1Kfbk3B6NYPCPohPBDU3Hxf5Xeyy9PdkNp"; + "KT1JW6PwhfaEJu6U3ENsxUeja48AdtqSoekd"; + "KT1VsSxSXUkgw6zkBGgUuDXXuJs9ToPqkrCg"; + "KT1TcAHw5gpejyemwRtdNyFKGBLc4qwA5gtw"; + "KT1FN5fcNNcgieGjzxbVEPWUpJGwZEpzNGA8"; + "KT1Um7ieBEytZtumecLqGeL56iY6BuWoBgio"; + "KT1QuofAgnsWffHzLA7D78rxytJruGHDe7XG"; + "KT1CSKPf2jeLpMmrgKquN2bCjBTkAcAdRVDy"; + "KT1D5NmtDtgCwPxYNb2ZK2But6dhNLs1T1bV"; + "KT1VvXEpeBpreAVpfp4V8ZujqWu2gVykwXBJ"; + "KT1TzamC1SCj68ia2E4q2GWZeT24yRHvUZay"; + "KT1LZFMGrdnPjRLsCZ1aEDUAF5myA5Eo4rQe"; + "KT1PDAELuX7CypUHinUgFgGFskKs7ytwh5Vw"; + "KT19xDbLsvQKnp9xqfDNPWJbKJJmV93dHDUa"; + "KT1Cz7TyVFvHxXpxLS57RFePrhTGisUpPhvD"; + "KT1LQ99RfGcmFe98PiBcGXuyjBkWzAcoXXhW"; + "KT1Gow8VzXZx3Akn5kvjACqnjnyYBxQpzSKr"; + "KT1DnfT4hfikoMY3uiPE9mQV4y3Xweramb2k"; + "KT1FuFDZGdw86p6krdBUKoZfEMkcUmezqX5o"; + "KT1SLWhfqPtQq7f4zLomh8BNgDeprF9B6d2M"; + "KT1THsDNgHtN56ew9VVCAUWnqPC81pqAxCEp"; + "KT1CM1g1o9RKDdtDKgcBWE59X2KgTc2TcYtC"; + "KT1W148mcjmfvr9J2RvWcGHxsAFApq9mcfgT"; + "KT1HvwFnXteMbphi7mfPDhCWkZSDvXEz8iyv"; + "KT1RUT25eGgo9KKWXfLhj1xYjghAY1iZ2don"; + "KT1EWLAQGPMF2uhtVRPaCH2vtFVN36Njdr6z"; + "KT1WPEis2WhAc2FciM2tZVn8qe6pCBe9HkDp"; + "KT1Msatnmdy24sQt6knzpALs4tvHfSPPduA2"; + "KT1A56dh8ivKNvLiLVkjYPyudmnY2Ti5Sba3"; + "KT1KRyTaxCAM3YRquifEe29BDbUKNhJ6hdtx"; + "KT1FL3C6t9Lyfskyb6rQrCRQTnf7M9t587VM"; + "KT1Q1kfbvzteafLvnGz92DGvkdypXfTGfEA3"; + ]; patched_code = bin_expr_exn "0200000f73050007640865086407640865065a036c000000052564657374046a00000010257472616e736665725f616d6f756e7400000009255472616e7366657206630765065a036c0000000a25706f75725f64657374045c0000001025706f75725f617574686f72697a657200000009255365745f706f757207640865065f0765065f035c0000000c257369676e61746f726965730462000000102567726f75705f7468726573686f6c640000000b256b65795f67726f757073046200000012256f766572616c6c5f7468726573686f6c6400000009255365745f6b6579730663035d0000000d255365745f64656c65676174650000000d25616374696f6e5f696e707574065f055f056303670000000b257369676e6174757265730000000725416374696f6e0563076504670000000a25706f75725f61757468046a0000000c25706f75725f616d6f756e7405010765076504620000000f257265706c61795f636f756e7465720865065f0765065f035c0000000c257369676e61746f726965730462000000102567726f75705f7468726573686f6c640000000b256b65795f67726f757073046200000012256f766572616c6c5f7468726573686f6c6400000009256b65795f696e666f076508650865046a0000000f257665737465645f62616c616e6365046a000000122576657374696e675f696e6372656d656e74000000132576657374696e675f7175616e7469746965730865046b0000000c256e6578745f7061796f7574045b00000010257061796f75745f696e74657276616c000000112576657374696e675f7363686564756c65000000082576657374696e6705630765046e0000000a25706f75725f64657374045c0000001025706f75725f617574686f72697a657205020200000ce503210316072e020000078e051f020000001903170321063d036d0000000b406f7065726174696f6e73034c034c0316032104170000000c256b65795f696e666f204025051f0200000074041600000012257265706c61795f636f756e746572204025051f0200000016032104170000000e257369676e617475726573204025034c051f0200000036051f020000001804160000001025616374696f6e5f696e7075742040250321034903540342034c0342040c00000007407061636b6564034c051f0200000050032104160000000e256b65795f67726f757073204025051f0200000033041700000015256f766572616c6c5f7468726573686f6c64204025043000000010406f766572616c6c5f636f756e746572034c0552020000016c051f020000004f072d020000003a051f0200000002034c0321041600000003402525051f020000001f04170000000340252504300000000e4067726f75705f636f756e746572034c02000000090200000004034f03270552020000008f051f0200000015072d020000000002000000090200000004034f0327072f020000000203200200000065034c051f0200000033051f020000002c034c051f0200000021051f020000001a0743035b004104120000000e4067726f75705f636f756e7465720321041800000007407369675f6f6b0200000015072c020000000002000000090200000004034f0327034c0200000064051f020000005d051f02000000560743035b0000020000001c03190428000000144067726f75705f7468726573686f6c645f6d6574072c0200000023051f020000001c0743035b0041041200000010406f766572616c6c5f636f756e7465720200000000072d02000000090200000004034f03270200000000034c072d02000000090200000004034f0327020000000003200743035b0000020000001e0319042800000016406f766572616c6c5f7468726573686f6c645f6d65740200000015072c020000000002000000090200000004034f03270200000076051f020000006f051f0200000068032103160321041600000012257265706c61795f636f756e74657220402507430362000104120000000f407265706c61795f636f756e746572051f020000001204170000000c256b65795f696e666f2040250442000000052540202540051f020000000203170342072e020000025d072e02000001f40321051f0200000196041700000013257472616e736665725f616d6f756e7420402503210415000000084062616c616e6365020000001e020000000403190328072c020000000002000000090200000004034f0327034c051f0200000141051f020000004003210317032103160416000000162576657374696e675f7175616e7469746965732040250321041600000012257665737465645f62616c616e636520402503210321051f0200000023020000001e020000000403190332072c020000000002000000090200000004034f0327034c0393072f0200000004034f0327020000001504580000000f407665737465645f62616c616e6365051f020000001b0417000000152576657374696e675f696e6372656d656e742040250442000000194076657374696e675f7175616e746974696573202540202540051f0200000038032103160417000000142576657374696e675f7363686564756c65204025051f020000001304170000000d25706f75725f696e666f20402504420000000e4076657374696e672025402025400442000000052540202540034c031603420321041700000013257472616e736665725f616d6f756e74204025051f020000000e0416000000082564657374204025034f044d0000000c407472616e736665725f6f70041b0000000b406f7065726174696f6e73020000005d034c051f020000005405380200000006037a03540342034c03210316051f020000002c031704160000000b2576657374696e672040250442000000132576657374696e672025706f75725f696e666f0442000000084073746f7261676502000001cf072e02000001ab0321032104160000000e256b65795f67726f757073204025051f0200000064041700000021256f766572616c6c5f7468726573686f6c6420406e65775f7468726573686f6c640321074303620000020000001e020000000403190337072c020000000002000000090200000004034f03270843036200000000000840636f756e746572055202000000aa0321041600000010257369676e61746f7269657320402525051f02000000450417000000142567726f75705f7468726573686f6c64204025250321074303620000020000001e020000000403190337072c020000000002000000090200000004034f0327044500000009406e756d5f6b657973020000001e020000000403190328072c020000000002000000090200000004034f032707430362000104120000000840636f756e746572020000001e020000000403190328072c020000000002000000090200000004034f0327034c051f020000004b051f02000000190321031604160000000f257265706c61795f636f756e746572034c04420000000c254020256b65795f696e666f051f020000000203170442000000084073746f726167650200000018044e00000010407365745f64656c65676174655f6f70031b03420200000547072f02000001c80317032103170321051f020000001304170000000d25706f75725f696e666f20402504160000000b2576657374696e6720402503210417000000142576657374696e675f7363686564756c65204025032104160000000f256e6578745f7061796f75742040250321034002000000040319032a0200000015072c020000000002000000090200000004034f0327051f020000001b041700000013257061796f75745f696e74657276616c2040250321041200000010406e65775f6e6578745f7061796f7574044200000025256e6578745f7061796f757420254020406e65775f76657374696e675f7363686564756c65034c0416000000162576657374696e675f7175616e7469746965732040250321041600000012257665737465645f62616c616e6365204025051f020000001d0417000000152576657374696e675f696e6372656d656e74204025032104120000000c406e65775f62616c616e6365044200000012257665737465645f62616c616e63652025400442000000252576657374696e675f7175616e746974696573202576657374696e675f7363686564756c6504420000000b2576657374696e67202540034c03160442000000084073746f72616765053d036d0200000371051f0200000053031703210317032104160000000b2576657374696e6720402503210416000000162576657374696e675f7175616e7469746965732040250321041600000012257665737465645f62616c616e636520402503210321051f02000001e104170000001025706f75725f616d6f756e74204025250321051f0200000023020000001e020000000403190332072c020000000002000000090200000004034f032703210415000000084062616c616e6365020000001e020000000403190328072c020000000002000000090200000004034f0327034c049300000010406e65775f6375725f62616c616e6365072f0200000004034f03270200000000051f020000001b0417000000152576657374696e675f696e6372656d656e74204025044200000026257665737465645f62616c616e6365202540204076657374696e675f7175616e746974696573051f020000001a0417000000142576657374696e675f7363686564756c6520402504420000000e2540202540204076657374696e67051f020000002a04170000000d25706f75725f696e666f2040250321072f02000000090200000004034f03270200000000034c051f02000000870442000000052540202540034c03160321041600000012257265706c61795f636f756e746572204025032107430362000104120000000f407265706c61795f636f756e746572034c034903540342051f0200000032051f020000001204170000000c256b65795f696e666f20402504420000000525402025400442000000084073746f726167650321051f02000000fd034c032104160000000d25706f75725f646573742040250555036c072f0200000023074303680100000018426164207472616e73616374696f6e20726563656976657203270200000000051f02000000ac032104170000001325706f75725f617574686f72697a6572204025051f020000005904160000000d25706f75725f64657374204025034c032104160000000d25706f75725f61757468204025051f020000002804170000000f25706f75725f616d6f756e74204025034c03420342040c00000007407061636b656404180000000d40706f75725f617574685f6f6b0200000015072c020000000002000000090200000004034f0327053d036d04170000000f25706f75725f616d6f756e74204025034f044d0000000840706f75725f6f70031b0342"; @@ -63,6 +108,7 @@ let expruqNpURkmjQk5RGHjLrnS1U3DZnEsQCvQQNLSpN1powRmJeQgoJ = legacy_script_hash = Script_expr_hash.of_b58check_exn "expruqNpURkmjQk5RGHjLrnS1U3DZnEsQCvQQNLSpN1powRmJeQgoJ"; + addresses = ["KT1CjfCztmRpsyUee1nLa9Wcpfr7vgwqRZmk"]; patched_code = bin_expr_exn "02000001d405000764085e036c055f036d0000000325646f046c000000082564656661756c7405010765035d036e050202000001a403210316072e02000000930743036a00000313020000001e020000000403190325072c020000000002000000090200000004034f0327020000000b051f02000000020321034c03170316031e0354034802000000490319033c072c020000002a034807430368010000001b4f6e6c7920746865206f776e65722063616e206f7065726174652e03420327020000000f034f0326051f0200000002031703420200000101051f0200000006031703210317034202000000c303170321053d036d0200000014051f020000000b051f02000000020321034c034c0200000017051f0200000010051f0200000009051f02000000020320055507640563036e076407650563036e0563036a0764036a076407650563036e0563036a036e020000002f072f020000002307430368010000001842616420636f6e747261637420696e2073746f7261676521032702000000000313053e036a03480346034205330764036a076407650563036e0563036a036e05440563036e034d031b0342034c0316034c0200000012020000000d03210316051f02000000020317051f0200000004034c03420342"; @@ -73,6 +119,7 @@ let expruwujdJkc5y4iPzr83Sd3KrJhzxSUb67JdCZmXNKiTTNvEkMrRU = legacy_script_hash = Script_expr_hash.of_b58check_exn "expruwujdJkc5y4iPzr83Sd3KrJhzxSUb67JdCZmXNKiTTNvEkMrRU"; + addresses = ["KT1MHDHRLugz3A4qP6KqZDpa7FFmZfcJauV4"]; patched_code = bin_expr_exn "0200000cd705000764085e036c055f036d0000000325646f065f055f055f0362000000082564656661756c7405010765035d036e05020200000ca103210316072e02000000930743036a00000313020000001e020000000403190325072c020000000002000000090200000004034f0327020000000b051f02000000020321034c03170316031e0354034802000000490319033c072c020000002a034807430368010000001b4f6e6c7920746865206f776e65722063616e206f7065726174652e03420327020000000f034f0326051f0200000002031703420200000bfe051f020000000603170321031703420200000bc00321051f0200000002031703160743076507650765036203620765036207650362076503620362055f076507650362036207650362076503620765036203620707070707070000000007070000070700000707000000bf0302000000000200000019051f020000001004210000000a40706172616d65746572034c05520200000a3404580000002a405f706f696e74636f6c6f725f6f6c645f70745f6f6c645f636f6c6f725f6c6973745f736c6173685f33051f020000000203210342032104160000000b40706f696e74636f6c6f72072d02000002270200000014051f020000000b042100000005407461696c034c072d02000001d00200000014051f020000000b042100000005407461696c034c072d02000001510200000014051f020000000b042100000005407461696c034c072d020000001607430368010000000b57726f6e6720706f696e740327020000010b042100000002406e072d02000000e10200000014051f020000000b042100000005407461696c034c072d020000001607430368010000000b57726f6e6720706f696e740327020000009b042100000002406e03300200000039051f0200000030051f0200000027051f020000001e051f0200000015051f020000000c04210000000640636f6c6f72034c034c034c034c034c0342020000004a051f0200000041051f0200000038051f020000002f051f0200000026051f020000001d051f0200000014051f020000000b0421000000054068656164034c034c034c034c034c034c034c0342051f020000000403200320020000001607430368010000000b57726f6e672072616e67650327051f020000000403200320020000004f0743035b00010200000015051f020000000c04210000000640636f6c6f72034c03420200000026051f020000001d051f0200000014051f020000000b0421000000054068656164034c034c034c0342051f02000000040320032002000000270743035b00010200000014051f020000000b0421000000054068656164034c0342053d03620342051f020000000403200320020000002007430765055f03620765055f0362035b0707020000000007070200000000000104580000000f405f7074325f70636f6c6f72325f6e0321020000001003170416000000084070636f6c6f7232072d020000028f0200000012051f020000000904210000000340746c034c072d02000002320200000012051f020000000904210000000340746c034c072d02000001b30200000012051f020000000904210000000340746c034c072d02000001000200000012051f020000000904210000000340746c034c072d020000001607430368010000000b57726f6e6720636f6c6f72032702000000bc04210000000240610200000023051f020000001a051f0200000011051f02000000080421000000024062034c034c034c03420200000035051f020000002c051f0200000023051f020000001a051f0200000011051f02000000080421000000024067034c034c034c034c034c03420200000047051f020000003e051f0200000035051f020000002c051f0200000023051f020000001a051f0200000011051f02000000080421000000024072034c034c034c034c034c034c034c0342051f02000000040320032002000000850743036200bf030200000011051f02000000080421000000024062034c03420200000023051f020000001a051f0200000011051f02000000080421000000024067034c034c034c03420200000035051f020000002c051f0200000023051f020000001a051f0200000011051f02000000080421000000024072034c034c034c034c034c0342051f02000000040320032002000000510743036200bf0307430362000003420200000011051f02000000080421000000024067034c03420200000023051f020000001a051f0200000011051f02000000080421000000024072034c034c034c0342051f020000000403200320020000002f0743036200bf03074303620000034207430362000003420200000011051f02000000080421000000024072034c0342051f0200000004032003200200000024020000000b051f02000000020321034c0317031604170000000a406f6c645f636f6c6f720458000000074070636f6c6f720200000014051f020000000b051f02000000020321034c034c0317041700000005406c697374020000001d051f0200000014051f020000000b051f02000000020321034c034c034c03170316041600000007406f6c645f707403420200000014051f020000000b051f02000000020321034c034c0416000000044070743203420200000014051f020000000b051f02000000020321034c034c020000000a0317041700000002406e034207430359030a0534020000031604580000001540746d705f73686172705f315f736c6173685f333504210000000c40746d705f73686172705f310321041600000002406e020000000b051f02000000020321034c020000000403170317041600000007406f6c645f70740200000014051f020000000b051f02000000020321034c034c020000000403170317041700000005406c697374020000003a051f0200000031051f0200000028051f020000001f051f0200000016051f020000000d0421000000074070636f6c6f72034c034c034c034c034c0200000026051f020000001d051f0200000014051f020000000b051f02000000020321034c034c034c034c020000000c031704160000000440707432072d02000000ef0200000012051f020000000904210000000340746c034c072d020000007c0200000012051f020000000904210000000340746c034c072d020000001c07430368010000001157726f6e6720636f6f7264696e617465730327020000003204210000000240790200000023051f020000001a051f0200000011051f02000000080421000000024078034c034c034c0342051f02000000040320032002000000450200000026051f020000001d051f0200000014051f020000000b051f02000000020321034c034c034c034c03170200000011051f02000000080421000000024078034c0342051f02000000040320032002000000520200000014051f020000000b051f02000000020321034c034c03170743036200010200000026051f020000001d051f0200000014051f020000000b051f02000000020321034c034c034c034c0316031203420458000000034070740200000027051f0200000020051f0200000019051f0200000012051f020000000b051f020000000403200320044200000003407074041b00000005406c697374034c0342053d036203420743035b00010200000014051f020000000b051f02000000020321034c034c034b03420743035b00000200000014051f020000000b051f02000000020321034c034c0200000017051f0200000010051f0200000009051f020000000203200319032a034203210316051f02000000020317045800000015405f5f6e5f5f7074325f6f6c645f70745f6c6973740200000014051f020000000d051f02000000060320032003200321020000000403170317041700000005406c6973740200000014051f020000000b051f02000000020321034c034c0200000017051f0200000010051f0200000009051f020000000203200200000014051f020000000b051f02000000020321034c034c0200000017051f0200000010051f0200000009051f02000000020320020000000403170317041600000007406f6c645f70740342034204580000000f405f5f70745f706172616d65746572051f02000000020320020000000b051f02000000020321034c0555055f07650765036203620765036207650362076503620362020000002e072f020000002207430368010000001742616420636f6e747261637420696e2073746f726167650327020000000003130200000014051f020000000b051f02000000020321034c034c0200000017051f0200000010051f0200000009051f0200000002032004170000000a40706172616d65746572044d00000003406f70034c053d036d0200000014051f020000000b051f02000000020321034c034c0200000017051f0200000010051f0200000009051f02000000020320031b0342034c0316034c0200000012020000000d03210316051f02000000020317051f0200000004034c03420342"; @@ -83,6 +130,7 @@ let expruZKjVy3JbWcJmjtnvMGvRamkDhMgM3urGGdne3pkN9VKgK7VnD = legacy_script_hash = Script_expr_hash.of_b58check_exn "expruZKjVy3JbWcJmjtnvMGvRamkDhMgM3urGGdne3pkN9VKgK7VnD"; + addresses = ["KT1BvVxWM6cjFuJNet4R9m64VDCN2iMvjuGE"]; patched_code = bin_expr_exn "0200001da3050007640764045d0000000d257365745f64656c6567617465046c000000102572656d6f76655f64656c65676174650864046c00000010255f4c69715f656e7472795f6d61696e0764046200000013255f4c69715f656e7472795f73656c6c4f75740764046a00000014255f4c69715f656e7472795f77697468647261770764046c00000013255f4c69715f656e7472795f6465706f7369740865046a000000062573656c6c500765046a000000052562757950046a0000000d25657874726142616c616e6365000000253a707269636555706461746520255f4c69715f656e7472795f757064617465507269636573000000122564656661756c74203a5f656e747269657305010765035d08650860036e0362000000092562616c616e6365730765046800000005256e616d6507650468000000072573796d626f6c076504620000000925646563696d616c73076504620000000c25746f74616c537570706c790765046a0000000825696e42616b65720765046e00000006256f776e65720765046a00000009256275795072696365046a0000000a2573656c6c5072696365000000083a73746f7261676505020200001bef03210316072e02000000b10743036a00000313020000001e020000000403190325072c020000000002000000090200000004034f0327020000000b051f02000000020321034c03170316031e0354034802000000670319033c072c020000002a034807430368010000001b4f6e6c7920746865206f776e65722063616e206f7065726174652e03420327020000002d051f02000000060317053d036d072e02000000080346034e031b0342020000000c0320053e035d034e031b03420200001b2e051f020000000603170321031703420200001af00321051f02000000020317031604210000000a40706172616d65746572072e020000055404580000000c406e6f705f736c6173685f330200000025051f020000001c0200000017051f020000000e0421000000084073746f72616765034c034c042100000006407374617465020000001d0317031703170317031703170317041600000009256275795072696365074303620080897a0313043a00000007406d6963726f730322072f020000001507430368010000000a42616420616d6f756e74032702000004a5044800000005406164647204210000000540616464720555036c072f020000003a07430368010000002f43616e6e6f7420757365207468697320636f6e74726163742066726f6d206e6f6e20756e697420636f6e74726163740327020000043a0200000024051f020000001b0200000016051f020000000d04210000000740616d6f756e74034c034c04160000000740746f6b656e73020000003f051f02000000360200000031051f02000000280200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c034c034c03210416000000092562616c616e636573034c03170321041600000005256e616d65034c031703210416000000072573796d626f6c034c0317032104160000000925646563696d616c73034c03170317020000004e051f02000000450200000040051f02000000370200000032051f02000000290200000024051f020000001b0200000016051f020000000d04210000000740746f6b656e73034c034c034c034c034c0200000093051f020000008a0200000085051f020000007c0200000077051f020000006e0200000069051f0200000060020000005b051f0200000052020000004d051f0200000044020000003f051f02000000360200000031051f02000000280200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c034c034c034c034c034c034c034c034c020000001a031703170317031704160000000c25746f74616c537570706c79031204420000000c25746f74616c537570706c79034c04420000000925646563696d616c73034c0442000000072573796d626f6c034c044200000005256e616d65034c04420000000d407331202562616c616e6365730317020000004d051f0200000044020000003f051f02000000360200000031051f02000000280200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c034c034c034c0416000000092562616c616e636573020000005b051f0200000052020000004d051f0200000044020000003f051f02000000360200000031051f02000000280200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c034c034c034c034c0416000000092562616c616e636573020000004c051f0200000043020000003e051f02000000350200000030051f02000000270200000022051f02000000190200000014051f020000000b0421000000054061646472034c034c034c034c034c0329072f0200000006074303620000020000000004580000000540686176650200000032051f02000000290200000024051f020000001b0200000016051f020000000d04210000000740746f6b656e73034c034c034c0312020000004c051f0200000043020000003e051f02000000350200000030051f02000000270200000022051f02000000190200000014051f020000000b0421000000054061646472034c034c034c034c034c051f02000000020346051f0200000019051f0200000012051f020000000b051f020000000403200320035004420000000d407332202562616c616e636573053d036d0342051f020000000403200320051f0200000004032003200200001568072e02000008d004580000001040616d6f756e745f736c6173685f31340200000025051f020000001c0200000017051f020000000e0421000000084073746f72616765034c034c0743036a0080c0a8ca9a3a0743036a0080897a0200000032051f02000000290200000024051f020000001b0200000016051f020000000d04210000000740616d6f756e74034c034c034c043a00000005407a616d740322072f020000001507430368010000000a62616420616d6f756e740327020000080d04480000000540616464720743036a0000041300000009407478416d6f756e740319033c072c020000003207430368010000002763616e6e6f742062757920616e642073656c6c20696e2073616d65207472616e73616374696f6e032702000007a00200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c0416000000092562616c616e6365730200000014051f020000000b0421000000054061646472034c0329072f0200000006074303620000020000000004580000000540686176650421000000054068617665020000004e051f02000000450200000040051f02000000370200000032051f02000000290200000024051f020000001b0200000016051f020000000d04210000000740616d6f756e74034c034c034c034c034c0319032a072c020000003507430368010000002a546865206164647265737320646f6573206e6f7420686176652074686174206d7563682073746f726564032702000006850200000014051f020000000b0421000000054061646472034c0555036c072f02000000480200000014051f020000000b0421000000054061646472034c07430368010000002243616e6e6f74207265636f76657220626f6f6c20636f6e74726163742066726f6d3a034203270200000614020000004e051f02000000450200000040051f02000000370200000032051f02000000290200000024051f020000001b0200000016051f020000000d04210000000740616d6f756e74034c034c034c034c034c020000004d051f0200000044020000003f051f02000000360200000031051f02000000280200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c034c034c034c020000001a031703170317031704160000000c25746f74616c537570706c79034b03210311034c0328072c020000051c0200000013051f020000000a04210000000440647374034c020000005b051f0200000052020000004d051f0200000044020000003f051f02000000360200000031051f02000000280200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c034c034c034c034c020000001e031703170317031703170317031704170000000a2573656c6c50726963650200000051051f02000000480200000043051f020000003a0200000035051f020000002c0200000027051f020000001e0200000019051f0200000010020000000b051f02000000020321034c034c034c034c034c034c04160000000a406e6f6e4d6963726f73043a0000000740746f53656e64034f044d00000003406f70020000006a051f0200000061020000005c051f0200000053020000004e051f02000000450200000040051f02000000370200000032051f02000000290200000024051f020000001b0200000016051f020000000d04210000000740616d6f756e74034c034c034c034c034c034c034c020000003e051f02000000350200000030051f02000000270200000022051f02000000190200000014051f020000000b0421000000054068617665034c034c034c034c034b03210311034c0328072c020000031b0200000069051f0200000060020000005b051f0200000052020000004d051f0200000044020000003f051f02000000360200000031051f02000000280200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c034c034c034c034c034c03210416000000092562616c616e636573034c03170321041600000005256e616d65034c031703210416000000072573796d626f6c034c0317032104160000000925646563696d616c73034c03170317020000006d051f0200000064020000005f051f02000000560200000051051f02000000480200000043051f020000003a0200000035051f020000002c0200000027051f020000001e0200000019051f020000001004210000000a406e6577537570706c79034c034c034c034c034c034c034c04420000000c25746f74616c537570706c79034c04420000000925646563696d616c73034c0442000000072573796d626f6c034c044200000005256e616d65034c04420000000d407331202562616c616e63657303170200000077051f020000006e0200000069051f0200000060020000005b051f0200000052020000004d051f0200000044020000003f051f02000000360200000031051f02000000280200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c034c034c034c034c034c034c0416000000092562616c616e6365730200000028051f020000001f020000001a051f020000001104210000000b406e657742616c616e6365034c034c0200000076051f020000006d0200000068051f020000005f020000005a051f0200000051020000004c051f0200000043020000003e051f02000000350200000030051f02000000270200000022051f02000000190200000014051f020000000b0421000000054061646472034c034c034c034c034c034c034c034c051f02000000020346051f0200000017051f0200000010051f0200000009051f02000000020320035004420000000d407332202562616c616e636573053d036d0200000019051f0200000010020000000b051f02000000020321034c034c031b0342020000001507430368010000000a62616420616d6f756e740327051f020000000403200320020000001507430368010000000a62616420616d6f756e740327051f02000000020320051f02000000020320051f020000000403200320051f0200000004032003200200000c8c072e020000034f04580000000d40616d745f736c6173685f33330200000025051f020000001c0200000017051f020000000e0421000000084073746f72616765034c034c0743035d0100000024747a314c42454b5861785162643547747a62633141544377633370707075383161574763041e0000000540646573740200000021051f02000000180200000013051f020000000a04210000000440616d74034c034c034f044d00000003406f700200000015051f020000000c042100000006407374617465034c0200000018031703170317031703170317041600000006256f776e657204470000000540616464720319033c072c02000000220743036801000000174f6e6c79206f776e65722063616e207769746864726177032702000002280200000015051f020000000c042100000006407374617465034c03210416000000092562616c616e636573034c03170321041600000005256e616d65034c031703210416000000072573796d626f6c034c0317032104160000000925646563696d616c73034c0317032104160000000c25746f74616c537570706c79034c031703170200000075051f020000006c0200000067051f020000005e0200000059051f0200000050020000004b051f0200000042020000003d051f0200000034020000002f051f02000000260200000021051f02000000180200000013051f020000000a04210000000440616d74034c034c034c034c034c034c034c034c0200000077051f020000006e0200000069051f0200000060020000005b051f0200000052020000004d051f0200000044020000003f051f02000000360200000031051f02000000280200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c034c034c034c034c034c034c02000000180317031703170317031704160000000825696e42616b6572031204420000000825696e42616b6572034c04420000000c25746f74616c537570706c79034c04420000000925646563696d616c73034c0442000000072573796d626f6c034c044200000005256e616d65034c04420000000d407331202562616c616e636573053d036d0200000020051f02000000170200000012051f0200000009042100000003406f70034c034c031b0342051f02000000060320032003200200000931072e020000022504580000000d406e6f705f736c6173685f33390200000025051f020000001c0200000017051f020000000e0421000000084073746f72616765034c034c0421000000064073746174650200000018031703170317031703170317041600000006256f776e657204470000000540616464720319033c072c02000000210743036801000000164f6e6c79206f776e65722063616e206465706f7369740327020000017804210000000640737461746503210416000000092562616c616e636573034c03170321041600000005256e616d65034c031703210416000000072573796d626f6c034c0317032104160000000925646563696d616c73034c0317032104160000000c25746f74616c537570706c79034c0317031704130000000740616d6f756e740200000069051f0200000060020000005b051f0200000052020000004d051f0200000044020000003f051f02000000360200000031051f02000000280200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c034c034c034c034c034c02000000180317031703170317031704160000000825696e42616b6572034b04420000000825696e42616b6572034c04420000000c25746f74616c537570706c79034c04420000000925646563696d616c73034c0442000000072573796d626f6c034c044200000005256e616d65034c04420000000d407331202562616c616e636573053d036d0342051f020000000403200320020000070004580000000e40696e666f5f736c6173685f34340200000025051f020000001c0200000017051f020000000e0421000000084073746f72616765034c034c04210000000640737461746503210416000000092562616c616e636573034c03170321041600000005256e616d65034c031703210416000000072573796d626f6c034c0317032104160000000925646563696d616c73034c0317032104160000000c25746f74616c537570706c79034c0317032104160000000825696e42616b6572034c03170321041600000006256f776e6572034c03170416000000092562757950726963650200000084051f020000007b0200000076051f020000006d0200000068051f020000005f020000005a051f0200000051020000004c051f0200000043020000003e051f02000000350200000030051f02000000270200000022051f02000000190200000014051f020000000b04210000000540696e666f034c034c034c034c034c034c034c034c034c0416000000062573656c6c50034c044200000014256275795072696365202573656c6c5072696365034c044200000006256f776e6572034c04420000000825696e42616b6572034c04420000000c25746f74616c537570706c79034c04420000000925646563696d616c73034c0442000000072573796d626f6c034c044200000005256e616d65034c04420000000d407331202562616c616e63657303210416000000092562616c616e636573034c03170321041600000005256e616d65034c031703210416000000072573796d626f6c034c0317032104160000000925646563696d616c73034c0317032104160000000c25746f74616c537570706c79034c0317032104160000000825696e42616b6572034c03170321041600000006256f776e6572034c031704170000000a2573656c6c50726963650200000084051f020000007b0200000076051f020000006d0200000068051f020000005f020000005a051f0200000051020000004c051f0200000043020000003e051f02000000350200000030051f02000000270200000022051f02000000190200000014051f020000000b04210000000540696e666f034c034c034c034c034c034c034c034c034c020000000d03170416000000052562757950044200000014256275795072696365202573656c6c5072696365034c044200000006256f776e6572034c04420000000825696e42616b6572034c04420000000c25746f74616c537570706c79034c04420000000925646563696d616c73034c0442000000072573796d626f6c034c044200000005256e616d65034c04420000000d407332202562616c616e6365730200000022051f02000000190200000014051f020000000b04210000000540696e666f034c034c0416000000062573656c6c500200000030051f02000000270200000022051f02000000190200000014051f020000000b04210000000540696e666f034c034c034c020000000d0317041600000005256275795003190337072c020000002b074303680100000020696e76616c69642070726963652c20656e61626c6573206172626974726167650327020000026f0200000015051f020000000c042100000006407374617465034c0200000018031703170317031703170317041600000006256f776e657204470000000540616464720319033c072c02000000230743036801000000184f6e6c79206f776e65722063616e20736574207072696365032702000001fa04210000000340733203210416000000092562616c616e636573034c03170321041600000005256e616d65034c031703210416000000072573796d626f6c034c0317032104160000000925646563696d616c73034c0317032104160000000c25746f74616c537570706c79034c031703170200000076051f020000006d0200000068051f020000005f020000005a051f0200000051020000004c051f0200000043020000003e051f02000000350200000030051f02000000270200000022051f02000000190200000014051f020000000b04210000000540696e666f034c034c034c034c034c034c034c034c0200000015031704170000000d25657874726142616c616e63650200000066051f020000005d0200000058051f020000004f020000004a051f0200000041020000003c051f0200000033020000002e051f02000000250200000020051f02000000170200000012051f0200000009042100000003407332034c034c034c034c034c034c034c02000000180317031703170317031704160000000825696e42616b6572031204420000000825696e42616b6572034c04420000000c25746f74616c537570706c79034c04420000000925646563696d616c73034c0442000000072573796d626f6c034c044200000005256e616d65034c04420000000d407333202562616c616e636573053d036d0342051f0200000006032003200320051f020000000403200320034c0316034c0200000012020000000d03210316051f02000000020317051f0200000004034c03420342"; @@ -93,6 +141,7 @@ let exprv98vtze1uwbDXdpb27R8RQabWZMZDXGNAwaAZwCg6WSvXu8fw3 = legacy_script_hash = Script_expr_hash.of_b58check_exn "exprv98vtze1uwbDXdpb27R8RQabWZMZDXGNAwaAZwCg6WSvXu8fw3"; + addresses = ["KT1PyX9b8WmShQjqNgDQsvxqj9UYdmHLr3xg"]; patched_code = bin_expr_exn "0200000cd305000764085e036c055f036d0000000325646f065f055f055f0362000000082564656661756c7405010765035d036e05020200000c9d03210316072e02000000930743036a00000313020000001e020000000403190325072c020000000002000000090200000004034f0327020000000b051f02000000020321034c03170316031e0354034802000000490319033c072c020000002a034807430368010000001b4f6e6c7920746865206f776e65722063616e206f7065726174652e03420327020000000f034f0326051f0200000002031703420200000bfa051f020000000603170321031703420200000bbc0321051f0200000002031703160743076507650765036203620765036207650362076503620362055f076507650362036207650362076503620765036203620707070707070000000007070000070700000707000000bf0302000000000200000019051f020000001004210000000a40706172616d65746572034c05520200000a3004580000002a405f706f696e74636f6c6f725f6f6c645f70745f6f6c645f636f6c6f725f6c6973745f736c6173685f33051f020000000203210342032104160000000b40706f696e74636f6c6f72072d02000002270200000014051f020000000b042100000005407461696c034c072d02000001d00200000014051f020000000b042100000005407461696c034c072d02000001510200000014051f020000000b042100000005407461696c034c072d020000001607430368010000000b57726f6e6720706f696e740327020000010b042100000002406e072d02000000e10200000014051f020000000b042100000005407461696c034c072d020000001607430368010000000b57726f6e6720706f696e740327020000009b042100000002406e03300200000039051f0200000030051f0200000027051f020000001e051f0200000015051f020000000c04210000000640636f6c6f72034c034c034c034c034c0342020000004a051f0200000041051f0200000038051f020000002f051f0200000026051f020000001d051f0200000014051f020000000b0421000000054068656164034c034c034c034c034c034c034c0342051f020000000403200320020000001607430368010000000b57726f6e672072616e67650327051f020000000403200320020000004f0743035b00010200000015051f020000000c04210000000640636f6c6f72034c03420200000026051f020000001d051f0200000014051f020000000b0421000000054068656164034c034c034c0342051f02000000040320032002000000270743035b00010200000014051f020000000b0421000000054068656164034c0342053d03620342051f020000000403200320020000002007430765055f03620765055f0362035b0707020000000007070200000000000104580000000f405f7074325f70636f6c6f72325f6e0321020000001003170416000000084070636f6c6f7232072d020000028f0200000012051f020000000904210000000340746c034c072d02000002320200000012051f020000000904210000000340746c034c072d02000001b30200000012051f020000000904210000000340746c034c072d02000001000200000012051f020000000904210000000340746c034c072d020000001607430368010000000b57726f6e6720636f6c6f72032702000000bc04210000000240610200000023051f020000001a051f0200000011051f02000000080421000000024062034c034c034c03420200000035051f020000002c051f0200000023051f020000001a051f0200000011051f02000000080421000000024067034c034c034c034c034c03420200000047051f020000003e051f0200000035051f020000002c051f0200000023051f020000001a051f0200000011051f02000000080421000000024072034c034c034c034c034c034c034c0342051f02000000040320032002000000850743036200bf030200000011051f02000000080421000000024062034c03420200000023051f020000001a051f0200000011051f02000000080421000000024067034c034c034c03420200000035051f020000002c051f0200000023051f020000001a051f0200000011051f02000000080421000000024072034c034c034c034c034c0342051f02000000040320032002000000510743036200bf0307430362000003420200000011051f02000000080421000000024067034c03420200000023051f020000001a051f0200000011051f02000000080421000000024072034c034c034c0342051f020000000403200320020000002f0743036200bf03074303620000034207430362000003420200000011051f02000000080421000000024072034c0342051f0200000004032003200200000024020000000b051f02000000020321034c0317031604170000000a406f6c645f636f6c6f720458000000074070636f6c6f720200000014051f020000000b051f02000000020321034c034c0317041700000005406c697374020000001d051f0200000014051f020000000b051f02000000020321034c034c034c03170316041600000007406f6c645f707403420200000014051f020000000b051f02000000020321034c034c0416000000044070743203420200000014051f020000000b051f02000000020321034c034c020000000a0317041700000002406e034207430359030a0534020000031204580000001540746d705f73686172705f315f736c6173685f333504210000000c40746d705f73686172705f310321020000000403170317041600000007406f6c645f7074020000000b051f02000000020321034c020000000c031704160000000440707432072d02000000dd0200000012051f020000000904210000000340746c034c072d020000007c0200000012051f020000000904210000000340746c034c072d020000001c07430368010000001157726f6e6720636f6f7264696e617465730327020000003204210000000240790200000023051f020000001a051f0200000011051f02000000080421000000024078034c034c034c0342051f02000000040320032002000000330200000014051f020000000b051f02000000020321034c034c03170200000011051f02000000080421000000024078034c0342051f0200000004032003200200000029032103170743036200010200000014051f020000000b051f02000000020321034c034c031603120342051f020000000203200200000010051f0200000009051f020000000203200458000000034070740743035b00010200000014051f020000000b051f02000000020321034c034c041600000002406e044b00000002406e0200000014051f020000000b051f02000000020321034c034c0200000017051f0200000010051f0200000009051f02000000020320020000000403170317041700000005406c697374020000001d051f0200000014051f020000000b051f02000000020321034c034c034c020000001d051f0200000014051f020000000b051f02000000020321034c034c034c0442000000094070745f636f6c6f72041b00000005406c6973740200000014051f020000000b051f02000000020321034c034c0200000017051f0200000010051f0200000009051f020000000203200342053d03620342020000000b051f02000000020321034c03420743035b00000200000014051f020000000b051f02000000020321034c034c0200000017051f0200000010051f0200000009051f020000000203200319032a034203210316051f020000000203170200000014051f020000000d051f0200000006032003200320045800000015405f5f6e5f5f7074325f6f6c645f70745f6c6973740321020000000403170317041700000005406c6973740200000014051f020000000b051f02000000020321034c034c0200000017051f0200000010051f0200000009051f020000000203200200000014051f020000000b051f02000000020321034c034c0200000017051f0200000010051f0200000009051f02000000020320020000000403170317041600000007406f6c645f707403420342051f0200000002032004580000000f405f5f70745f706172616d65746572020000000b051f02000000020321034c0555055f07650765036203620765036207650362076503620362020000002e072f020000002207430368010000001742616420636f6e747261637420696e2073746f726167650327020000000003130200000014051f020000000b051f02000000020321034c034c0200000017051f0200000010051f0200000009051f0200000002032004170000000a40706172616d65746572044d00000003406f70034c053d036d0200000014051f020000000b051f02000000020321034c034c0200000017051f0200000010051f0200000009051f02000000020320031b0342034c0316034c0200000012020000000d03210316051f02000000020317051f0200000004034c03420342"; @@ -103,6 +152,14 @@ let expru1ukk6ZqdA32rFYFG7j1eGjfsatbdUZWz8Mi1kXWZYRZm4FZVe = legacy_script_hash = Script_expr_hash.of_b58check_exn "expru1ukk6ZqdA32rFYFG7j1eGjfsatbdUZWz8Mi1kXWZYRZm4FZVe"; + addresses = + [ + "KT1XTXBsEauzcv3uPvVXW92mVqrx99UGsb9T"; + "KT1Puc9St8wdNoGtLiD2WXaHbWU7styaxYhD"; + "KT19c8n5mWrqpxMcR3J687yssHxotj88nGhZ"; + "KT1DrJV8vhkdLEj76h1H9Q4irZDqAkMPo1Qf"; + "KT1D68BvUm9N1fcq6uaZnyZvmBkBvj9biyPu"; + ]; patched_code = bin_expr_exn "0200002e9205000764076407640865046e000000083a7370656e646572076504620000000a3a616c6c6f77616e63650462000000113a63757272656e74416c6c6f77616e63650000000825617070726f766508650765046e000000063a6f776e657204620000000d3a6d696e4c71744d696e74656407650462000000133a6d6178546f6b656e734465706f7369746564046b000000093a646561646c696e650000000d256164644c6971756964697479076408650765046e000000063a6f776e65720765046e000000033a746f04620000000a3a6c71744275726e65640765046a000000103a6d696e58747a57697468647261776e07650462000000133a6d696e546f6b656e7357697468647261776e046b000000093a646561646c696e65000000102572656d6f76654c697175696469747907640865046e000000033a746f07650462000000103a6d696e546f6b656e73426f75676874046b000000093a646561646c696e650000000b2578747a546f546f6b656e08650765046e000000063a6f776e6572046e000000033a746f076504620000000b3a746f6b656e73536f6c640765046a0000000d3a6d696e58747a426f75676874046b000000093a646561646c696e650000000b25746f6b656e546f58747a0764076408650765046e000000153a6f7574707574446578746572436f6e747261637407650462000000103a6d696e546f6b656e73426f75676874046e000000063a6f776e65720765046e000000033a746f076504620000000b3a746f6b656e73536f6c64046b000000093a646561646c696e650000000d25746f6b656e546f546f6b656e0764045d0000001025757064617465546f6b656e506f6f6c04620000001825757064617465546f6b656e506f6f6c496e7465726e616c076408650563035d0359000000092573657442616b65720764046e0000000b257365744d616e61676572046c000000082564656661756c74050107650861046e000000063a6f776e657207650462000000083a62616c616e63650760046e000000083a7370656e64657204620000000a3a616c6c6f77616e636500000009256163636f756e7473076507650459000000183a73656c6649735570646174696e67546f6b656e506f6f6c076504590000000c3a667265657a6542616b65720462000000093a6c7174546f74616c07650765046e000000083a6d616e61676572046e0000000d3a746f6b656e41646472657373076504620000000a3a746f6b656e506f6f6c046a000000083a78747a506f6f6c05020200002aef055707650764076407640765036e07650362036207650765036e036207650362036b076407650765036e0765036e03620765036a07650362036b07640765036e07650362036b07650765036e036e076503620765036a036b0764076407650765036e07650362036e0765036e07650362036b0764035d0362076407650563035d03590764036e036c07650761036e076503620760036e036207650765035907650359036207650765036e036e07650362036a03210316051f02000000020317072e0200001df1072e0200000b73072e02000001c1051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327051f02000000020321034c031603480329072f020000000e0723036e03620743036200000342020000000003210317071f0002020000000203210570000203160329072f02000000060743036200000200000000071f000202000000020321057000020317031703190325072c020000000002000000630743036801000000585468652063757272656e7420616c6c6f77616e636520706172616d65746572206d75737420657175616c207468652073656e64657227732063757272656e7420616c6c6f77616e636520666f7220746865206f776e65722e0327032103170570000203210316051f02000000060317031603460350051f020000000d0321051f020000000203160317034c0320034c0342051f020000000403210316034603480350051f020000000d0321051f020000000203170316034c03200342053d036d034202000009a6051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e03270200000000032103170317034003190337072c0200000000020000002807430368010000001d4e4f572069732067726561746572207468616e20646561646c696e652e032703210317031607430362000003190337072c0200000000020000003807430368010000002d6d6178546f6b656e734465706f7369746564206d7573742062652067726561746572207468616e207a65726f2e032703210316031707430362000003190337072c020000000002000000320743036801000000276d696e4c71744d696e746564206d7573742062652067726561746572207468616e207a65726f2e03270743036a000003130319032a072c0200000000020000002c074303680100000021416d6f756e74206d7573742062652067726561746572207468616e207a65726f2e0327051f02000000020321034c031703160317031703300325072c020000032f03130743036a0080897a03190332072c0200000000020000004f07430368010000004454686520696e697469616c206c697175696469747920616d6f756e74206d7573742062652067726561746572207468616e206f7220657175616c20746f20312058545a2e0327034c0313051f02000000060743036a00010322072f020000000b0743036801000000000327020000000203160321051f0200000071051f020000000403210317051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c03420342051f020000000d0321051f020000000203160317034c0320034c0342034c071f0002020000000203210570000203160316051f0200000004032103160329072f020000000e0723036e03620743036200000342020000000005700002051f020000000d0321051f020000000203170316034c03200342051f0200000004032103160346071f00030200000002032105700003031603160350051f020000000d0321051f020000000203170316034c032003420321031703170317031703130312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c034203210317031703170316071f00020200000002032105700002031703160312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342051f0200000011032103170316051f0200000004031603160321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a0000057000030349035405700005051f020000000203420342034d051f0200000004053d036d031b034202000004e6051f02000000020321034c0317031703170317051f02000000060743036a00010322072f020000000b0743036801000000000327020000000203160313051f02000000060743036a00010322072f020000000b0743036801000000000327020000000203160321071f000402000000020321057000040317031703170316033a071f00020200000002032105700002034c0322072f020000001507430368010000000a64697642795a65726f2e0327020000002703210316051f02000000020317034c03300325072c020000000002000000080743036200010312032107430362000003190337072c02000000000200000023074303680100000018746f6b656e734465706f7369746564206973207a65726f2e0327034c071f000402000000020321057000040317031603170317033a051f0200000002034c0322072f0200000002032702000000020316071f0002020000000203210570000203160317051f0200000002032103190332072c020000000002000000430743036801000000386c71744d696e746564206d7573742062652067726561746572207468616e206f7220657175616c20746f206d696e4c71744d696e7465642e0327051f0200000066051f02000000020321034c03170316051f0200000002032103190328072c0200000000020000003e074303680100000033746f6b656e734465706f73697465642069732067726561746572207468616e206d6178546f6b656e734465706f73697465642e0327071f00030200000002032105700003071f0003020000000203210570000303160316051f020000000203160329072f020000000e0723036e03620743036200000342020000000003210316071f000202000000020321057000020312051f020000000d0321051f020000000203170316034c032003420346071f0003020000000203210570000303160316051f020000000f051f020000000805700003032103160350051f020000000d0321051f020000000203170316034c0320034203210317031603170317057000020312051f020000000403210317051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c03420342051f020000000d0321051f020000000203160317034c0320034c03420321031703170317031703130312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c034203210317031703170316071f000202000000020321057000020312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342051f020000000b051f0200000004031603160321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a0000057000030349035405700005051f020000000203420342034d051f0200000004053d036d031b03420200001272072e02000008e5051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000321031703170317034003190337072c0200000000020000002807430368010000001d4e4f572069732067726561746572207468616e20646561646c696e652e03270743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e03270321031703160743036a000003190337072c0200000000020000003507430368010000002a6d696e58747a57697468647261776e206d7573742062652067726561746572207468616e207a65726f2e0327032103170317031607430362000003190337072c0200000000020000003807430368010000002d6d696e546f6b656e7357697468647261776e206d7573742062652067726561746572207468616e207a65726f2e0327032103160317031707430362000003190337072c0200000000020000002f0743036801000000246c71744275726e6564206d7573742062652067726561746572207468616e207a65726f2e0327032103160316051f020000000d051f02000000020321034c03160329072f02000000220743036801000000176f776e657220686173206e6f206c69717569646974792e03270200000000034c0321031603170317071f00020200000002032105700002031603190328072c0200000000020000003507430368010000002a6c71744275726e65642069732067726561746572207468616e206f776e657227732062616c616e63652e0327032103160316034803190325072c0200000004034c03160200000132034c0321031703480329072f020000002a07430368010000001f73656e64657220686173206e6f20617070726f76616c2062616c616e63652e03270200000000051f0200000017034c0321031603170317051f02000000060743035b0000034b0321051f020000004b03190328072c0200000000020000003b07430368010000003073656e64657220617070726f76616c2062616c616e6365206973206c657373207468616e204c5154206275726e65642e03270311034605700002032103170570000203480350051f020000000d0321051f020000000203160317034c0320034c034203210316051f0200000043034605710001032103160316034c051f020000002e051f020000000b051f0200000004032103160350051f020000000d0321051f020000000203170316034c03200342051f02000000020321034c031603170317071f000302000000020321057000030317031703170317051f02000000060743036a00010322072f020000000b074303680100000000032702000000020316033a051f0200000017071f0002020000000203210570000203170316031703170322072f020000001507430368010000000a64697642795a65726f2e0327020000000203160743036a0001033a0321071f000302000000020321057000030317031603190332072c0200000000020000003507430368010000002a78747a57697468647261776e206973206c657373207468616e206d696e58747a57697468647261776e2e0327071f00020200000002032105700002031603170317051f0200000023071f0003020000000203210570000303210317031603170317034c0317031703170316033a0322072f020000001507430368010000000a64697642795a65726f2e0327020000000203160321071f0004020000000203210570000403170317031603190332072c0200000000020000003b074303680100000030746f6b656e7357697468647261776e206973206c657373207468616e206d696e546f6b656e7357697468647261776e2e0327071f0003020000000203210570000303160317031705700003034b03210743035b000003190332072c02000000020311020000000b0743036801000000000327057000040321071f0005020000000203210570000503160316051f020000000203160329072f020000000e0723036e03620743036200000342020000000005700002051f020000000d0321051f020000000203170316034c03200342051f0200000004032103160346071f00050200000002032105700005031603160350051f020000000d0321051f020000000203170316034c0320034203210317031603170317071f00040200000002032105700004031603170317034c034b03210743035b000003190332072c02000000020311020000000b0743036801000000000327051f020000000403210317051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c03420342051f020000000d0321051f020000000203160317034c0320034c034203210317031703170316071f00020200000002032105700002034c034b03210743035b000003190332072c02000000020311020000000b0743036801000000000327051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c034203210317031703170317071f00030200000002032105700003034c034b051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342071f000302000000020321057000030316031703160555036c072f020000000403170327020000000005700003034f034d051f020000005f051f020000000d051f02000000060316031703160321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a000005700003057000040342034903540342034d053d036d034c031b034c031b03420200000981072e020000049c051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e03270200000000032103170317034003190337072c0200000000020000002807430368010000001d4e4f572069732067726561746572207468616e20646561646c696e652e03270743036a000003130319032a072c0200000000020000002c074303680100000021416d6f756e74206d7573742062652067726561746572207468616e207a65726f2e032703210317031607430362000003190337072c0200000000020000003507430368010000002a6d696e546f6b656e73426f75676874206d7573742062652067726561746572207468616e207a65726f2e0327051f020000004d032103170317031703170743036a000003190337072c0200000000020000002d07430368010000002278747a506f6f6c206d7573742062652067726561746572207468616e207a65726f2e0327051f020000004e0321031703170317031607430362000003190337072c0200000000020000002e074303680100000023746f6b656e506f6f6c206d7573742062652067726561746572207468616e207a65726f0327051f02000000020321034c0317031703170317051f02000000060743036a00010322072f020000000b0743036801000000000327020000000203160743036200a80f033a0313051f02000000060743036a00010322072f020000000b0743036801000000000327020000000203160321051f020000000b0743036200a50f033a03120743036200a50f033a071f000302000000020321057000030317031703170316033a0322072f020000001507430368010000000a64697642795a65726f2e0327020000000203160321051f0200000052051f020000000603210317031603190328072c0200000000020000003507430368010000002a746f6b656e73426f75676874206973206c657373207468616e206d696e546f6b656e73426f756768742e03270321071f000302000000020321057000030317031703170316034b03210743035b000003190332072c02000000020311020000000b0743036801000000000327051f020000000405700002051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c03420321031703170317031703130312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342051f020000000d051f02000000060316034903540321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a0000057000030570000505700005051f020000000203420342034d051f0200000004053d036d031b034202000004d9051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000321031703170317034003190337072c0200000000020000002807430368010000001d4e4f572069732067726561746572207468616e20646561646c696e652e03270743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327051f020000004d032103170317031703170743036a000003190337072c0200000000020000002d07430368010000002278747a506f6f6c206d7573742062652067726561746572207468616e207a65726f2e0327051f020000004e0321031703170317031607430362000003190337072c0200000000020000002e074303680100000023746f6b656e506f6f6c206d7573742062652067726561746572207468616e207a65726f032703210317031607430362000003190337072c0200000000020000001d074303680100000012746f6b656e73536f6c64206973207a65726f032703210317031703160743036a000003190337072c020000000002000000320743036801000000276d696e58747a426f75676874206d7573742062652067726561746572207468616e207a65726f2e03270321031703160743036200a50f033a071f0002020000000203210570000203170317031703160743036200a80f033a0312051f02000000020321034c031703160743036200a50f033a071f000302000000020321057000030317031703170317051f02000000060743036a00010322072f020000000b074303680100000000032702000000020316033a0322072f020000001507430368010000000a64697642795a65726f2e0327020000000203160743036a0001033a0321051f020000004e051f0200000008032103170317031603190328072c0200000000020000002f07430368010000002478747a426f75676874206973206c657373207468616e206d696e58747a426f756768742e0327051f0200000092034c03210317031703170316071f00020200000002032105700002031703160312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c03420321051f0200000088051f020000000a03210317031703170317034c034b051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342071f00020200000002032105700002031603170555036c072f02000000020327020000000005700001034f034d051f020000006a051f0200000011032103170316051f0200000004031603160321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a0000057000030349035405700005051f020000000203420342034d053d036d05700002031b034c031b03420200000c33072e0200000841072e02000004f1051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e03270321031703170317034003190337072c0200000000020000002807430368010000001d4e4f572069732067726561746572207468616e20646561646c696e652e0327032103170317031607430362000003190337072c0200000000020000001d074303680100000012746f6b656e73536f6c64206973207a65726f0327032103160317031607430362000003190337072c0200000000020000003507430368010000002a6d696e546f6b656e73426f75676874206d7573742062652067726561746572207468616e207a65726f2e0327051f020000004d032103170317031703170743036a000003190337072c0200000000020000002d07430368010000002278747a506f6f6c206d7573742062652067726561746572207468616e207a65726f2e0327051f020000004e0321031703170317031607430362000003190337072c0200000000020000002e074303680100000023746f6b656e506f6f6c206d7573742062652067726561746572207468616e207a65726f032703210317031703160743036200a50f033a071f0002020000000203210570000203170317031703160743036200a80f033a0312051f02000000020321034c0317031703160743036200a50f033a071f000302000000020321057000030317031703170317051f02000000060743036a00010322072f020000000b074303680100000000032702000000020316033a0322072f020000001507430368010000000a64697642795a65726f2e0327020000000203160743036a0001033a051f02000000020321034c031703170316071f0003020000000203210570000303170317031703160312051f020000000405700002051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c034203210317031703170317071f00020200000002032105700002034c034b051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342071f000202000000020321057000020316031606550765036e07650362036b0000000b2578747a546f546f6b656e072f020000000403170327020000000005700002071f00030200000002032105700003032103170316051f02000000190321031603170316051f0200000008032103170317031703420342034c0320034d034c051f0200000017034c0321031703170316051f02000000060316031703170321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a0000057000030349035405700005051f020000000203420342034d053d036d034c031b051f0200000002034c034c031b03420200000344072e02000001720743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327031e0354034803190325072c02000000000200000020074303680100000015756e73616665557064617465546f6b656e506f6f6c03270321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000321031707430359030a051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203170316034c032003420342051f020000000d0321051f020000000203160317034c0320034c03420321031703170316031706550765036e055a03620000000b2567657442616c616e6365072f02000000040317032702000000000743036a000004490000001825757064617465546f6b656e506f6f6c496e7465726e616c034903540342034d051f0200000004053d036d031b034202000001c60743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327051f02000000020321034c031703160316072c0200000000020000003207430368010000002744657874657220646964206e6f7420696e6974696174652074686973206f7065726174696f6e2e0327051f02000000020321034c0317031703160317034803190325072c0200000000020000004e0743036801000000435468652073656e646572206973206e6f742074686520746f6b656e20636f6e7472616374206173736f6369617465642077697468207468697320636f6e74726163742e0327051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c034203210317074303590303051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203170316034c032003420342051f020000000d0321051f020000000203160317034c0320034c0342053d036d034202000003e6072e02000001bd051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327051f02000000020321034c0317031703160316034803190325072c0200000000020000002e07430368010000002373656e646572206973206e6f742074686520636f6e7472616374206d616e616765722e0327051f02000000020321034c0317031603170316033f072c0200000000020000003d07430368010000003243616e6e6f74206368616e6765207468652062616b6572207768696c6520667265657a6542616b657220697320747275652e032703210316051f02000000020317034e051f0200000073051f020000000403210317051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c03420342051f020000000d0321051f020000000203160317034c0320034c0342053d036d031b0342020000021d072e0200000147051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327051f02000000020321034c0317031703160316034803190325072c0200000000020000002e07430368010000002373656e646572206973206e6f742074686520636f6e7472616374206d616e616765722e0327051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203170316034c032003420342034c0342051f020000000d0321051f020000000203160317034c0320034c0342053d036d034202000000ca03200321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000321031703170317031703130312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342053d036d0342"; @@ -113,7 +170,26 @@ let exprubv5oQmAUP8BwktmDgMWqTizYDJVhzHhJESGZhJ2GkHESZ1VWg = legacy_script_hash = Script_expr_hash.of_b58check_exn "exprubv5oQmAUP8BwktmDgMWqTizYDJVhzHhJESGZhJ2GkHESZ1VWg"; + addresses = ["KT1CT7S2b9hXNRxRrEcany9sak1qe4aaFAZJ"]; patched_code = bin_expr_exn "0200002bf705000764076407640865046e000000083a7370656e646572076504620000000a3a616c6c6f77616e63650462000000113a63757272656e74416c6c6f77616e63650000000825617070726f766508650765046e000000063a6f776e657204620000000d3a6d696e4c71744d696e74656407650462000000133a6d6178546f6b656e734465706f7369746564046b000000093a646561646c696e650000000d256164644c6971756964697479076408650765046e000000063a6f776e65720765046e000000033a746f04620000000a3a6c71744275726e65640765046a000000103a6d696e58747a57697468647261776e07650462000000133a6d696e546f6b656e7357697468647261776e046b000000093a646561646c696e65000000102572656d6f76654c697175696469747907640865046e000000033a746f07650462000000103a6d696e546f6b656e73426f75676874046b000000093a646561646c696e650000000b2578747a546f546f6b656e08650765046e000000063a6f776e6572046e000000033a746f076504620000000b3a746f6b656e73536f6c640765046a0000000d3a6d696e58747a426f75676874046b000000093a646561646c696e650000000b25746f6b656e546f58747a0764076408650765046e000000153a6f7574707574446578746572436f6e747261637407650462000000103a6d696e546f6b656e73426f75676874046e000000063a6f776e65720765046e000000033a746f076504620000000b3a746f6b656e73536f6c64046b000000093a646561646c696e650000000d25746f6b656e546f546f6b656e0764045d0000001025757064617465546f6b656e506f6f6c04620000001825757064617465546f6b656e506f6f6c496e7465726e616c076408650563035d0359000000092573657442616b65720764046e0000000b257365744d616e61676572046c000000082564656661756c74050107650861046e000000063a6f776e657207650462000000083a62616c616e63650760046e000000083a7370656e64657204620000000a3a616c6c6f77616e636500000009256163636f756e7473076507650459000000183a73656c6649735570646174696e67546f6b656e506f6f6c076504590000000c3a667265657a6542616b65720462000000093a6c7174546f74616c07650765046e000000083a6d616e61676572046e0000000d3a746f6b656e41646472657373076504620000000a3a746f6b656e506f6f6c046a000000083a78747a506f6f6c05020200002854055707650764076407640765036e07650362036207650765036e036207650362036b076407650765036e0765036e03620765036a07650362036b07640765036e07650362036b07650765036e036e076503620765036a036b0764076407650765036e07650362036e0765036e07650362036b0764035d0362076407650563035d03590764036e036c07650761036e076503620760036e036207650765035907650359036207650765036e036e07650362036a03210316051f02000000020317072e0200001c3a072e0200000b8d072e02000001c1051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327051f02000000020321034c031603480329072f020000000e0723036e03620743036200000342020000000003210317071f0002020000000203210570000203160329072f02000000060743036200000200000000071f000202000000020321057000020317031703190325072c020000000002000000630743036801000000585468652063757272656e7420616c6c6f77616e636520706172616d65746572206d75737420657175616c207468652073656e64657227732063757272656e7420616c6c6f77616e636520666f7220746865206f776e65722e0327032103170570000203210316051f02000000060317031603460350051f020000000d0321051f020000000203160317034c0320034c0342051f020000000403210316034603480350051f020000000d0321051f020000000203170316034c03200342053d036d034202000009c0051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e03270200000000032103170317034003190337072c0200000000020000002807430368010000001d4e4f572069732067726561746572207468616e20646561646c696e652e032703210317031607430362000003190337072c0200000000020000003807430368010000002d6d6178546f6b656e734465706f7369746564206d7573742062652067726561746572207468616e207a65726f2e032703210316031707430362000003190337072c020000000002000000320743036801000000276d696e4c71744d696e746564206d7573742062652067726561746572207468616e207a65726f2e032703130743036a000003190337072c0200000000020000004607430368010000003b54686520616d6f756e74206f662058545a2073656e7420746f20446578746572206d7573742062652067726561746572207468616e207a65726f2e0327051f02000000020321034c031703160317031703300325072c020000032f03130743036a0080897a03190332072c0200000000020000004f07430368010000004454686520696e697469616c206c697175696469747920616d6f756e74206d7573742062652067726561746572207468616e206f7220657175616c20746f20312058545a2e0327034c0313051f02000000060743036a00010322072f020000000b0743036801000000000327020000000203160321051f0200000071051f020000000403210317051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c03420342051f020000000d0321051f020000000203160317034c0320034c0342034c071f0002020000000203210570000203160316051f0200000004032103160329072f020000000e0723036e03620743036200000342020000000005700002051f020000000d0321051f020000000203170316034c03200342051f0200000004032103160346071f00030200000002032105700003031603160350051f020000000d0321051f020000000203170316034c032003420321031703170317031703130312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c034203210317031703170316071f00020200000002032105700002031703160312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342051f0200000011032103170316051f0200000004031603160321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a0000057000030349035405700005051f020000000203420342034d051f0200000004053d036d031b034202000004e6051f02000000020321034c0317031703170317051f02000000060743036a00010322072f020000000b0743036801000000000327020000000203160313051f02000000060743036a00010322072f020000000b0743036801000000000327020000000203160321071f000402000000020321057000040317031703170316033a071f00020200000002032105700002034c0322072f020000001507430368010000000a64697642795a65726f2e0327020000002703210316051f02000000020317034c03300325072c020000000002000000080743036200010312032107430362000003190337072c02000000000200000023074303680100000018746f6b656e734465706f7369746564206973207a65726f2e0327034c071f000402000000020321057000040317031603170317033a051f0200000002034c0322072f0200000002032702000000020316071f0002020000000203210570000203160317051f0200000002032103190332072c020000000002000000430743036801000000386c71744d696e746564206d7573742062652067726561746572207468616e206f7220657175616c20746f206d696e4c71744d696e7465642e0327051f0200000066051f02000000020321034c03170316051f0200000002032103190328072c0200000000020000003e074303680100000033746f6b656e734465706f73697465642069732067726561746572207468616e206d6178546f6b656e734465706f73697465642e0327071f00030200000002032105700003071f0003020000000203210570000303160316051f020000000203160329072f020000000e0723036e03620743036200000342020000000003210316071f000202000000020321057000020312051f020000000d0321051f020000000203170316034c032003420346071f0003020000000203210570000303160316051f020000000f051f020000000805700003032103160350051f020000000d0321051f020000000203170316034c0320034203210317031603170317057000020312051f020000000403210317051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c03420342051f020000000d0321051f020000000203160317034c0320034c03420321031703170317031703130312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c034203210317031703170316071f000202000000020321057000020312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342051f020000000b051f0200000004031603160321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a0000057000030349035405700005051f020000000203420342034d051f0200000004053d036d031b034202000010a1072e02000008e5051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e03270321031703170317034003190337072c0200000000020000002807430368010000001d4e4f572069732067726561746572207468616e20646561646c696e652e03270321031703160743036a000003190337072c0200000000020000003507430368010000002a6d696e58747a57697468647261776e206d7573742062652067726561746572207468616e207a65726f2e0327032103170317031607430362000003190337072c0200000000020000003807430368010000002d6d696e546f6b656e7357697468647261776e206d7573742062652067726561746572207468616e207a65726f2e0327032103160317031707430362000003190337072c0200000000020000002f0743036801000000246c71744275726e6564206d7573742062652067726561746572207468616e207a65726f2e0327032103160316051f020000000d051f02000000020321034c03160329072f02000000220743036801000000176f776e657220686173206e6f206c69717569646974792e03270200000000034c0321031603170317071f00020200000002032105700002031603190328072c0200000000020000003507430368010000002a6c71744275726e65642069732067726561746572207468616e206f776e657227732062616c616e63652e0327032103160316034803190325072c0200000004034c03160200000132034c0321031703480329072f020000002a07430368010000001f73656e64657220686173206e6f20617070726f76616c2062616c616e63652e03270200000000051f0200000017034c0321031603170317051f02000000060743035b0000034b0321051f020000004b03190328072c0200000000020000003b07430368010000003073656e64657220617070726f76616c2062616c616e6365206973206c657373207468616e204c5154206275726e65642e03270311034605700002032103170570000203480350051f020000000d0321051f020000000203160317034c0320034c034203210316051f0200000043034605710001032103160316034c051f020000002e051f020000000b051f0200000004032103160350051f020000000d0321051f020000000203170316034c03200342051f02000000020321034c031603170317071f000302000000020321057000030317031703170317051f02000000060743036a00010322072f020000000b074303680100000000032702000000020316033a051f0200000017071f0002020000000203210570000203170316031703170322072f020000001507430368010000000a64697642795a65726f2e0327020000000203160743036a0001033a0321071f000302000000020321057000030317031603190332072c0200000000020000003507430368010000002a78747a57697468647261776e206973206c657373207468616e206d696e58747a57697468647261776e2e0327071f00020200000002032105700002031603170317051f0200000023071f0003020000000203210570000303210317031603170317034c0317031703170316033a0322072f020000001507430368010000000a64697642795a65726f2e0327020000000203160321071f0004020000000203210570000403170317031603190332072c0200000000020000003b074303680100000030746f6b656e7357697468647261776e206973206c657373207468616e206d696e546f6b656e7357697468647261776e2e0327071f0003020000000203210570000303160317031705700003034b03210743035b000003190332072c02000000020311020000000b0743036801000000000327057000040321071f0005020000000203210570000503160316051f020000000203160329072f020000000e0723036e03620743036200000342020000000005700002051f020000000d0321051f020000000203170316034c03200342051f0200000004032103160346071f00050200000002032105700005031603160350051f020000000d0321051f020000000203170316034c0320034203210317031603170317071f00040200000002032105700004031603170317034c034b03210743035b000003190332072c02000000020311020000000b0743036801000000000327051f020000000403210317051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c03420342051f020000000d0321051f020000000203160317034c0320034c034203210317031703170316071f00020200000002032105700002034c034b03210743035b000003190332072c02000000020311020000000b0743036801000000000327051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c034203210317031703170317071f00030200000002032105700003034c034b051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342071f000302000000020321057000030316031703160555036c072f020000000403170327020000000005700003034f034d051f020000005f051f020000000d051f02000000060316031703160321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a000005700003057000040342034903540342034d053d036d034c031b034c031b034202000007b0072e02000003af051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e03270200000000032103170317034003190337072c0200000000020000002807430368010000001d4e4f572069732067726561746572207468616e20646561646c696e652e032703210317031607430362000003190337072c0200000000020000003507430368010000002a6d696e546f6b656e73426f75676874206d7573742062652067726561746572207468616e207a65726f2e0327051f02000000020321034c0317031703170317051f02000000060743036a00010322072f020000000b0743036801000000000327020000000203160743036200a80f033a0313051f02000000060743036a00010322072f020000000b0743036801000000000327020000000203160321051f020000000b0743036200a50f033a03120743036200a50f033a071f000302000000020321057000030317031703170316033a0322072f020000001507430368010000000a64697642795a65726f2e0327020000000203160321051f0200000052051f020000000603210317031603190328072c0200000000020000003507430368010000002a746f6b656e73426f75676874206973206c657373207468616e206d696e546f6b656e73426f756768742e03270321071f000302000000020321057000030317031703170316034b03210743035b000003190332072c02000000020311020000000b0743036801000000000327051f020000000405700002051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c03420321031703170317031703130312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342051f020000000d051f02000000060316034903540321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a0000057000030570000505700005051f020000000203420342034d051f0200000004053d036d031b034202000003f5051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e032703210317031703160743036a000003190337072c020000000002000000320743036801000000276d696e58747a426f75676874206d7573742062652067726561746572207468616e207a65726f2e03270321031703170317034003190337072c0200000000020000002807430368010000001d4e4f572069732067726561746572207468616e20646561646c696e652e03270321031703160743036200a50f033a071f0002020000000203210570000203170317031703160743036200a80f033a0312051f02000000020321034c031703160743036200a50f033a071f000302000000020321057000030317031703170317051f02000000060743036a00010322072f020000000b074303680100000000032702000000020316033a0322072f020000001507430368010000000a64697642795a65726f2e0327020000000203160743036a0001033a0321051f020000004e051f0200000008032103170317031603190328072c0200000000020000002f07430368010000002478747a426f75676874206973206c657373207468616e206d696e58747a426f756768742e0327051f0200000092034c03210317031703170316071f00020200000002032105700002031703160312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c03420321051f0200000088051f020000000a03210317031703170317034c034b051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342071f00020200000002032105700002031603170555036c072f02000000020327020000000005700001034f034d051f020000006a051f0200000011032103170316051f0200000004031603160321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a0000057000030349035405700005051f020000000203420342034d053d036d034c031b034c031b03420200000b4f072e020000075d072e020000040d051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e03270321031703170317034003190337072c0200000000020000002807430368010000001d4e4f572069732067726561746572207468616e20646561646c696e652e0327032103160317031607430362000003190337072c0200000000020000003507430368010000002a6d696e546f6b656e73426f75676874206d7573742062652067726561746572207468616e207a65726f2e032703210317031703160743036200a50f033a071f0002020000000203210570000203170317031703160743036200a80f033a0312051f02000000020321034c0317031703160743036200a50f033a071f000302000000020321057000030317031703170317051f02000000060743036a00010322072f020000000b074303680100000000032702000000020316033a0322072f020000001507430368010000000a64697642795a65726f2e0327020000000203160743036a0001033a051f02000000020321034c031703170316071f0003020000000203210570000303170317031703160312051f020000000405700002051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c034203210317031703170317071f00020200000002032105700002034c034b051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342071f000202000000020321057000020316031606550765036e07650362036b0000000b2578747a546f546f6b656e072f020000000403170327020000000005700002071f00030200000002032105700003032103170316051f02000000190321031603170316051f0200000008032103170317031703420342034c0320034d034c051f0200000017034c0321031703170316051f02000000060316031703170321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a0000057000030349035405700005051f020000000203420342034d053d036d034c031b051f0200000002034c034c031b03420200000344072e02000001720743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327031e0354034803190325072c02000000000200000020074303680100000015756e73616665557064617465546f6b656e506f6f6c03270321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000321031707430359030a051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203170316034c032003420342051f020000000d0321051f020000000203160317034c0320034c03420321031703170316031706550765036e055a03620000000b2567657442616c616e6365072f02000000040317032702000000000743036a000004490000001825757064617465546f6b656e506f6f6c496e7465726e616c034903540342034d051f0200000004053d036d031b034202000001c60743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327051f02000000020321034c031703160316072c0200000000020000003207430368010000002744657874657220646964206e6f7420696e6974696174652074686973206f7065726174696f6e2e0327051f02000000020321034c0317031703160317034803190325072c0200000000020000004e0743036801000000435468652073656e646572206973206e6f742074686520746f6b656e20636f6e7472616374206173736f6369617465642077697468207468697320636f6e74726163742e0327051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c034203210317074303590303051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203170316034c032003420342051f020000000d0321051f020000000203160317034c0320034c0342053d036d034202000003e6072e02000001bd051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327051f02000000020321034c0317031703160316034803190325072c0200000000020000002e07430368010000002373656e646572206973206e6f742074686520636f6e7472616374206d616e616765722e0327051f02000000020321034c0317031603170316033f072c0200000000020000003d07430368010000003243616e6e6f74206368616e6765207468652062616b6572207768696c6520667265657a6542616b657220697320747275652e032703210316051f02000000020317034e051f0200000073051f020000000403210317051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c03420342051f020000000d0321051f020000000203160317034c0320034c0342053d036d031b0342020000021d072e0200000147051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327051f02000000020321034c0317031703160316034803190325072c0200000000020000002e07430368010000002373656e646572206973206e6f742074686520636f6e7472616374206d616e616765722e0327051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203170316034c032003420342034c0342051f020000000d0321051f020000000203160317034c0320034c0342053d036d034202000000ca03200321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000321031703170317031703130312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342053d036d0342"; } + +let patches = + [ + exprtgpMFzTtyg1STJqANLQsjsMXmkf8UuJTuczQh8GPtqfw18x6Lc; + exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw; + expruqNpURkmjQk5RGHjLrnS1U3DZnEsQCvQQNLSpN1powRmJeQgoJ; + expruwujdJkc5y4iPzr83Sd3KrJhzxSUb67JdCZmXNKiTTNvEkMrRU; + expruZKjVy3JbWcJmjtnvMGvRamkDhMgM3urGGdne3pkN9VKgK7VnD; + exprv98vtze1uwbDXdpb27R8RQabWZMZDXGNAwaAZwCg6WSvXu8fw3; + expru1ukk6ZqdA32rFYFG7j1eGjfsatbdUZWz8Mi1kXWZYRZm4FZVe; + exprubv5oQmAUP8BwktmDgMWqTizYDJVhzHhJESGZhJ2GkHESZ1VWg; + ] + +let addresses_to_patch = + List.concat_map + (fun {legacy_script_hash; patched_code; addresses} -> + List.map (fun addr -> (addr, legacy_script_hash, patched_code)) addresses) + patches diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_patched_contracts.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_patched_contracts.ml index c866b36cc5..a07394f210 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_patched_contracts.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_patched_contracts.ml @@ -33,132 +33,163 @@ open Tezos_micheline open Protocol -open Legacy_script_patches_for_J + +module type LEGACY_SCRIPT_PATCHES = sig + type t + + val script_hash : t -> Script_expr_hash.t + + val code : t -> Michelson_v1_primitives.prim Micheline.canonical + + val patches : t list +end + +module type LEGACY_PATCH_TESTS = sig + type t + + val tests : t -> unit Alcotest_lwt.test_case list +end let script_hash_testable = Alcotest.testable Script_expr_hash.pp Script_expr_hash.equal -let patched_contracts = - [ - exprtgpMFzTtyg1STJqANLQsjsMXmkf8UuJTuczQh8GPtqfw18x6Lc; - exprucjN3PgUnqQHFXQmemT44DjkacU35NrSSKyz18JSSjJB9vtUEw; - expruqNpURkmjQk5RGHjLrnS1U3DZnEsQCvQQNLSpN1powRmJeQgoJ; - expruwujdJkc5y4iPzr83Sd3KrJhzxSUb67JdCZmXNKiTTNvEkMrRU; - expruZKjVy3JbWcJmjtnvMGvRamkDhMgM3urGGdne3pkN9VKgK7VnD; - exprv98vtze1uwbDXdpb27R8RQabWZMZDXGNAwaAZwCg6WSvXu8fw3; - expru1ukk6ZqdA32rFYFG7j1eGjfsatbdUZWz8Mi1kXWZYRZm4FZVe; - exprubv5oQmAUP8BwktmDgMWqTizYDJVhzHhJESGZhJ2GkHESZ1VWg; - ] - -let readable_micheline m = - let open Micheline in - map_node (fun _ -> ()) Michelson_v1_primitives.string_of_prim (root m) - -let contract_path ?(ext = "patched.tz") hash = - Filename.concat "patched_contracts" - @@ Format.asprintf "%a.%s" Script_expr_hash.pp hash ext - -let read_file ?ext hash = - let filename = contract_path ?ext hash in - Lwt_io.(with_file ~mode:Input filename read) - -(* Test that the hashes of the scripts in ./patched_contract/.original.tz - match hashes of the contracts being updated by the migration. *) -let test_original_contract {legacy_script_hash; _} () = - let open Lwt_result_syntax in - let*! code = read_file ~ext:"original.tz" legacy_script_hash in - let michelson = Michelson_v1_parser.parse_toplevel ~check:true code in - let*? prog = Micheline_parser.no_parsing_error michelson in - let bytes = - Data_encoding.Binary.to_bytes_exn - Alpha_context.Script.expr_encoding - prog.expanded - in - Alcotest.check - script_hash_testable - "Expr hash doesn't match" - legacy_script_hash - (Script_expr_hash.hash_bytes [bytes]) ; - return () - -(* Test that the binary-encoded versions of the patched contracts used during the - migration correspond to the content of the `./patched_contracts/.tz` - files *) -let test_patched_contract {legacy_script_hash; patched_code} () = - let open Lwt_result_syntax in - let*! expected_michelson = read_file legacy_script_hash in - let*? program = - Micheline_parser.no_parsing_error - @@ Michelson_v1_parser.parse_toplevel ~check:true expected_michelson - in - match - Micheline_diff.diff - ~prev:(readable_micheline patched_code) - ~current:(readable_micheline program.expanded) - () - with - | Some diff -> - let msg = - Format.asprintf - "Patched code for %a different than expected!\n%a" - Script_expr_hash.pp - legacy_script_hash - Micheline_printer.print_expr - diff - in - Alcotest.fail msg - | None -> return () - -(* Test that the diff files `./patched_contracts/.diff` - are the results of the `diff` command on the corresponding - original and patched files *) -let verify_diff {legacy_script_hash; _} () = - let open Lwt_result_syntax in - let*! expected_diff = read_file ~ext:"diff" legacy_script_hash in - let original_code = contract_path ~ext:"original.tz" legacy_script_hash in - (* The other test asserts that this is indeed the patched code. *) - let current_code = contract_path ~ext:"patched.tz" legacy_script_hash in - let diff_cmd = - ( "", - [| - "diff"; - "-u"; - "--label"; - original_code; - "--label"; - current_code; - original_code; - current_code; - |] ) - in - let*! actual_diff = Lwt_process.pread diff_cmd in - Alcotest.(check string) "same diff" expected_diff actual_diff ; - return () +(** This functor provides testing for legacy script patches. Patches to + be tested should be placed in a module conformal to the signature + [LEGACY_SCRIPT_PATCHES]. It should contain a list of patches and for + each patch it has to provide a hash of the patched contract and the + new code (as Micheline). + + Additionally for each patch 3 files need to be placed in + [patched_contracts] subdirectory: + * script_hash.original.tz – containing the original version of the + script; + * script_hash.patched.tz - containing the patched version; + * script_hash.diff - containing the diff between the two. + + These files are there so that reviewers of the migration can easily + see what changes are made to each contract and these tests make sure + that the patched code supplied in file is identical to the one + included in the migration; and that the diff is correct. *) +module Legacy_patch_test (Patches : LEGACY_SCRIPT_PATCHES) : + LEGACY_PATCH_TESTS with type t = Patches.t = struct + type t = Patches.t + + let readable_micheline m = + let open Micheline in + map_node (fun _ -> ()) Michelson_v1_primitives.string_of_prim (root m) + + let contract_path ?(ext = "patched.tz") hash = + Filename.concat "patched_contracts" + @@ Format.asprintf "%a.%s" Script_expr_hash.pp hash ext + + let read_file ?ext hash = + let filename = contract_path ?ext hash in + Lwt_io.(with_file ~mode:Input filename read) + + (* Test that the hashes of the scripts in ./patched_contract/.original.tz + match hashes of the contracts being updated by the migration. *) + let test_original_contract legacy_script_hash () = + let open Lwt_result_syntax in + let*! code = read_file ~ext:"original.tz" legacy_script_hash in + let michelson = Michelson_v1_parser.parse_toplevel ~check:true code in + let*? prog = Micheline_parser.no_parsing_error michelson in + let bytes = + Data_encoding.Binary.to_bytes_exn + Alpha_context.Script.expr_encoding + prog.expanded + in + Alcotest.check + script_hash_testable + "Expr hash doesn't match" + legacy_script_hash + (Script_expr_hash.hash_bytes [bytes]) ; + return () + + (* Test that the binary-encoded versions of the patched contracts used during the + migration correspond to the content of the `./patched_contracts/.tz` + files *) + let test_patched_contract patch () = + let open Lwt_result_syntax in + let*! expected_michelson = read_file @@ Patches.script_hash patch in + let*? program = + Micheline_parser.no_parsing_error + @@ Michelson_v1_parser.parse_toplevel ~check:true expected_michelson + in + match + Micheline_diff.diff + ~prev:(readable_micheline @@ Patches.code patch) + ~current:(readable_micheline program.expanded) + () + with + | Some diff -> + let msg = + Format.asprintf + "Patched code for %a different than expected!\n%a" + Script_expr_hash.pp + (Patches.script_hash patch) + Micheline_printer.print_expr + diff + in + Alcotest.fail msg + | None -> return () + + (* Test that the diff files `./patched_contracts/.diff` + are the results of the `diff` command on the corresponding + original and patched files *) + let verify_diff legacy_script_hash () = + let open Lwt_result_syntax in + let*! expected_diff = read_file ~ext:"diff" legacy_script_hash in + let original_code = contract_path ~ext:"original.tz" legacy_script_hash in + (* The other test asserts that this is indeed the patched code. *) + let current_code = contract_path ~ext:"patched.tz" legacy_script_hash in + let diff_cmd = + ( "", + [| + "diff"; + "-u"; + "--label"; + original_code; + "--label"; + current_code; + original_code; + current_code; + |] ) + in + let*! actual_diff = Lwt_process.pread diff_cmd in + Alcotest.(check string) "same diff" expected_diff actual_diff ; + return () + + let tests (patch : Patches.t) = + let script_hash = Patches.script_hash patch in + [ + Tztest.tztest + (Format.asprintf + "check original contract hash %a" + Script_expr_hash.pp + script_hash) + `Quick + (test_original_contract script_hash); + Tztest.tztest + (Format.asprintf + "check patched contract %a" + Script_expr_hash.pp + script_hash) + `Quick + (test_patched_contract patch); + Tztest.tztest + (Format.asprintf "verify patch for %a" Script_expr_hash.pp script_hash) + `Quick + (verify_diff script_hash); + ] +end + +(* List modules containing patched scripts here: *) +let test_modules : (module LEGACY_SCRIPT_PATCHES) list = + [(module Legacy_script_patches_for_J)] let tests = List.concat_map - (fun patch -> - [ - Tztest.tztest - (Format.asprintf - "check original contract hash %a" - Script_expr_hash.pp - patch.legacy_script_hash) - `Quick - (test_original_contract patch); - Tztest.tztest - (Format.asprintf - "check patched contract %a" - Script_expr_hash.pp - patch.legacy_script_hash) - `Quick - (test_patched_contract patch); - Tztest.tztest - (Format.asprintf - "verify patch for %a" - Script_expr_hash.pp - patch.legacy_script_hash) - `Quick - (verify_diff patch); - ]) - patched_contracts + (fun (module Patches : LEGACY_SCRIPT_PATCHES) -> + let module Test = Legacy_patch_test (Patches) in + List.concat_map Test.tests Patches.patches) + test_modules From 9d3fd72a89d308fcdf626917c3dde68816e0e2c3 Mon Sep 17 00:00:00 2001 From: Sventimir Date: Thu, 10 Mar 2022 16:09:46 +0100 Subject: [PATCH 068/100] Proto Alpha: Add another test for patched contracts. --- .../michelson/test_patched_contracts.ml | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_patched_contracts.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_patched_contracts.ml index a07394f210..13e5d58f6b 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_patched_contracts.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_patched_contracts.ml @@ -72,6 +72,8 @@ let script_hash_testable = included in the migration; and that the diff is correct. *) module Legacy_patch_test (Patches : LEGACY_SCRIPT_PATCHES) : LEGACY_PATCH_TESTS with type t = Patches.t = struct + open Lwt_result_syntax + type t = Patches.t let readable_micheline m = @@ -89,7 +91,6 @@ module Legacy_patch_test (Patches : LEGACY_SCRIPT_PATCHES) : (* Test that the hashes of the scripts in ./patched_contract/.original.tz match hashes of the contracts being updated by the migration. *) let test_original_contract legacy_script_hash () = - let open Lwt_result_syntax in let*! code = read_file ~ext:"original.tz" legacy_script_hash in let michelson = Michelson_v1_parser.parse_toplevel ~check:true code in let*? prog = Micheline_parser.no_parsing_error michelson in @@ -109,7 +110,6 @@ module Legacy_patch_test (Patches : LEGACY_SCRIPT_PATCHES) : migration correspond to the content of the `./patched_contracts/.tz` files *) let test_patched_contract patch () = - let open Lwt_result_syntax in let*! expected_michelson = read_file @@ Patches.script_hash patch in let*? program = Micheline_parser.no_parsing_error @@ -137,7 +137,6 @@ module Legacy_patch_test (Patches : LEGACY_SCRIPT_PATCHES) : are the results of the `diff` command on the corresponding original and patched files *) let verify_diff legacy_script_hash () = - let open Lwt_result_syntax in let*! expected_diff = read_file ~ext:"diff" legacy_script_hash in let original_code = contract_path ~ext:"original.tz" legacy_script_hash in (* The other test asserts that this is indeed the patched code. *) @@ -159,6 +158,22 @@ module Legacy_patch_test (Patches : LEGACY_SCRIPT_PATCHES) : Alcotest.(check string) "same diff" expected_diff actual_diff ; return () + let typecheck_patched_script code () = + (* Number 3 below controls how much accounts should be + created. This number shouldn't be too small or the context + won't have enough tokens to form a roll. *) + let* (block, _) = Context.init 3 in + let* inc = Incremental.begin_construction block in + let ctxt = Incremental.alpha_ctxt inc in + let* _ = + Lwt.map Environment.wrap_tzresult + @@ Script_ir_translator.parse_code + ~legacy:false + ~code:(Script_repr.lazy_expr code) + ctxt + in + return () + let tests (patch : Patches.t) = let script_hash = Patches.script_hash patch in [ @@ -180,6 +195,10 @@ module Legacy_patch_test (Patches : LEGACY_SCRIPT_PATCHES) : (Format.asprintf "verify patch for %a" Script_expr_hash.pp script_hash) `Quick (verify_diff script_hash); + Tztest.tztest + (Format.asprintf "type check %a" Script_expr_hash.pp script_hash) + `Quick + (typecheck_patched_script @@ Patches.code patch); ] end From 74b29a8ef9046f9bd82bcc5602225ac7c32f6ed8 Mon Sep 17 00:00:00 2001 From: Sventimir Date: Fri, 11 Mar 2022 12:36:13 +0100 Subject: [PATCH 069/100] Proto Alpha: Upgrade the patched contracts to newest Michelson. Some of these scripts used features that were deprecated after the patching has started, so to make them type check, we need to patch them again. --- .../legacy_script_patches_for_J.ml | 6 +-- ...FYFG7j1eGjfsatbdUZWz8Mi1kXWZYRZm4FZVe.diff | 44 ++++++++++++++++--- ...1eGjfsatbdUZWz8Mi1kXWZYRZm4FZVe.patched.tz | 9 ++-- ...jtnvMGvRamkDhMgM3urGGdne3pkN9VKgK7VnD.diff | 10 +++++ ...vRamkDhMgM3urGGdne3pkN9VKgK7VnD.patched.tz | 3 +- ...ktmDgMWqTizYDJVhzHhJESGZhJ2GkHESZ1VWg.diff | 44 ++++++++++++++++--- ...WqTizYDJVhzHhJESGZhJ2GkHESZ1VWg.patched.tz | 9 ++-- .../michelson/test_patched_contracts.ml | 2 +- 8 files changed, 102 insertions(+), 25 deletions(-) diff --git a/src/proto_alpha/lib_protocol/legacy_script_patches_for_J.ml b/src/proto_alpha/lib_protocol/legacy_script_patches_for_J.ml index f4693d11f5..e7355d3ebf 100644 --- a/src/proto_alpha/lib_protocol/legacy_script_patches_for_J.ml +++ b/src/proto_alpha/lib_protocol/legacy_script_patches_for_J.ml @@ -133,7 +133,7 @@ let expruZKjVy3JbWcJmjtnvMGvRamkDhMgM3urGGdne3pkN9VKgK7VnD = addresses = ["KT1BvVxWM6cjFuJNet4R9m64VDCN2iMvjuGE"]; patched_code = bin_expr_exn - "0200001da3050007640764045d0000000d257365745f64656c6567617465046c000000102572656d6f76655f64656c65676174650864046c00000010255f4c69715f656e7472795f6d61696e0764046200000013255f4c69715f656e7472795f73656c6c4f75740764046a00000014255f4c69715f656e7472795f77697468647261770764046c00000013255f4c69715f656e7472795f6465706f7369740865046a000000062573656c6c500765046a000000052562757950046a0000000d25657874726142616c616e6365000000253a707269636555706461746520255f4c69715f656e7472795f757064617465507269636573000000122564656661756c74203a5f656e747269657305010765035d08650860036e0362000000092562616c616e6365730765046800000005256e616d6507650468000000072573796d626f6c076504620000000925646563696d616c73076504620000000c25746f74616c537570706c790765046a0000000825696e42616b65720765046e00000006256f776e65720765046a00000009256275795072696365046a0000000a2573656c6c5072696365000000083a73746f7261676505020200001bef03210316072e02000000b10743036a00000313020000001e020000000403190325072c020000000002000000090200000004034f0327020000000b051f02000000020321034c03170316031e0354034802000000670319033c072c020000002a034807430368010000001b4f6e6c7920746865206f776e65722063616e206f7065726174652e03420327020000002d051f02000000060317053d036d072e02000000080346034e031b0342020000000c0320053e035d034e031b03420200001b2e051f020000000603170321031703420200001af00321051f02000000020317031604210000000a40706172616d65746572072e020000055404580000000c406e6f705f736c6173685f330200000025051f020000001c0200000017051f020000000e0421000000084073746f72616765034c034c042100000006407374617465020000001d0317031703170317031703170317041600000009256275795072696365074303620080897a0313043a00000007406d6963726f730322072f020000001507430368010000000a42616420616d6f756e74032702000004a5044800000005406164647204210000000540616464720555036c072f020000003a07430368010000002f43616e6e6f7420757365207468697320636f6e74726163742066726f6d206e6f6e20756e697420636f6e74726163740327020000043a0200000024051f020000001b0200000016051f020000000d04210000000740616d6f756e74034c034c04160000000740746f6b656e73020000003f051f02000000360200000031051f02000000280200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c034c034c03210416000000092562616c616e636573034c03170321041600000005256e616d65034c031703210416000000072573796d626f6c034c0317032104160000000925646563696d616c73034c03170317020000004e051f02000000450200000040051f02000000370200000032051f02000000290200000024051f020000001b0200000016051f020000000d04210000000740746f6b656e73034c034c034c034c034c0200000093051f020000008a0200000085051f020000007c0200000077051f020000006e0200000069051f0200000060020000005b051f0200000052020000004d051f0200000044020000003f051f02000000360200000031051f02000000280200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c034c034c034c034c034c034c034c034c020000001a031703170317031704160000000c25746f74616c537570706c79031204420000000c25746f74616c537570706c79034c04420000000925646563696d616c73034c0442000000072573796d626f6c034c044200000005256e616d65034c04420000000d407331202562616c616e6365730317020000004d051f0200000044020000003f051f02000000360200000031051f02000000280200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c034c034c034c0416000000092562616c616e636573020000005b051f0200000052020000004d051f0200000044020000003f051f02000000360200000031051f02000000280200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c034c034c034c034c0416000000092562616c616e636573020000004c051f0200000043020000003e051f02000000350200000030051f02000000270200000022051f02000000190200000014051f020000000b0421000000054061646472034c034c034c034c034c0329072f0200000006074303620000020000000004580000000540686176650200000032051f02000000290200000024051f020000001b0200000016051f020000000d04210000000740746f6b656e73034c034c034c0312020000004c051f0200000043020000003e051f02000000350200000030051f02000000270200000022051f02000000190200000014051f020000000b0421000000054061646472034c034c034c034c034c051f02000000020346051f0200000019051f0200000012051f020000000b051f020000000403200320035004420000000d407332202562616c616e636573053d036d0342051f020000000403200320051f0200000004032003200200001568072e02000008d004580000001040616d6f756e745f736c6173685f31340200000025051f020000001c0200000017051f020000000e0421000000084073746f72616765034c034c0743036a0080c0a8ca9a3a0743036a0080897a0200000032051f02000000290200000024051f020000001b0200000016051f020000000d04210000000740616d6f756e74034c034c034c043a00000005407a616d740322072f020000001507430368010000000a62616420616d6f756e740327020000080d04480000000540616464720743036a0000041300000009407478416d6f756e740319033c072c020000003207430368010000002763616e6e6f742062757920616e642073656c6c20696e2073616d65207472616e73616374696f6e032702000007a00200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c0416000000092562616c616e6365730200000014051f020000000b0421000000054061646472034c0329072f0200000006074303620000020000000004580000000540686176650421000000054068617665020000004e051f02000000450200000040051f02000000370200000032051f02000000290200000024051f020000001b0200000016051f020000000d04210000000740616d6f756e74034c034c034c034c034c0319032a072c020000003507430368010000002a546865206164647265737320646f6573206e6f7420686176652074686174206d7563682073746f726564032702000006850200000014051f020000000b0421000000054061646472034c0555036c072f02000000480200000014051f020000000b0421000000054061646472034c07430368010000002243616e6e6f74207265636f76657220626f6f6c20636f6e74726163742066726f6d3a034203270200000614020000004e051f02000000450200000040051f02000000370200000032051f02000000290200000024051f020000001b0200000016051f020000000d04210000000740616d6f756e74034c034c034c034c034c020000004d051f0200000044020000003f051f02000000360200000031051f02000000280200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c034c034c034c020000001a031703170317031704160000000c25746f74616c537570706c79034b03210311034c0328072c020000051c0200000013051f020000000a04210000000440647374034c020000005b051f0200000052020000004d051f0200000044020000003f051f02000000360200000031051f02000000280200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c034c034c034c034c020000001e031703170317031703170317031704170000000a2573656c6c50726963650200000051051f02000000480200000043051f020000003a0200000035051f020000002c0200000027051f020000001e0200000019051f0200000010020000000b051f02000000020321034c034c034c034c034c034c04160000000a406e6f6e4d6963726f73043a0000000740746f53656e64034f044d00000003406f70020000006a051f0200000061020000005c051f0200000053020000004e051f02000000450200000040051f02000000370200000032051f02000000290200000024051f020000001b0200000016051f020000000d04210000000740616d6f756e74034c034c034c034c034c034c034c020000003e051f02000000350200000030051f02000000270200000022051f02000000190200000014051f020000000b0421000000054068617665034c034c034c034c034b03210311034c0328072c020000031b0200000069051f0200000060020000005b051f0200000052020000004d051f0200000044020000003f051f02000000360200000031051f02000000280200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c034c034c034c034c034c03210416000000092562616c616e636573034c03170321041600000005256e616d65034c031703210416000000072573796d626f6c034c0317032104160000000925646563696d616c73034c03170317020000006d051f0200000064020000005f051f02000000560200000051051f02000000480200000043051f020000003a0200000035051f020000002c0200000027051f020000001e0200000019051f020000001004210000000a406e6577537570706c79034c034c034c034c034c034c034c04420000000c25746f74616c537570706c79034c04420000000925646563696d616c73034c0442000000072573796d626f6c034c044200000005256e616d65034c04420000000d407331202562616c616e63657303170200000077051f020000006e0200000069051f0200000060020000005b051f0200000052020000004d051f0200000044020000003f051f02000000360200000031051f02000000280200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c034c034c034c034c034c034c0416000000092562616c616e6365730200000028051f020000001f020000001a051f020000001104210000000b406e657742616c616e6365034c034c0200000076051f020000006d0200000068051f020000005f020000005a051f0200000051020000004c051f0200000043020000003e051f02000000350200000030051f02000000270200000022051f02000000190200000014051f020000000b0421000000054061646472034c034c034c034c034c034c034c034c051f02000000020346051f0200000017051f0200000010051f0200000009051f02000000020320035004420000000d407332202562616c616e636573053d036d0200000019051f0200000010020000000b051f02000000020321034c034c031b0342020000001507430368010000000a62616420616d6f756e740327051f020000000403200320020000001507430368010000000a62616420616d6f756e740327051f02000000020320051f02000000020320051f020000000403200320051f0200000004032003200200000c8c072e020000034f04580000000d40616d745f736c6173685f33330200000025051f020000001c0200000017051f020000000e0421000000084073746f72616765034c034c0743035d0100000024747a314c42454b5861785162643547747a62633141544377633370707075383161574763041e0000000540646573740200000021051f02000000180200000013051f020000000a04210000000440616d74034c034c034f044d00000003406f700200000015051f020000000c042100000006407374617465034c0200000018031703170317031703170317041600000006256f776e657204470000000540616464720319033c072c02000000220743036801000000174f6e6c79206f776e65722063616e207769746864726177032702000002280200000015051f020000000c042100000006407374617465034c03210416000000092562616c616e636573034c03170321041600000005256e616d65034c031703210416000000072573796d626f6c034c0317032104160000000925646563696d616c73034c0317032104160000000c25746f74616c537570706c79034c031703170200000075051f020000006c0200000067051f020000005e0200000059051f0200000050020000004b051f0200000042020000003d051f0200000034020000002f051f02000000260200000021051f02000000180200000013051f020000000a04210000000440616d74034c034c034c034c034c034c034c034c0200000077051f020000006e0200000069051f0200000060020000005b051f0200000052020000004d051f0200000044020000003f051f02000000360200000031051f02000000280200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c034c034c034c034c034c034c02000000180317031703170317031704160000000825696e42616b6572031204420000000825696e42616b6572034c04420000000c25746f74616c537570706c79034c04420000000925646563696d616c73034c0442000000072573796d626f6c034c044200000005256e616d65034c04420000000d407331202562616c616e636573053d036d0200000020051f02000000170200000012051f0200000009042100000003406f70034c034c031b0342051f02000000060320032003200200000931072e020000022504580000000d406e6f705f736c6173685f33390200000025051f020000001c0200000017051f020000000e0421000000084073746f72616765034c034c0421000000064073746174650200000018031703170317031703170317041600000006256f776e657204470000000540616464720319033c072c02000000210743036801000000164f6e6c79206f776e65722063616e206465706f7369740327020000017804210000000640737461746503210416000000092562616c616e636573034c03170321041600000005256e616d65034c031703210416000000072573796d626f6c034c0317032104160000000925646563696d616c73034c0317032104160000000c25746f74616c537570706c79034c0317031704130000000740616d6f756e740200000069051f0200000060020000005b051f0200000052020000004d051f0200000044020000003f051f02000000360200000031051f02000000280200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c034c034c034c034c034c02000000180317031703170317031704160000000825696e42616b6572034b04420000000825696e42616b6572034c04420000000c25746f74616c537570706c79034c04420000000925646563696d616c73034c0442000000072573796d626f6c034c044200000005256e616d65034c04420000000d407331202562616c616e636573053d036d0342051f020000000403200320020000070004580000000e40696e666f5f736c6173685f34340200000025051f020000001c0200000017051f020000000e0421000000084073746f72616765034c034c04210000000640737461746503210416000000092562616c616e636573034c03170321041600000005256e616d65034c031703210416000000072573796d626f6c034c0317032104160000000925646563696d616c73034c0317032104160000000c25746f74616c537570706c79034c0317032104160000000825696e42616b6572034c03170321041600000006256f776e6572034c03170416000000092562757950726963650200000084051f020000007b0200000076051f020000006d0200000068051f020000005f020000005a051f0200000051020000004c051f0200000043020000003e051f02000000350200000030051f02000000270200000022051f02000000190200000014051f020000000b04210000000540696e666f034c034c034c034c034c034c034c034c034c0416000000062573656c6c50034c044200000014256275795072696365202573656c6c5072696365034c044200000006256f776e6572034c04420000000825696e42616b6572034c04420000000c25746f74616c537570706c79034c04420000000925646563696d616c73034c0442000000072573796d626f6c034c044200000005256e616d65034c04420000000d407331202562616c616e63657303210416000000092562616c616e636573034c03170321041600000005256e616d65034c031703210416000000072573796d626f6c034c0317032104160000000925646563696d616c73034c0317032104160000000c25746f74616c537570706c79034c0317032104160000000825696e42616b6572034c03170321041600000006256f776e6572034c031704170000000a2573656c6c50726963650200000084051f020000007b0200000076051f020000006d0200000068051f020000005f020000005a051f0200000051020000004c051f0200000043020000003e051f02000000350200000030051f02000000270200000022051f02000000190200000014051f020000000b04210000000540696e666f034c034c034c034c034c034c034c034c034c020000000d03170416000000052562757950044200000014256275795072696365202573656c6c5072696365034c044200000006256f776e6572034c04420000000825696e42616b6572034c04420000000c25746f74616c537570706c79034c04420000000925646563696d616c73034c0442000000072573796d626f6c034c044200000005256e616d65034c04420000000d407332202562616c616e6365730200000022051f02000000190200000014051f020000000b04210000000540696e666f034c034c0416000000062573656c6c500200000030051f02000000270200000022051f02000000190200000014051f020000000b04210000000540696e666f034c034c034c020000000d0317041600000005256275795003190337072c020000002b074303680100000020696e76616c69642070726963652c20656e61626c6573206172626974726167650327020000026f0200000015051f020000000c042100000006407374617465034c0200000018031703170317031703170317041600000006256f776e657204470000000540616464720319033c072c02000000230743036801000000184f6e6c79206f776e65722063616e20736574207072696365032702000001fa04210000000340733203210416000000092562616c616e636573034c03170321041600000005256e616d65034c031703210416000000072573796d626f6c034c0317032104160000000925646563696d616c73034c0317032104160000000c25746f74616c537570706c79034c031703170200000076051f020000006d0200000068051f020000005f020000005a051f0200000051020000004c051f0200000043020000003e051f02000000350200000030051f02000000270200000022051f02000000190200000014051f020000000b04210000000540696e666f034c034c034c034c034c034c034c034c0200000015031704170000000d25657874726142616c616e63650200000066051f020000005d0200000058051f020000004f020000004a051f0200000041020000003c051f0200000033020000002e051f02000000250200000020051f02000000170200000012051f0200000009042100000003407332034c034c034c034c034c034c034c02000000180317031703170317031704160000000825696e42616b6572031204420000000825696e42616b6572034c04420000000c25746f74616c537570706c79034c04420000000925646563696d616c73034c0442000000072573796d626f6c034c044200000005256e616d65034c04420000000d407333202562616c616e636573053d036d0342051f0200000006032003200320051f020000000403200320034c0316034c0200000012020000000d03210316051f02000000020317051f0200000004034c03420342"; + "0200001dc9050007640764045d0000000d257365745f64656c6567617465046c000000102572656d6f76655f64656c65676174650864046c00000010255f4c69715f656e7472795f6d61696e0764046200000013255f4c69715f656e7472795f73656c6c4f75740764046a00000014255f4c69715f656e7472795f77697468647261770764046c00000013255f4c69715f656e7472795f6465706f7369740865046a000000062573656c6c500765046a000000052562757950046a0000000d25657874726142616c616e6365000000253a707269636555706461746520255f4c69715f656e7472795f757064617465507269636573000000122564656661756c74203a5f656e747269657305010765035d08650860036e0362000000092562616c616e6365730765046800000005256e616d6507650468000000072573796d626f6c076504620000000925646563696d616c73076504620000000c25746f74616c537570706c790765046a0000000825696e42616b65720765046e00000006256f776e65720765046a00000009256275795072696365046a0000000a2573656c6c5072696365000000083a73746f7261676505020200001c1503210316072e02000000b10743036a00000313020000001e020000000403190325072c020000000002000000090200000004034f0327020000000b051f02000000020321034c03170316031e0354034802000000670319033c072c020000002a034807430368010000001b4f6e6c7920746865206f776e65722063616e206f7065726174652e03420327020000002d051f02000000060317053d036d072e02000000080346034e031b0342020000000c0320053e035d034e031b03420200001b54051f020000000603170321031703420200001b160321051f02000000020317031604210000000a40706172616d65746572072e020000055404580000000c406e6f705f736c6173685f330200000025051f020000001c0200000017051f020000000e0421000000084073746f72616765034c034c042100000006407374617465020000001d0317031703170317031703170317041600000009256275795072696365074303620080897a0313043a00000007406d6963726f730322072f020000001507430368010000000a42616420616d6f756e74032702000004a5044800000005406164647204210000000540616464720555036c072f020000003a07430368010000002f43616e6e6f7420757365207468697320636f6e74726163742066726f6d206e6f6e20756e697420636f6e74726163740327020000043a0200000024051f020000001b0200000016051f020000000d04210000000740616d6f756e74034c034c04160000000740746f6b656e73020000003f051f02000000360200000031051f02000000280200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c034c034c03210416000000092562616c616e636573034c03170321041600000005256e616d65034c031703210416000000072573796d626f6c034c0317032104160000000925646563696d616c73034c03170317020000004e051f02000000450200000040051f02000000370200000032051f02000000290200000024051f020000001b0200000016051f020000000d04210000000740746f6b656e73034c034c034c034c034c0200000093051f020000008a0200000085051f020000007c0200000077051f020000006e0200000069051f0200000060020000005b051f0200000052020000004d051f0200000044020000003f051f02000000360200000031051f02000000280200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c034c034c034c034c034c034c034c034c020000001a031703170317031704160000000c25746f74616c537570706c79031204420000000c25746f74616c537570706c79034c04420000000925646563696d616c73034c0442000000072573796d626f6c034c044200000005256e616d65034c04420000000d407331202562616c616e6365730317020000004d051f0200000044020000003f051f02000000360200000031051f02000000280200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c034c034c034c0416000000092562616c616e636573020000005b051f0200000052020000004d051f0200000044020000003f051f02000000360200000031051f02000000280200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c034c034c034c034c0416000000092562616c616e636573020000004c051f0200000043020000003e051f02000000350200000030051f02000000270200000022051f02000000190200000014051f020000000b0421000000054061646472034c034c034c034c034c0329072f0200000006074303620000020000000004580000000540686176650200000032051f02000000290200000024051f020000001b0200000016051f020000000d04210000000740746f6b656e73034c034c034c0312020000004c051f0200000043020000003e051f02000000350200000030051f02000000270200000022051f02000000190200000014051f020000000b0421000000054061646472034c034c034c034c034c051f02000000020346051f0200000019051f0200000012051f020000000b051f020000000403200320035004420000000d407332202562616c616e636573053d036d0342051f020000000403200320051f020000000403200320020000158e072e02000008d004580000001040616d6f756e745f736c6173685f31340200000025051f020000001c0200000017051f020000000e0421000000084073746f72616765034c034c0743036a0080c0a8ca9a3a0743036a0080897a0200000032051f02000000290200000024051f020000001b0200000016051f020000000d04210000000740616d6f756e74034c034c034c043a00000005407a616d740322072f020000001507430368010000000a62616420616d6f756e740327020000080d04480000000540616464720743036a0000041300000009407478416d6f756e740319033c072c020000003207430368010000002763616e6e6f742062757920616e642073656c6c20696e2073616d65207472616e73616374696f6e032702000007a00200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c0416000000092562616c616e6365730200000014051f020000000b0421000000054061646472034c0329072f0200000006074303620000020000000004580000000540686176650421000000054068617665020000004e051f02000000450200000040051f02000000370200000032051f02000000290200000024051f020000001b0200000016051f020000000d04210000000740616d6f756e74034c034c034c034c034c0319032a072c020000003507430368010000002a546865206164647265737320646f6573206e6f7420686176652074686174206d7563682073746f726564032702000006850200000014051f020000000b0421000000054061646472034c0555036c072f02000000480200000014051f020000000b0421000000054061646472034c07430368010000002243616e6e6f74207265636f76657220626f6f6c20636f6e74726163742066726f6d3a034203270200000614020000004e051f02000000450200000040051f02000000370200000032051f02000000290200000024051f020000001b0200000016051f020000000d04210000000740616d6f756e74034c034c034c034c034c020000004d051f0200000044020000003f051f02000000360200000031051f02000000280200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c034c034c034c020000001a031703170317031704160000000c25746f74616c537570706c79034b03210311034c0328072c020000051c0200000013051f020000000a04210000000440647374034c020000005b051f0200000052020000004d051f0200000044020000003f051f02000000360200000031051f02000000280200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c034c034c034c034c020000001e031703170317031703170317031704170000000a2573656c6c50726963650200000051051f02000000480200000043051f020000003a0200000035051f020000002c0200000027051f020000001e0200000019051f0200000010020000000b051f02000000020321034c034c034c034c034c034c04160000000a406e6f6e4d6963726f73043a0000000740746f53656e64034f044d00000003406f70020000006a051f0200000061020000005c051f0200000053020000004e051f02000000450200000040051f02000000370200000032051f02000000290200000024051f020000001b0200000016051f020000000d04210000000740616d6f756e74034c034c034c034c034c034c034c020000003e051f02000000350200000030051f02000000270200000022051f02000000190200000014051f020000000b0421000000054068617665034c034c034c034c034b03210311034c0328072c020000031b0200000069051f0200000060020000005b051f0200000052020000004d051f0200000044020000003f051f02000000360200000031051f02000000280200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c034c034c034c034c034c03210416000000092562616c616e636573034c03170321041600000005256e616d65034c031703210416000000072573796d626f6c034c0317032104160000000925646563696d616c73034c03170317020000006d051f0200000064020000005f051f02000000560200000051051f02000000480200000043051f020000003a0200000035051f020000002c0200000027051f020000001e0200000019051f020000001004210000000a406e6577537570706c79034c034c034c034c034c034c034c04420000000c25746f74616c537570706c79034c04420000000925646563696d616c73034c0442000000072573796d626f6c034c044200000005256e616d65034c04420000000d407331202562616c616e63657303170200000077051f020000006e0200000069051f0200000060020000005b051f0200000052020000004d051f0200000044020000003f051f02000000360200000031051f02000000280200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c034c034c034c034c034c034c0416000000092562616c616e6365730200000028051f020000001f020000001a051f020000001104210000000b406e657742616c616e6365034c034c0200000076051f020000006d0200000068051f020000005f020000005a051f0200000051020000004c051f0200000043020000003e051f02000000350200000030051f02000000270200000022051f02000000190200000014051f020000000b0421000000054061646472034c034c034c034c034c034c034c034c051f02000000020346051f0200000017051f0200000010051f0200000009051f02000000020320035004420000000d407332202562616c616e636573053d036d0200000019051f0200000010020000000b051f02000000020321034c034c031b0342020000001507430368010000000a62616420616d6f756e740327051f020000000403200320020000001507430368010000000a62616420616d6f756e740327051f02000000020320051f02000000020320051f020000000403200320051f0200000004032003200200000cb2072e020000034f04580000000d40616d745f736c6173685f33330200000025051f020000001c0200000017051f020000000e0421000000084073746f72616765034c034c0743035d0100000024747a314c42454b5861785162643547747a62633141544377633370707075383161574763041e0000000540646573740200000021051f02000000180200000013051f020000000a04210000000440616d74034c034c034f044d00000003406f700200000015051f020000000c042100000006407374617465034c0200000018031703170317031703170317041600000006256f776e657204470000000540616464720319033c072c02000000220743036801000000174f6e6c79206f776e65722063616e207769746864726177032702000002280200000015051f020000000c042100000006407374617465034c03210416000000092562616c616e636573034c03170321041600000005256e616d65034c031703210416000000072573796d626f6c034c0317032104160000000925646563696d616c73034c0317032104160000000c25746f74616c537570706c79034c031703170200000075051f020000006c0200000067051f020000005e0200000059051f0200000050020000004b051f0200000042020000003d051f0200000034020000002f051f02000000260200000021051f02000000180200000013051f020000000a04210000000440616d74034c034c034c034c034c034c034c034c0200000077051f020000006e0200000069051f0200000060020000005b051f0200000052020000004d051f0200000044020000003f051f02000000360200000031051f02000000280200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c034c034c034c034c034c034c02000000180317031703170317031704160000000825696e42616b6572031204420000000825696e42616b6572034c04420000000c25746f74616c537570706c79034c04420000000925646563696d616c73034c0442000000072573796d626f6c034c044200000005256e616d65034c04420000000d407331202562616c616e636573053d036d0200000020051f02000000170200000012051f0200000009042100000003406f70034c034c031b0342051f02000000060320032003200200000957072e020000024b04580000000d406e6f705f736c6173685f33390200000025051f020000001c0200000017051f020000000e0421000000084073746f72616765034c034c0421000000064073746174650200000018031703170317031703170317041600000006256f776e657204470000000540616464720319033c072c02000000210743036801000000164f6e6c79206f776e65722063616e206465706f7369740327020000019e04210000000640737461746503210416000000092562616c616e636573034c03170321041600000005256e616d65034c031703210416000000072573796d626f6c034c0317032104160000000925646563696d616c73034c0317032104160000000c25746f74616c537570706c79034c0317031704130000000740616d6f756e740200000069051f0200000060020000005b051f0200000052020000004d051f0200000044020000003f051f02000000360200000031051f02000000280200000023051f020000001a0200000015051f020000000c042100000006407374617465034c034c034c034c034c034c034c02000000180317031703170317031704160000000825696e42616b65720393072f020000001a07430368010000000f6e65676174697665206d7574657a210327020000000004420000000825696e42616b6572034c04420000000c25746f74616c537570706c79034c04420000000925646563696d616c73034c0442000000072573796d626f6c034c044200000005256e616d65034c04420000000d407331202562616c616e636573053d036d0342051f020000000403200320020000070004580000000e40696e666f5f736c6173685f34340200000025051f020000001c0200000017051f020000000e0421000000084073746f72616765034c034c04210000000640737461746503210416000000092562616c616e636573034c03170321041600000005256e616d65034c031703210416000000072573796d626f6c034c0317032104160000000925646563696d616c73034c0317032104160000000c25746f74616c537570706c79034c0317032104160000000825696e42616b6572034c03170321041600000006256f776e6572034c03170416000000092562757950726963650200000084051f020000007b0200000076051f020000006d0200000068051f020000005f020000005a051f0200000051020000004c051f0200000043020000003e051f02000000350200000030051f02000000270200000022051f02000000190200000014051f020000000b04210000000540696e666f034c034c034c034c034c034c034c034c034c0416000000062573656c6c50034c044200000014256275795072696365202573656c6c5072696365034c044200000006256f776e6572034c04420000000825696e42616b6572034c04420000000c25746f74616c537570706c79034c04420000000925646563696d616c73034c0442000000072573796d626f6c034c044200000005256e616d65034c04420000000d407331202562616c616e63657303210416000000092562616c616e636573034c03170321041600000005256e616d65034c031703210416000000072573796d626f6c034c0317032104160000000925646563696d616c73034c0317032104160000000c25746f74616c537570706c79034c0317032104160000000825696e42616b6572034c03170321041600000006256f776e6572034c031704170000000a2573656c6c50726963650200000084051f020000007b0200000076051f020000006d0200000068051f020000005f020000005a051f0200000051020000004c051f0200000043020000003e051f02000000350200000030051f02000000270200000022051f02000000190200000014051f020000000b04210000000540696e666f034c034c034c034c034c034c034c034c034c020000000d03170416000000052562757950044200000014256275795072696365202573656c6c5072696365034c044200000006256f776e6572034c04420000000825696e42616b6572034c04420000000c25746f74616c537570706c79034c04420000000925646563696d616c73034c0442000000072573796d626f6c034c044200000005256e616d65034c04420000000d407332202562616c616e6365730200000022051f02000000190200000014051f020000000b04210000000540696e666f034c034c0416000000062573656c6c500200000030051f02000000270200000022051f02000000190200000014051f020000000b04210000000540696e666f034c034c034c020000000d0317041600000005256275795003190337072c020000002b074303680100000020696e76616c69642070726963652c20656e61626c6573206172626974726167650327020000026f0200000015051f020000000c042100000006407374617465034c0200000018031703170317031703170317041600000006256f776e657204470000000540616464720319033c072c02000000230743036801000000184f6e6c79206f776e65722063616e20736574207072696365032702000001fa04210000000340733203210416000000092562616c616e636573034c03170321041600000005256e616d65034c031703210416000000072573796d626f6c034c0317032104160000000925646563696d616c73034c0317032104160000000c25746f74616c537570706c79034c031703170200000076051f020000006d0200000068051f020000005f020000005a051f0200000051020000004c051f0200000043020000003e051f02000000350200000030051f02000000270200000022051f02000000190200000014051f020000000b04210000000540696e666f034c034c034c034c034c034c034c034c0200000015031704170000000d25657874726142616c616e63650200000066051f020000005d0200000058051f020000004f020000004a051f0200000041020000003c051f0200000033020000002e051f02000000250200000020051f02000000170200000012051f0200000009042100000003407332034c034c034c034c034c034c034c02000000180317031703170317031704160000000825696e42616b6572031204420000000825696e42616b6572034c04420000000c25746f74616c537570706c79034c04420000000925646563696d616c73034c0442000000072573796d626f6c034c044200000005256e616d65034c04420000000d407333202562616c616e636573053d036d0342051f0200000006032003200320051f020000000403200320034c0316034c0200000012020000000d03210316051f02000000020317051f0200000004034c03420342"; } let exprv98vtze1uwbDXdpb27R8RQabWZMZDXGNAwaAZwCg6WSvXu8fw3 = @@ -162,7 +162,7 @@ let expru1ukk6ZqdA32rFYFG7j1eGjfsatbdUZWz8Mi1kXWZYRZm4FZVe = ]; patched_code = bin_expr_exn - "0200002e9205000764076407640865046e000000083a7370656e646572076504620000000a3a616c6c6f77616e63650462000000113a63757272656e74416c6c6f77616e63650000000825617070726f766508650765046e000000063a6f776e657204620000000d3a6d696e4c71744d696e74656407650462000000133a6d6178546f6b656e734465706f7369746564046b000000093a646561646c696e650000000d256164644c6971756964697479076408650765046e000000063a6f776e65720765046e000000033a746f04620000000a3a6c71744275726e65640765046a000000103a6d696e58747a57697468647261776e07650462000000133a6d696e546f6b656e7357697468647261776e046b000000093a646561646c696e65000000102572656d6f76654c697175696469747907640865046e000000033a746f07650462000000103a6d696e546f6b656e73426f75676874046b000000093a646561646c696e650000000b2578747a546f546f6b656e08650765046e000000063a6f776e6572046e000000033a746f076504620000000b3a746f6b656e73536f6c640765046a0000000d3a6d696e58747a426f75676874046b000000093a646561646c696e650000000b25746f6b656e546f58747a0764076408650765046e000000153a6f7574707574446578746572436f6e747261637407650462000000103a6d696e546f6b656e73426f75676874046e000000063a6f776e65720765046e000000033a746f076504620000000b3a746f6b656e73536f6c64046b000000093a646561646c696e650000000d25746f6b656e546f546f6b656e0764045d0000001025757064617465546f6b656e506f6f6c04620000001825757064617465546f6b656e506f6f6c496e7465726e616c076408650563035d0359000000092573657442616b65720764046e0000000b257365744d616e61676572046c000000082564656661756c74050107650861046e000000063a6f776e657207650462000000083a62616c616e63650760046e000000083a7370656e64657204620000000a3a616c6c6f77616e636500000009256163636f756e7473076507650459000000183a73656c6649735570646174696e67546f6b656e506f6f6c076504590000000c3a667265657a6542616b65720462000000093a6c7174546f74616c07650765046e000000083a6d616e61676572046e0000000d3a746f6b656e41646472657373076504620000000a3a746f6b656e506f6f6c046a000000083a78747a506f6f6c05020200002aef055707650764076407640765036e07650362036207650765036e036207650362036b076407650765036e0765036e03620765036a07650362036b07640765036e07650362036b07650765036e036e076503620765036a036b0764076407650765036e07650362036e0765036e07650362036b0764035d0362076407650563035d03590764036e036c07650761036e076503620760036e036207650765035907650359036207650765036e036e07650362036a03210316051f02000000020317072e0200001df1072e0200000b73072e02000001c1051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327051f02000000020321034c031603480329072f020000000e0723036e03620743036200000342020000000003210317071f0002020000000203210570000203160329072f02000000060743036200000200000000071f000202000000020321057000020317031703190325072c020000000002000000630743036801000000585468652063757272656e7420616c6c6f77616e636520706172616d65746572206d75737420657175616c207468652073656e64657227732063757272656e7420616c6c6f77616e636520666f7220746865206f776e65722e0327032103170570000203210316051f02000000060317031603460350051f020000000d0321051f020000000203160317034c0320034c0342051f020000000403210316034603480350051f020000000d0321051f020000000203170316034c03200342053d036d034202000009a6051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e03270200000000032103170317034003190337072c0200000000020000002807430368010000001d4e4f572069732067726561746572207468616e20646561646c696e652e032703210317031607430362000003190337072c0200000000020000003807430368010000002d6d6178546f6b656e734465706f7369746564206d7573742062652067726561746572207468616e207a65726f2e032703210316031707430362000003190337072c020000000002000000320743036801000000276d696e4c71744d696e746564206d7573742062652067726561746572207468616e207a65726f2e03270743036a000003130319032a072c0200000000020000002c074303680100000021416d6f756e74206d7573742062652067726561746572207468616e207a65726f2e0327051f02000000020321034c031703160317031703300325072c020000032f03130743036a0080897a03190332072c0200000000020000004f07430368010000004454686520696e697469616c206c697175696469747920616d6f756e74206d7573742062652067726561746572207468616e206f7220657175616c20746f20312058545a2e0327034c0313051f02000000060743036a00010322072f020000000b0743036801000000000327020000000203160321051f0200000071051f020000000403210317051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c03420342051f020000000d0321051f020000000203160317034c0320034c0342034c071f0002020000000203210570000203160316051f0200000004032103160329072f020000000e0723036e03620743036200000342020000000005700002051f020000000d0321051f020000000203170316034c03200342051f0200000004032103160346071f00030200000002032105700003031603160350051f020000000d0321051f020000000203170316034c032003420321031703170317031703130312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c034203210317031703170316071f00020200000002032105700002031703160312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342051f0200000011032103170316051f0200000004031603160321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a0000057000030349035405700005051f020000000203420342034d051f0200000004053d036d031b034202000004e6051f02000000020321034c0317031703170317051f02000000060743036a00010322072f020000000b0743036801000000000327020000000203160313051f02000000060743036a00010322072f020000000b0743036801000000000327020000000203160321071f000402000000020321057000040317031703170316033a071f00020200000002032105700002034c0322072f020000001507430368010000000a64697642795a65726f2e0327020000002703210316051f02000000020317034c03300325072c020000000002000000080743036200010312032107430362000003190337072c02000000000200000023074303680100000018746f6b656e734465706f7369746564206973207a65726f2e0327034c071f000402000000020321057000040317031603170317033a051f0200000002034c0322072f0200000002032702000000020316071f0002020000000203210570000203160317051f0200000002032103190332072c020000000002000000430743036801000000386c71744d696e746564206d7573742062652067726561746572207468616e206f7220657175616c20746f206d696e4c71744d696e7465642e0327051f0200000066051f02000000020321034c03170316051f0200000002032103190328072c0200000000020000003e074303680100000033746f6b656e734465706f73697465642069732067726561746572207468616e206d6178546f6b656e734465706f73697465642e0327071f00030200000002032105700003071f0003020000000203210570000303160316051f020000000203160329072f020000000e0723036e03620743036200000342020000000003210316071f000202000000020321057000020312051f020000000d0321051f020000000203170316034c032003420346071f0003020000000203210570000303160316051f020000000f051f020000000805700003032103160350051f020000000d0321051f020000000203170316034c0320034203210317031603170317057000020312051f020000000403210317051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c03420342051f020000000d0321051f020000000203160317034c0320034c03420321031703170317031703130312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c034203210317031703170316071f000202000000020321057000020312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342051f020000000b051f0200000004031603160321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a0000057000030349035405700005051f020000000203420342034d051f0200000004053d036d031b03420200001272072e02000008e5051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000321031703170317034003190337072c0200000000020000002807430368010000001d4e4f572069732067726561746572207468616e20646561646c696e652e03270743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e03270321031703160743036a000003190337072c0200000000020000003507430368010000002a6d696e58747a57697468647261776e206d7573742062652067726561746572207468616e207a65726f2e0327032103170317031607430362000003190337072c0200000000020000003807430368010000002d6d696e546f6b656e7357697468647261776e206d7573742062652067726561746572207468616e207a65726f2e0327032103160317031707430362000003190337072c0200000000020000002f0743036801000000246c71744275726e6564206d7573742062652067726561746572207468616e207a65726f2e0327032103160316051f020000000d051f02000000020321034c03160329072f02000000220743036801000000176f776e657220686173206e6f206c69717569646974792e03270200000000034c0321031603170317071f00020200000002032105700002031603190328072c0200000000020000003507430368010000002a6c71744275726e65642069732067726561746572207468616e206f776e657227732062616c616e63652e0327032103160316034803190325072c0200000004034c03160200000132034c0321031703480329072f020000002a07430368010000001f73656e64657220686173206e6f20617070726f76616c2062616c616e63652e03270200000000051f0200000017034c0321031603170317051f02000000060743035b0000034b0321051f020000004b03190328072c0200000000020000003b07430368010000003073656e64657220617070726f76616c2062616c616e6365206973206c657373207468616e204c5154206275726e65642e03270311034605700002032103170570000203480350051f020000000d0321051f020000000203160317034c0320034c034203210316051f0200000043034605710001032103160316034c051f020000002e051f020000000b051f0200000004032103160350051f020000000d0321051f020000000203170316034c03200342051f02000000020321034c031603170317071f000302000000020321057000030317031703170317051f02000000060743036a00010322072f020000000b074303680100000000032702000000020316033a051f0200000017071f0002020000000203210570000203170316031703170322072f020000001507430368010000000a64697642795a65726f2e0327020000000203160743036a0001033a0321071f000302000000020321057000030317031603190332072c0200000000020000003507430368010000002a78747a57697468647261776e206973206c657373207468616e206d696e58747a57697468647261776e2e0327071f00020200000002032105700002031603170317051f0200000023071f0003020000000203210570000303210317031603170317034c0317031703170316033a0322072f020000001507430368010000000a64697642795a65726f2e0327020000000203160321071f0004020000000203210570000403170317031603190332072c0200000000020000003b074303680100000030746f6b656e7357697468647261776e206973206c657373207468616e206d696e546f6b656e7357697468647261776e2e0327071f0003020000000203210570000303160317031705700003034b03210743035b000003190332072c02000000020311020000000b0743036801000000000327057000040321071f0005020000000203210570000503160316051f020000000203160329072f020000000e0723036e03620743036200000342020000000005700002051f020000000d0321051f020000000203170316034c03200342051f0200000004032103160346071f00050200000002032105700005031603160350051f020000000d0321051f020000000203170316034c0320034203210317031603170317071f00040200000002032105700004031603170317034c034b03210743035b000003190332072c02000000020311020000000b0743036801000000000327051f020000000403210317051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c03420342051f020000000d0321051f020000000203160317034c0320034c034203210317031703170316071f00020200000002032105700002034c034b03210743035b000003190332072c02000000020311020000000b0743036801000000000327051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c034203210317031703170317071f00030200000002032105700003034c034b051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342071f000302000000020321057000030316031703160555036c072f020000000403170327020000000005700003034f034d051f020000005f051f020000000d051f02000000060316031703160321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a000005700003057000040342034903540342034d053d036d034c031b034c031b03420200000981072e020000049c051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e03270200000000032103170317034003190337072c0200000000020000002807430368010000001d4e4f572069732067726561746572207468616e20646561646c696e652e03270743036a000003130319032a072c0200000000020000002c074303680100000021416d6f756e74206d7573742062652067726561746572207468616e207a65726f2e032703210317031607430362000003190337072c0200000000020000003507430368010000002a6d696e546f6b656e73426f75676874206d7573742062652067726561746572207468616e207a65726f2e0327051f020000004d032103170317031703170743036a000003190337072c0200000000020000002d07430368010000002278747a506f6f6c206d7573742062652067726561746572207468616e207a65726f2e0327051f020000004e0321031703170317031607430362000003190337072c0200000000020000002e074303680100000023746f6b656e506f6f6c206d7573742062652067726561746572207468616e207a65726f0327051f02000000020321034c0317031703170317051f02000000060743036a00010322072f020000000b0743036801000000000327020000000203160743036200a80f033a0313051f02000000060743036a00010322072f020000000b0743036801000000000327020000000203160321051f020000000b0743036200a50f033a03120743036200a50f033a071f000302000000020321057000030317031703170316033a0322072f020000001507430368010000000a64697642795a65726f2e0327020000000203160321051f0200000052051f020000000603210317031603190328072c0200000000020000003507430368010000002a746f6b656e73426f75676874206973206c657373207468616e206d696e546f6b656e73426f756768742e03270321071f000302000000020321057000030317031703170316034b03210743035b000003190332072c02000000020311020000000b0743036801000000000327051f020000000405700002051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c03420321031703170317031703130312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342051f020000000d051f02000000060316034903540321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a0000057000030570000505700005051f020000000203420342034d051f0200000004053d036d031b034202000004d9051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000321031703170317034003190337072c0200000000020000002807430368010000001d4e4f572069732067726561746572207468616e20646561646c696e652e03270743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327051f020000004d032103170317031703170743036a000003190337072c0200000000020000002d07430368010000002278747a506f6f6c206d7573742062652067726561746572207468616e207a65726f2e0327051f020000004e0321031703170317031607430362000003190337072c0200000000020000002e074303680100000023746f6b656e506f6f6c206d7573742062652067726561746572207468616e207a65726f032703210317031607430362000003190337072c0200000000020000001d074303680100000012746f6b656e73536f6c64206973207a65726f032703210317031703160743036a000003190337072c020000000002000000320743036801000000276d696e58747a426f75676874206d7573742062652067726561746572207468616e207a65726f2e03270321031703160743036200a50f033a071f0002020000000203210570000203170317031703160743036200a80f033a0312051f02000000020321034c031703160743036200a50f033a071f000302000000020321057000030317031703170317051f02000000060743036a00010322072f020000000b074303680100000000032702000000020316033a0322072f020000001507430368010000000a64697642795a65726f2e0327020000000203160743036a0001033a0321051f020000004e051f0200000008032103170317031603190328072c0200000000020000002f07430368010000002478747a426f75676874206973206c657373207468616e206d696e58747a426f756768742e0327051f0200000092034c03210317031703170316071f00020200000002032105700002031703160312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c03420321051f0200000088051f020000000a03210317031703170317034c034b051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342071f00020200000002032105700002031603170555036c072f02000000020327020000000005700001034f034d051f020000006a051f0200000011032103170316051f0200000004031603160321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a0000057000030349035405700005051f020000000203420342034d053d036d05700002031b034c031b03420200000c33072e0200000841072e02000004f1051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e03270321031703170317034003190337072c0200000000020000002807430368010000001d4e4f572069732067726561746572207468616e20646561646c696e652e0327032103170317031607430362000003190337072c0200000000020000001d074303680100000012746f6b656e73536f6c64206973207a65726f0327032103160317031607430362000003190337072c0200000000020000003507430368010000002a6d696e546f6b656e73426f75676874206d7573742062652067726561746572207468616e207a65726f2e0327051f020000004d032103170317031703170743036a000003190337072c0200000000020000002d07430368010000002278747a506f6f6c206d7573742062652067726561746572207468616e207a65726f2e0327051f020000004e0321031703170317031607430362000003190337072c0200000000020000002e074303680100000023746f6b656e506f6f6c206d7573742062652067726561746572207468616e207a65726f032703210317031703160743036200a50f033a071f0002020000000203210570000203170317031703160743036200a80f033a0312051f02000000020321034c0317031703160743036200a50f033a071f000302000000020321057000030317031703170317051f02000000060743036a00010322072f020000000b074303680100000000032702000000020316033a0322072f020000001507430368010000000a64697642795a65726f2e0327020000000203160743036a0001033a051f02000000020321034c031703170316071f0003020000000203210570000303170317031703160312051f020000000405700002051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c034203210317031703170317071f00020200000002032105700002034c034b051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342071f000202000000020321057000020316031606550765036e07650362036b0000000b2578747a546f546f6b656e072f020000000403170327020000000005700002071f00030200000002032105700003032103170316051f02000000190321031603170316051f0200000008032103170317031703420342034c0320034d034c051f0200000017034c0321031703170316051f02000000060316031703170321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a0000057000030349035405700005051f020000000203420342034d053d036d034c031b051f0200000002034c034c031b03420200000344072e02000001720743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327031e0354034803190325072c02000000000200000020074303680100000015756e73616665557064617465546f6b656e506f6f6c03270321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000321031707430359030a051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203170316034c032003420342051f020000000d0321051f020000000203160317034c0320034c03420321031703170316031706550765036e055a03620000000b2567657442616c616e6365072f02000000040317032702000000000743036a000004490000001825757064617465546f6b656e506f6f6c496e7465726e616c034903540342034d051f0200000004053d036d031b034202000001c60743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327051f02000000020321034c031703160316072c0200000000020000003207430368010000002744657874657220646964206e6f7420696e6974696174652074686973206f7065726174696f6e2e0327051f02000000020321034c0317031703160317034803190325072c0200000000020000004e0743036801000000435468652073656e646572206973206e6f742074686520746f6b656e20636f6e7472616374206173736f6369617465642077697468207468697320636f6e74726163742e0327051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c034203210317074303590303051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203170316034c032003420342051f020000000d0321051f020000000203160317034c0320034c0342053d036d034202000003e6072e02000001bd051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327051f02000000020321034c0317031703160316034803190325072c0200000000020000002e07430368010000002373656e646572206973206e6f742074686520636f6e7472616374206d616e616765722e0327051f02000000020321034c0317031603170316033f072c0200000000020000003d07430368010000003243616e6e6f74206368616e6765207468652062616b6572207768696c6520667265657a6542616b657220697320747275652e032703210316051f02000000020317034e051f0200000073051f020000000403210317051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c03420342051f020000000d0321051f020000000203160317034c0320034c0342053d036d031b0342020000021d072e0200000147051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327051f02000000020321034c0317031703160316034803190325072c0200000000020000002e07430368010000002373656e646572206973206e6f742074686520636f6e7472616374206d616e616765722e0327051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203170316034c032003420342034c0342051f020000000d0321051f020000000203160317034c0320034c0342053d036d034202000000ca03200321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000321031703170317031703130312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342053d036d0342"; + "0200002f0405000764076407640865046e000000083a7370656e646572076504620000000a3a616c6c6f77616e63650462000000113a63757272656e74416c6c6f77616e63650000000825617070726f766508650765046e000000063a6f776e657204620000000d3a6d696e4c71744d696e74656407650462000000133a6d6178546f6b656e734465706f7369746564046b000000093a646561646c696e650000000d256164644c6971756964697479076408650765046e000000063a6f776e65720765046e000000033a746f04620000000a3a6c71744275726e65640765046a000000103a6d696e58747a57697468647261776e07650462000000133a6d696e546f6b656e7357697468647261776e046b000000093a646561646c696e65000000102572656d6f76654c697175696469747907640865046e000000033a746f07650462000000103a6d696e546f6b656e73426f75676874046b000000093a646561646c696e650000000b2578747a546f546f6b656e08650765046e000000063a6f776e6572046e000000033a746f076504620000000b3a746f6b656e73536f6c640765046a0000000d3a6d696e58747a426f75676874046b000000093a646561646c696e650000000b25746f6b656e546f58747a0764076408650765046e000000153a6f7574707574446578746572436f6e747261637407650462000000103a6d696e546f6b656e73426f75676874046e000000063a6f776e65720765046e000000033a746f076504620000000b3a746f6b656e73536f6c64046b000000093a646561646c696e650000000d25746f6b656e546f546f6b656e0764045d0000001025757064617465546f6b656e506f6f6c04620000001825757064617465546f6b656e506f6f6c496e7465726e616c076408650563035d0359000000092573657442616b65720764046e0000000b257365744d616e61676572046c000000082564656661756c74050107650861046e000000063a6f776e657207650462000000083a62616c616e63650760046e000000083a7370656e64657204620000000a3a616c6c6f77616e636500000009256163636f756e7473076507650459000000183a73656c6649735570646174696e67546f6b656e506f6f6c076504590000000c3a667265657a6542616b65720462000000093a6c7174546f74616c07650765046e000000083a6d616e61676572046e0000000d3a746f6b656e41646472657373076504620000000a3a746f6b656e506f6f6c046a000000083a78747a506f6f6c05020200002b61055707650764076407640765036e07650362036207650765036e036207650362036b076407650765036e0765036e03620765036a07650362036b07640765036e07650362036b07650765036e036e076503620765036a036b0764076407650765036e07650362036e0765036e07650362036b0764035d0362076407650563035d03590764036e036c07650761036e076503620760036e036207650765035907650359036207650765036e036e07650362036a03210316051f02000000020317072e0200001e3d072e0200000b73072e02000001c1051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327051f02000000020321034c031603480329072f020000000e0723036e03620743036200000342020000000003210317071f0002020000000203210570000203160329072f02000000060743036200000200000000071f000202000000020321057000020317031703190325072c020000000002000000630743036801000000585468652063757272656e7420616c6c6f77616e636520706172616d65746572206d75737420657175616c207468652073656e64657227732063757272656e7420616c6c6f77616e636520666f7220746865206f776e65722e0327032103170570000203210316051f02000000060317031603460350051f020000000d0321051f020000000203160317034c0320034c0342051f020000000403210316034603480350051f020000000d0321051f020000000203170316034c03200342053d036d034202000009a6051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e03270200000000032103170317034003190337072c0200000000020000002807430368010000001d4e4f572069732067726561746572207468616e20646561646c696e652e032703210317031607430362000003190337072c0200000000020000003807430368010000002d6d6178546f6b656e734465706f7369746564206d7573742062652067726561746572207468616e207a65726f2e032703210316031707430362000003190337072c020000000002000000320743036801000000276d696e4c71744d696e746564206d7573742062652067726561746572207468616e207a65726f2e03270743036a000003130319032a072c0200000000020000002c074303680100000021416d6f756e74206d7573742062652067726561746572207468616e207a65726f2e0327051f02000000020321034c031703160317031703300325072c020000032f03130743036a0080897a03190332072c0200000000020000004f07430368010000004454686520696e697469616c206c697175696469747920616d6f756e74206d7573742062652067726561746572207468616e206f7220657175616c20746f20312058545a2e0327034c0313051f02000000060743036a00010322072f020000000b0743036801000000000327020000000203160321051f0200000071051f020000000403210317051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c03420342051f020000000d0321051f020000000203160317034c0320034c0342034c071f0002020000000203210570000203160316051f0200000004032103160329072f020000000e0723036e03620743036200000342020000000005700002051f020000000d0321051f020000000203170316034c03200342051f0200000004032103160346071f00030200000002032105700003031603160350051f020000000d0321051f020000000203170316034c032003420321031703170317031703130312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c034203210317031703170316071f00020200000002032105700002031703160312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342051f0200000011032103170316051f0200000004031603160321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a0000057000030349035405700005051f020000000203420342034d051f0200000004053d036d031b034202000004e6051f02000000020321034c0317031703170317051f02000000060743036a00010322072f020000000b0743036801000000000327020000000203160313051f02000000060743036a00010322072f020000000b0743036801000000000327020000000203160321071f000402000000020321057000040317031703170316033a071f00020200000002032105700002034c0322072f020000001507430368010000000a64697642795a65726f2e0327020000002703210316051f02000000020317034c03300325072c020000000002000000080743036200010312032107430362000003190337072c02000000000200000023074303680100000018746f6b656e734465706f7369746564206973207a65726f2e0327034c071f000402000000020321057000040317031603170317033a051f0200000002034c0322072f0200000002032702000000020316071f0002020000000203210570000203160317051f0200000002032103190332072c020000000002000000430743036801000000386c71744d696e746564206d7573742062652067726561746572207468616e206f7220657175616c20746f206d696e4c71744d696e7465642e0327051f0200000066051f02000000020321034c03170316051f0200000002032103190328072c0200000000020000003e074303680100000033746f6b656e734465706f73697465642069732067726561746572207468616e206d6178546f6b656e734465706f73697465642e0327071f00030200000002032105700003071f0003020000000203210570000303160316051f020000000203160329072f020000000e0723036e03620743036200000342020000000003210316071f000202000000020321057000020312051f020000000d0321051f020000000203170316034c032003420346071f0003020000000203210570000303160316051f020000000f051f020000000805700003032103160350051f020000000d0321051f020000000203170316034c0320034203210317031603170317057000020312051f020000000403210317051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c03420342051f020000000d0321051f020000000203160317034c0320034c03420321031703170317031703130312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c034203210317031703170316071f000202000000020321057000020312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342051f020000000b051f0200000004031603160321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a0000057000030349035405700005051f020000000203420342034d051f0200000004053d036d031b034202000012be072e020000090b051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000321031703170317034003190337072c0200000000020000002807430368010000001d4e4f572069732067726561746572207468616e20646561646c696e652e03270743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e03270321031703160743036a000003190337072c0200000000020000003507430368010000002a6d696e58747a57697468647261776e206d7573742062652067726561746572207468616e207a65726f2e0327032103170317031607430362000003190337072c0200000000020000003807430368010000002d6d696e546f6b656e7357697468647261776e206d7573742062652067726561746572207468616e207a65726f2e0327032103160317031707430362000003190337072c0200000000020000002f0743036801000000246c71744275726e6564206d7573742062652067726561746572207468616e207a65726f2e0327032103160316051f020000000d051f02000000020321034c03160329072f02000000220743036801000000176f776e657220686173206e6f206c69717569646974792e03270200000000034c0321031603170317071f00020200000002032105700002031603190328072c0200000000020000003507430368010000002a6c71744275726e65642069732067726561746572207468616e206f776e657227732062616c616e63652e0327032103160316034803190325072c0200000004034c03160200000132034c0321031703480329072f020000002a07430368010000001f73656e64657220686173206e6f20617070726f76616c2062616c616e63652e03270200000000051f0200000017034c0321031603170317051f02000000060743035b0000034b0321051f020000004b03190328072c0200000000020000003b07430368010000003073656e64657220617070726f76616c2062616c616e6365206973206c657373207468616e204c5154206275726e65642e03270311034605700002032103170570000203480350051f020000000d0321051f020000000203160317034c0320034c034203210316051f0200000043034605710001032103160316034c051f020000002e051f020000000b051f0200000004032103160350051f020000000d0321051f020000000203170316034c03200342051f02000000020321034c031603170317071f000302000000020321057000030317031703170317051f02000000060743036a00010322072f020000000b074303680100000000032702000000020316033a051f0200000017071f0002020000000203210570000203170316031703170322072f020000001507430368010000000a64697642795a65726f2e0327020000000203160743036a0001033a0321071f000302000000020321057000030317031603190332072c0200000000020000003507430368010000002a78747a57697468647261776e206973206c657373207468616e206d696e58747a57697468647261776e2e0327071f00020200000002032105700002031603170317051f0200000023071f0003020000000203210570000303210317031603170317034c0317031703170316033a0322072f020000001507430368010000000a64697642795a65726f2e0327020000000203160321071f0004020000000203210570000403170317031603190332072c0200000000020000003b074303680100000030746f6b656e7357697468647261776e206973206c657373207468616e206d696e546f6b656e7357697468647261776e2e0327071f0003020000000203210570000303160317031705700003034b03210743035b000003190332072c02000000020311020000000b0743036801000000000327057000040321071f0005020000000203210570000503160316051f020000000203160329072f020000000e0723036e03620743036200000342020000000005700002051f020000000d0321051f020000000203170316034c03200342051f0200000004032103160346071f00050200000002032105700005031603160350051f020000000d0321051f020000000203170316034c0320034203210317031603170317071f00040200000002032105700004031603170317034c034b03210743035b000003190332072c02000000020311020000000b0743036801000000000327051f020000000403210317051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c03420342051f020000000d0321051f020000000203160317034c0320034c034203210317031703170316071f00020200000002032105700002034c034b03210743035b000003190332072c02000000020311020000000b0743036801000000000327051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c034203210317031703170317071f00030200000002032105700003034c0393072f020000001a07430368010000000f6e65676174697665206d7574657a2103270200000000051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342071f000302000000020321057000030316031703160555036c072f020000000403170327020000000005700003034f034d051f020000005f051f020000000d051f02000000060316031703160321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a000005700003057000040342034903540342034d053d036d034c031b034c031b034202000009a7072e020000049c051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e03270200000000032103170317034003190337072c0200000000020000002807430368010000001d4e4f572069732067726561746572207468616e20646561646c696e652e03270743036a000003130319032a072c0200000000020000002c074303680100000021416d6f756e74206d7573742062652067726561746572207468616e207a65726f2e032703210317031607430362000003190337072c0200000000020000003507430368010000002a6d696e546f6b656e73426f75676874206d7573742062652067726561746572207468616e207a65726f2e0327051f020000004d032103170317031703170743036a000003190337072c0200000000020000002d07430368010000002278747a506f6f6c206d7573742062652067726561746572207468616e207a65726f2e0327051f020000004e0321031703170317031607430362000003190337072c0200000000020000002e074303680100000023746f6b656e506f6f6c206d7573742062652067726561746572207468616e207a65726f0327051f02000000020321034c0317031703170317051f02000000060743036a00010322072f020000000b0743036801000000000327020000000203160743036200a80f033a0313051f02000000060743036a00010322072f020000000b0743036801000000000327020000000203160321051f020000000b0743036200a50f033a03120743036200a50f033a071f000302000000020321057000030317031703170316033a0322072f020000001507430368010000000a64697642795a65726f2e0327020000000203160321051f0200000052051f020000000603210317031603190328072c0200000000020000003507430368010000002a746f6b656e73426f75676874206973206c657373207468616e206d696e546f6b656e73426f756768742e03270321071f000302000000020321057000030317031703170316034b03210743035b000003190332072c02000000020311020000000b0743036801000000000327051f020000000405700002051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c03420321031703170317031703130312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342051f020000000d051f02000000060316034903540321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a0000057000030570000505700005051f020000000203420342034d051f0200000004053d036d031b034202000004ff051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000321031703170317034003190337072c0200000000020000002807430368010000001d4e4f572069732067726561746572207468616e20646561646c696e652e03270743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327051f020000004d032103170317031703170743036a000003190337072c0200000000020000002d07430368010000002278747a506f6f6c206d7573742062652067726561746572207468616e207a65726f2e0327051f020000004e0321031703170317031607430362000003190337072c0200000000020000002e074303680100000023746f6b656e506f6f6c206d7573742062652067726561746572207468616e207a65726f032703210317031607430362000003190337072c0200000000020000001d074303680100000012746f6b656e73536f6c64206973207a65726f032703210317031703160743036a000003190337072c020000000002000000320743036801000000276d696e58747a426f75676874206d7573742062652067726561746572207468616e207a65726f2e03270321031703160743036200a50f033a071f0002020000000203210570000203170317031703160743036200a80f033a0312051f02000000020321034c031703160743036200a50f033a071f000302000000020321057000030317031703170317051f02000000060743036a00010322072f020000000b074303680100000000032702000000020316033a0322072f020000001507430368010000000a64697642795a65726f2e0327020000000203160743036a0001033a0321051f020000004e051f0200000008032103170317031603190328072c0200000000020000002f07430368010000002478747a426f75676874206973206c657373207468616e206d696e58747a426f756768742e0327051f0200000092034c03210317031703170316071f00020200000002032105700002031703160312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c03420321051f02000000ae051f020000000a03210317031703170317034c0393072f020000001a07430368010000000f6e65676174697665206d7574657a2103270200000000051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342071f00020200000002032105700002031603170555036c072f02000000020327020000000005700001034f034d051f020000006a051f0200000011032103170316051f0200000004031603160321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a0000057000030349035405700005051f020000000203420342034d053d036d05700002031b034c031b03420200000c59072e0200000867072e0200000517051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e03270321031703170317034003190337072c0200000000020000002807430368010000001d4e4f572069732067726561746572207468616e20646561646c696e652e0327032103170317031607430362000003190337072c0200000000020000001d074303680100000012746f6b656e73536f6c64206973207a65726f0327032103160317031607430362000003190337072c0200000000020000003507430368010000002a6d696e546f6b656e73426f75676874206d7573742062652067726561746572207468616e207a65726f2e0327051f020000004d032103170317031703170743036a000003190337072c0200000000020000002d07430368010000002278747a506f6f6c206d7573742062652067726561746572207468616e207a65726f2e0327051f020000004e0321031703170317031607430362000003190337072c0200000000020000002e074303680100000023746f6b656e506f6f6c206d7573742062652067726561746572207468616e207a65726f032703210317031703160743036200a50f033a071f0002020000000203210570000203170317031703160743036200a80f033a0312051f02000000020321034c0317031703160743036200a50f033a071f000302000000020321057000030317031703170317051f02000000060743036a00010322072f020000000b074303680100000000032702000000020316033a0322072f020000001507430368010000000a64697642795a65726f2e0327020000000203160743036a0001033a051f02000000020321034c031703170316071f0003020000000203210570000303170317031703160312051f020000000405700002051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c034203210317031703170317071f00020200000002032105700002034c0393072f020000001a07430368010000000f6e65676174697665206d7574657a2103270200000000051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342071f000202000000020321057000020316031606550765036e07650362036b0000000b2578747a546f546f6b656e072f020000000403170327020000000005700002071f00030200000002032105700003032103170316051f02000000190321031603170316051f0200000008032103170317031703420342034c0320034d034c051f0200000017034c0321031703170316051f02000000060316031703170321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a0000057000030349035405700005051f020000000203420342034d053d036d034c031b051f0200000002034c034c031b03420200000344072e02000001720743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327031e0354034803190325072c02000000000200000020074303680100000015756e73616665557064617465546f6b656e506f6f6c03270321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000321031707430359030a051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203170316034c032003420342051f020000000d0321051f020000000203160317034c0320034c03420321031703170316031706550765036e055a03620000000b2567657442616c616e6365072f02000000040317032702000000000743036a000004490000001825757064617465546f6b656e506f6f6c496e7465726e616c034903540342034d051f0200000004053d036d031b034202000001c60743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327051f02000000020321034c031703160316072c0200000000020000003207430368010000002744657874657220646964206e6f7420696e6974696174652074686973206f7065726174696f6e2e0327051f02000000020321034c0317031703160317034803190325072c0200000000020000004e0743036801000000435468652073656e646572206973206e6f742074686520746f6b656e20636f6e7472616374206173736f6369617465642077697468207468697320636f6e74726163742e0327051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c034203210317074303590303051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203170316034c032003420342051f020000000d0321051f020000000203160317034c0320034c0342053d036d034202000003e6072e02000001bd051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327051f02000000020321034c0317031703160316034803190325072c0200000000020000002e07430368010000002373656e646572206973206e6f742074686520636f6e7472616374206d616e616765722e0327051f02000000020321034c0317031603170316033f072c0200000000020000003d07430368010000003243616e6e6f74206368616e6765207468652062616b6572207768696c6520667265657a6542616b657220697320747275652e032703210316051f02000000020317034e051f0200000073051f020000000403210317051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c03420342051f020000000d0321051f020000000203160317034c0320034c0342053d036d031b0342020000021d072e0200000147051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327051f02000000020321034c0317031703160316034803190325072c0200000000020000002e07430368010000002373656e646572206973206e6f742074686520636f6e7472616374206d616e616765722e0327051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203170316034c032003420342034c0342051f020000000d0321051f020000000203160317034c0320034c0342053d036d034202000000ca03200321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000321031703170317031703130312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342053d036d0342"; } let exprubv5oQmAUP8BwktmDgMWqTizYDJVhzHhJESGZhJ2GkHESZ1VWg = @@ -173,7 +173,7 @@ let exprubv5oQmAUP8BwktmDgMWqTizYDJVhzHhJESGZhJ2GkHESZ1VWg = addresses = ["KT1CT7S2b9hXNRxRrEcany9sak1qe4aaFAZJ"]; patched_code = bin_expr_exn - "0200002bf705000764076407640865046e000000083a7370656e646572076504620000000a3a616c6c6f77616e63650462000000113a63757272656e74416c6c6f77616e63650000000825617070726f766508650765046e000000063a6f776e657204620000000d3a6d696e4c71744d696e74656407650462000000133a6d6178546f6b656e734465706f7369746564046b000000093a646561646c696e650000000d256164644c6971756964697479076408650765046e000000063a6f776e65720765046e000000033a746f04620000000a3a6c71744275726e65640765046a000000103a6d696e58747a57697468647261776e07650462000000133a6d696e546f6b656e7357697468647261776e046b000000093a646561646c696e65000000102572656d6f76654c697175696469747907640865046e000000033a746f07650462000000103a6d696e546f6b656e73426f75676874046b000000093a646561646c696e650000000b2578747a546f546f6b656e08650765046e000000063a6f776e6572046e000000033a746f076504620000000b3a746f6b656e73536f6c640765046a0000000d3a6d696e58747a426f75676874046b000000093a646561646c696e650000000b25746f6b656e546f58747a0764076408650765046e000000153a6f7574707574446578746572436f6e747261637407650462000000103a6d696e546f6b656e73426f75676874046e000000063a6f776e65720765046e000000033a746f076504620000000b3a746f6b656e73536f6c64046b000000093a646561646c696e650000000d25746f6b656e546f546f6b656e0764045d0000001025757064617465546f6b656e506f6f6c04620000001825757064617465546f6b656e506f6f6c496e7465726e616c076408650563035d0359000000092573657442616b65720764046e0000000b257365744d616e61676572046c000000082564656661756c74050107650861046e000000063a6f776e657207650462000000083a62616c616e63650760046e000000083a7370656e64657204620000000a3a616c6c6f77616e636500000009256163636f756e7473076507650459000000183a73656c6649735570646174696e67546f6b656e506f6f6c076504590000000c3a667265657a6542616b65720462000000093a6c7174546f74616c07650765046e000000083a6d616e61676572046e0000000d3a746f6b656e41646472657373076504620000000a3a746f6b656e506f6f6c046a000000083a78747a506f6f6c05020200002854055707650764076407640765036e07650362036207650765036e036207650362036b076407650765036e0765036e03620765036a07650362036b07640765036e07650362036b07650765036e036e076503620765036a036b0764076407650765036e07650362036e0765036e07650362036b0764035d0362076407650563035d03590764036e036c07650761036e076503620760036e036207650765035907650359036207650765036e036e07650362036a03210316051f02000000020317072e0200001c3a072e0200000b8d072e02000001c1051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327051f02000000020321034c031603480329072f020000000e0723036e03620743036200000342020000000003210317071f0002020000000203210570000203160329072f02000000060743036200000200000000071f000202000000020321057000020317031703190325072c020000000002000000630743036801000000585468652063757272656e7420616c6c6f77616e636520706172616d65746572206d75737420657175616c207468652073656e64657227732063757272656e7420616c6c6f77616e636520666f7220746865206f776e65722e0327032103170570000203210316051f02000000060317031603460350051f020000000d0321051f020000000203160317034c0320034c0342051f020000000403210316034603480350051f020000000d0321051f020000000203170316034c03200342053d036d034202000009c0051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e03270200000000032103170317034003190337072c0200000000020000002807430368010000001d4e4f572069732067726561746572207468616e20646561646c696e652e032703210317031607430362000003190337072c0200000000020000003807430368010000002d6d6178546f6b656e734465706f7369746564206d7573742062652067726561746572207468616e207a65726f2e032703210316031707430362000003190337072c020000000002000000320743036801000000276d696e4c71744d696e746564206d7573742062652067726561746572207468616e207a65726f2e032703130743036a000003190337072c0200000000020000004607430368010000003b54686520616d6f756e74206f662058545a2073656e7420746f20446578746572206d7573742062652067726561746572207468616e207a65726f2e0327051f02000000020321034c031703160317031703300325072c020000032f03130743036a0080897a03190332072c0200000000020000004f07430368010000004454686520696e697469616c206c697175696469747920616d6f756e74206d7573742062652067726561746572207468616e206f7220657175616c20746f20312058545a2e0327034c0313051f02000000060743036a00010322072f020000000b0743036801000000000327020000000203160321051f0200000071051f020000000403210317051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c03420342051f020000000d0321051f020000000203160317034c0320034c0342034c071f0002020000000203210570000203160316051f0200000004032103160329072f020000000e0723036e03620743036200000342020000000005700002051f020000000d0321051f020000000203170316034c03200342051f0200000004032103160346071f00030200000002032105700003031603160350051f020000000d0321051f020000000203170316034c032003420321031703170317031703130312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c034203210317031703170316071f00020200000002032105700002031703160312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342051f0200000011032103170316051f0200000004031603160321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a0000057000030349035405700005051f020000000203420342034d051f0200000004053d036d031b034202000004e6051f02000000020321034c0317031703170317051f02000000060743036a00010322072f020000000b0743036801000000000327020000000203160313051f02000000060743036a00010322072f020000000b0743036801000000000327020000000203160321071f000402000000020321057000040317031703170316033a071f00020200000002032105700002034c0322072f020000001507430368010000000a64697642795a65726f2e0327020000002703210316051f02000000020317034c03300325072c020000000002000000080743036200010312032107430362000003190337072c02000000000200000023074303680100000018746f6b656e734465706f7369746564206973207a65726f2e0327034c071f000402000000020321057000040317031603170317033a051f0200000002034c0322072f0200000002032702000000020316071f0002020000000203210570000203160317051f0200000002032103190332072c020000000002000000430743036801000000386c71744d696e746564206d7573742062652067726561746572207468616e206f7220657175616c20746f206d696e4c71744d696e7465642e0327051f0200000066051f02000000020321034c03170316051f0200000002032103190328072c0200000000020000003e074303680100000033746f6b656e734465706f73697465642069732067726561746572207468616e206d6178546f6b656e734465706f73697465642e0327071f00030200000002032105700003071f0003020000000203210570000303160316051f020000000203160329072f020000000e0723036e03620743036200000342020000000003210316071f000202000000020321057000020312051f020000000d0321051f020000000203170316034c032003420346071f0003020000000203210570000303160316051f020000000f051f020000000805700003032103160350051f020000000d0321051f020000000203170316034c0320034203210317031603170317057000020312051f020000000403210317051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c03420342051f020000000d0321051f020000000203160317034c0320034c03420321031703170317031703130312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c034203210317031703170316071f000202000000020321057000020312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342051f020000000b051f0200000004031603160321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a0000057000030349035405700005051f020000000203420342034d051f0200000004053d036d031b034202000010a1072e02000008e5051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e03270321031703170317034003190337072c0200000000020000002807430368010000001d4e4f572069732067726561746572207468616e20646561646c696e652e03270321031703160743036a000003190337072c0200000000020000003507430368010000002a6d696e58747a57697468647261776e206d7573742062652067726561746572207468616e207a65726f2e0327032103170317031607430362000003190337072c0200000000020000003807430368010000002d6d696e546f6b656e7357697468647261776e206d7573742062652067726561746572207468616e207a65726f2e0327032103160317031707430362000003190337072c0200000000020000002f0743036801000000246c71744275726e6564206d7573742062652067726561746572207468616e207a65726f2e0327032103160316051f020000000d051f02000000020321034c03160329072f02000000220743036801000000176f776e657220686173206e6f206c69717569646974792e03270200000000034c0321031603170317071f00020200000002032105700002031603190328072c0200000000020000003507430368010000002a6c71744275726e65642069732067726561746572207468616e206f776e657227732062616c616e63652e0327032103160316034803190325072c0200000004034c03160200000132034c0321031703480329072f020000002a07430368010000001f73656e64657220686173206e6f20617070726f76616c2062616c616e63652e03270200000000051f0200000017034c0321031603170317051f02000000060743035b0000034b0321051f020000004b03190328072c0200000000020000003b07430368010000003073656e64657220617070726f76616c2062616c616e6365206973206c657373207468616e204c5154206275726e65642e03270311034605700002032103170570000203480350051f020000000d0321051f020000000203160317034c0320034c034203210316051f0200000043034605710001032103160316034c051f020000002e051f020000000b051f0200000004032103160350051f020000000d0321051f020000000203170316034c03200342051f02000000020321034c031603170317071f000302000000020321057000030317031703170317051f02000000060743036a00010322072f020000000b074303680100000000032702000000020316033a051f0200000017071f0002020000000203210570000203170316031703170322072f020000001507430368010000000a64697642795a65726f2e0327020000000203160743036a0001033a0321071f000302000000020321057000030317031603190332072c0200000000020000003507430368010000002a78747a57697468647261776e206973206c657373207468616e206d696e58747a57697468647261776e2e0327071f00020200000002032105700002031603170317051f0200000023071f0003020000000203210570000303210317031603170317034c0317031703170316033a0322072f020000001507430368010000000a64697642795a65726f2e0327020000000203160321071f0004020000000203210570000403170317031603190332072c0200000000020000003b074303680100000030746f6b656e7357697468647261776e206973206c657373207468616e206d696e546f6b656e7357697468647261776e2e0327071f0003020000000203210570000303160317031705700003034b03210743035b000003190332072c02000000020311020000000b0743036801000000000327057000040321071f0005020000000203210570000503160316051f020000000203160329072f020000000e0723036e03620743036200000342020000000005700002051f020000000d0321051f020000000203170316034c03200342051f0200000004032103160346071f00050200000002032105700005031603160350051f020000000d0321051f020000000203170316034c0320034203210317031603170317071f00040200000002032105700004031603170317034c034b03210743035b000003190332072c02000000020311020000000b0743036801000000000327051f020000000403210317051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c03420342051f020000000d0321051f020000000203160317034c0320034c034203210317031703170316071f00020200000002032105700002034c034b03210743035b000003190332072c02000000020311020000000b0743036801000000000327051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c034203210317031703170317071f00030200000002032105700003034c034b051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342071f000302000000020321057000030316031703160555036c072f020000000403170327020000000005700003034f034d051f020000005f051f020000000d051f02000000060316031703160321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a000005700003057000040342034903540342034d053d036d034c031b034c031b034202000007b0072e02000003af051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e03270200000000032103170317034003190337072c0200000000020000002807430368010000001d4e4f572069732067726561746572207468616e20646561646c696e652e032703210317031607430362000003190337072c0200000000020000003507430368010000002a6d696e546f6b656e73426f75676874206d7573742062652067726561746572207468616e207a65726f2e0327051f02000000020321034c0317031703170317051f02000000060743036a00010322072f020000000b0743036801000000000327020000000203160743036200a80f033a0313051f02000000060743036a00010322072f020000000b0743036801000000000327020000000203160321051f020000000b0743036200a50f033a03120743036200a50f033a071f000302000000020321057000030317031703170316033a0322072f020000001507430368010000000a64697642795a65726f2e0327020000000203160321051f0200000052051f020000000603210317031603190328072c0200000000020000003507430368010000002a746f6b656e73426f75676874206973206c657373207468616e206d696e546f6b656e73426f756768742e03270321071f000302000000020321057000030317031703170316034b03210743035b000003190332072c02000000020311020000000b0743036801000000000327051f020000000405700002051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c03420321031703170317031703130312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342051f020000000d051f02000000060316034903540321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a0000057000030570000505700005051f020000000203420342034d051f0200000004053d036d031b034202000003f5051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e032703210317031703160743036a000003190337072c020000000002000000320743036801000000276d696e58747a426f75676874206d7573742062652067726561746572207468616e207a65726f2e03270321031703170317034003190337072c0200000000020000002807430368010000001d4e4f572069732067726561746572207468616e20646561646c696e652e03270321031703160743036200a50f033a071f0002020000000203210570000203170317031703160743036200a80f033a0312051f02000000020321034c031703160743036200a50f033a071f000302000000020321057000030317031703170317051f02000000060743036a00010322072f020000000b074303680100000000032702000000020316033a0322072f020000001507430368010000000a64697642795a65726f2e0327020000000203160743036a0001033a0321051f020000004e051f0200000008032103170317031603190328072c0200000000020000002f07430368010000002478747a426f75676874206973206c657373207468616e206d696e58747a426f756768742e0327051f0200000092034c03210317031703170316071f00020200000002032105700002031703160312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c03420321051f0200000088051f020000000a03210317031703170317034c034b051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342071f00020200000002032105700002031603170555036c072f02000000020327020000000005700001034f034d051f020000006a051f0200000011032103170316051f0200000004031603160321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a0000057000030349035405700005051f020000000203420342034d053d036d034c031b034c031b03420200000b4f072e020000075d072e020000040d051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e03270321031703170317034003190337072c0200000000020000002807430368010000001d4e4f572069732067726561746572207468616e20646561646c696e652e0327032103160317031607430362000003190337072c0200000000020000003507430368010000002a6d696e546f6b656e73426f75676874206d7573742062652067726561746572207468616e207a65726f2e032703210317031703160743036200a50f033a071f0002020000000203210570000203170317031703160743036200a80f033a0312051f02000000020321034c0317031703160743036200a50f033a071f000302000000020321057000030317031703170317051f02000000060743036a00010322072f020000000b074303680100000000032702000000020316033a0322072f020000001507430368010000000a64697642795a65726f2e0327020000000203160743036a0001033a051f02000000020321034c031703170316071f0003020000000203210570000303170317031703160312051f020000000405700002051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c034203210317031703170317071f00020200000002032105700002034c034b051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342071f000202000000020321057000020316031606550765036e07650362036b0000000b2578747a546f546f6b656e072f020000000403170327020000000005700002071f00030200000002032105700003032103170316051f02000000190321031603170316051f0200000008032103170317031703420342034c0320034d034c051f0200000017034c0321031703170316051f02000000060316031703170321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a0000057000030349035405700005051f020000000203420342034d053d036d034c031b051f0200000002034c034c031b03420200000344072e02000001720743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327031e0354034803190325072c02000000000200000020074303680100000015756e73616665557064617465546f6b656e506f6f6c03270321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000321031707430359030a051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203170316034c032003420342051f020000000d0321051f020000000203160317034c0320034c03420321031703170316031706550765036e055a03620000000b2567657442616c616e6365072f02000000040317032702000000000743036a000004490000001825757064617465546f6b656e506f6f6c496e7465726e616c034903540342034d051f0200000004053d036d031b034202000001c60743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327051f02000000020321034c031703160316072c0200000000020000003207430368010000002744657874657220646964206e6f7420696e6974696174652074686973206f7065726174696f6e2e0327051f02000000020321034c0317031703160317034803190325072c0200000000020000004e0743036801000000435468652073656e646572206973206e6f742074686520746f6b656e20636f6e7472616374206173736f6369617465642077697468207468697320636f6e74726163742e0327051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c034203210317074303590303051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203170316034c032003420342051f020000000d0321051f020000000203160317034c0320034c0342053d036d034202000003e6072e02000001bd051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327051f02000000020321034c0317031703160316034803190325072c0200000000020000002e07430368010000002373656e646572206973206e6f742074686520636f6e7472616374206d616e616765722e0327051f02000000020321034c0317031603170316033f072c0200000000020000003d07430368010000003243616e6e6f74206368616e6765207468652062616b6572207768696c6520667265657a6542616b657220697320747275652e032703210316051f02000000020317034e051f0200000073051f020000000403210317051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c03420342051f020000000d0321051f020000000203160317034c0320034c0342053d036d031b0342020000021d072e0200000147051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327051f02000000020321034c0317031703160316034803190325072c0200000000020000002e07430368010000002373656e646572206973206e6f742074686520636f6e7472616374206d616e616765722e0327051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203170316034c032003420342034c0342051f020000000d0321051f020000000203160317034c0320034c0342053d036d034202000000ca03200321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000321031703170317031703130312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342053d036d0342"; + "0200002c6905000764076407640865046e000000083a7370656e646572076504620000000a3a616c6c6f77616e63650462000000113a63757272656e74416c6c6f77616e63650000000825617070726f766508650765046e000000063a6f776e657204620000000d3a6d696e4c71744d696e74656407650462000000133a6d6178546f6b656e734465706f7369746564046b000000093a646561646c696e650000000d256164644c6971756964697479076408650765046e000000063a6f776e65720765046e000000033a746f04620000000a3a6c71744275726e65640765046a000000103a6d696e58747a57697468647261776e07650462000000133a6d696e546f6b656e7357697468647261776e046b000000093a646561646c696e65000000102572656d6f76654c697175696469747907640865046e000000033a746f07650462000000103a6d696e546f6b656e73426f75676874046b000000093a646561646c696e650000000b2578747a546f546f6b656e08650765046e000000063a6f776e6572046e000000033a746f076504620000000b3a746f6b656e73536f6c640765046a0000000d3a6d696e58747a426f75676874046b000000093a646561646c696e650000000b25746f6b656e546f58747a0764076408650765046e000000153a6f7574707574446578746572436f6e747261637407650462000000103a6d696e546f6b656e73426f75676874046e000000063a6f776e65720765046e000000033a746f076504620000000b3a746f6b656e73536f6c64046b000000093a646561646c696e650000000d25746f6b656e546f546f6b656e0764045d0000001025757064617465546f6b656e506f6f6c04620000001825757064617465546f6b656e506f6f6c496e7465726e616c076408650563035d0359000000092573657442616b65720764046e0000000b257365744d616e61676572046c000000082564656661756c74050107650861046e000000063a6f776e657207650462000000083a62616c616e63650760046e000000083a7370656e64657204620000000a3a616c6c6f77616e636500000009256163636f756e7473076507650459000000183a73656c6649735570646174696e67546f6b656e506f6f6c076504590000000c3a667265657a6542616b65720462000000093a6c7174546f74616c07650765046e000000083a6d616e61676572046e0000000d3a746f6b656e41646472657373076504620000000a3a746f6b656e506f6f6c046a000000083a78747a506f6f6c050202000028c6055707650764076407640765036e07650362036207650765036e036207650362036b076407650765036e0765036e03620765036a07650362036b07640765036e07650362036b07650765036e036e076503620765036a036b0764076407650765036e07650362036e0765036e07650362036b0764035d0362076407650563035d03590764036e036c07650761036e076503620760036e036207650765035907650359036207650765036e036e07650362036a03210316051f02000000020317072e0200001c86072e0200000b8d072e02000001c1051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327051f02000000020321034c031603480329072f020000000e0723036e03620743036200000342020000000003210317071f0002020000000203210570000203160329072f02000000060743036200000200000000071f000202000000020321057000020317031703190325072c020000000002000000630743036801000000585468652063757272656e7420616c6c6f77616e636520706172616d65746572206d75737420657175616c207468652073656e64657227732063757272656e7420616c6c6f77616e636520666f7220746865206f776e65722e0327032103170570000203210316051f02000000060317031603460350051f020000000d0321051f020000000203160317034c0320034c0342051f020000000403210316034603480350051f020000000d0321051f020000000203170316034c03200342053d036d034202000009c0051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e03270200000000032103170317034003190337072c0200000000020000002807430368010000001d4e4f572069732067726561746572207468616e20646561646c696e652e032703210317031607430362000003190337072c0200000000020000003807430368010000002d6d6178546f6b656e734465706f7369746564206d7573742062652067726561746572207468616e207a65726f2e032703210316031707430362000003190337072c020000000002000000320743036801000000276d696e4c71744d696e746564206d7573742062652067726561746572207468616e207a65726f2e032703130743036a000003190337072c0200000000020000004607430368010000003b54686520616d6f756e74206f662058545a2073656e7420746f20446578746572206d7573742062652067726561746572207468616e207a65726f2e0327051f02000000020321034c031703160317031703300325072c020000032f03130743036a0080897a03190332072c0200000000020000004f07430368010000004454686520696e697469616c206c697175696469747920616d6f756e74206d7573742062652067726561746572207468616e206f7220657175616c20746f20312058545a2e0327034c0313051f02000000060743036a00010322072f020000000b0743036801000000000327020000000203160321051f0200000071051f020000000403210317051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c03420342051f020000000d0321051f020000000203160317034c0320034c0342034c071f0002020000000203210570000203160316051f0200000004032103160329072f020000000e0723036e03620743036200000342020000000005700002051f020000000d0321051f020000000203170316034c03200342051f0200000004032103160346071f00030200000002032105700003031603160350051f020000000d0321051f020000000203170316034c032003420321031703170317031703130312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c034203210317031703170316071f00020200000002032105700002031703160312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342051f0200000011032103170316051f0200000004031603160321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a0000057000030349035405700005051f020000000203420342034d051f0200000004053d036d031b034202000004e6051f02000000020321034c0317031703170317051f02000000060743036a00010322072f020000000b0743036801000000000327020000000203160313051f02000000060743036a00010322072f020000000b0743036801000000000327020000000203160321071f000402000000020321057000040317031703170316033a071f00020200000002032105700002034c0322072f020000001507430368010000000a64697642795a65726f2e0327020000002703210316051f02000000020317034c03300325072c020000000002000000080743036200010312032107430362000003190337072c02000000000200000023074303680100000018746f6b656e734465706f7369746564206973207a65726f2e0327034c071f000402000000020321057000040317031603170317033a051f0200000002034c0322072f0200000002032702000000020316071f0002020000000203210570000203160317051f0200000002032103190332072c020000000002000000430743036801000000386c71744d696e746564206d7573742062652067726561746572207468616e206f7220657175616c20746f206d696e4c71744d696e7465642e0327051f0200000066051f02000000020321034c03170316051f0200000002032103190328072c0200000000020000003e074303680100000033746f6b656e734465706f73697465642069732067726561746572207468616e206d6178546f6b656e734465706f73697465642e0327071f00030200000002032105700003071f0003020000000203210570000303160316051f020000000203160329072f020000000e0723036e03620743036200000342020000000003210316071f000202000000020321057000020312051f020000000d0321051f020000000203170316034c032003420346071f0003020000000203210570000303160316051f020000000f051f020000000805700003032103160350051f020000000d0321051f020000000203170316034c0320034203210317031603170317057000020312051f020000000403210317051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c03420342051f020000000d0321051f020000000203160317034c0320034c03420321031703170317031703130312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c034203210317031703170316071f000202000000020321057000020312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342051f020000000b051f0200000004031603160321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a0000057000030349035405700005051f020000000203420342034d051f0200000004053d036d031b034202000010ed072e020000090b051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e03270321031703170317034003190337072c0200000000020000002807430368010000001d4e4f572069732067726561746572207468616e20646561646c696e652e03270321031703160743036a000003190337072c0200000000020000003507430368010000002a6d696e58747a57697468647261776e206d7573742062652067726561746572207468616e207a65726f2e0327032103170317031607430362000003190337072c0200000000020000003807430368010000002d6d696e546f6b656e7357697468647261776e206d7573742062652067726561746572207468616e207a65726f2e0327032103160317031707430362000003190337072c0200000000020000002f0743036801000000246c71744275726e6564206d7573742062652067726561746572207468616e207a65726f2e0327032103160316051f020000000d051f02000000020321034c03160329072f02000000220743036801000000176f776e657220686173206e6f206c69717569646974792e03270200000000034c0321031603170317071f00020200000002032105700002031603190328072c0200000000020000003507430368010000002a6c71744275726e65642069732067726561746572207468616e206f776e657227732062616c616e63652e0327032103160316034803190325072c0200000004034c03160200000132034c0321031703480329072f020000002a07430368010000001f73656e64657220686173206e6f20617070726f76616c2062616c616e63652e03270200000000051f0200000017034c0321031603170317051f02000000060743035b0000034b0321051f020000004b03190328072c0200000000020000003b07430368010000003073656e64657220617070726f76616c2062616c616e6365206973206c657373207468616e204c5154206275726e65642e03270311034605700002032103170570000203480350051f020000000d0321051f020000000203160317034c0320034c034203210316051f0200000043034605710001032103160316034c051f020000002e051f020000000b051f0200000004032103160350051f020000000d0321051f020000000203170316034c03200342051f02000000020321034c031603170317071f000302000000020321057000030317031703170317051f02000000060743036a00010322072f020000000b074303680100000000032702000000020316033a051f0200000017071f0002020000000203210570000203170316031703170322072f020000001507430368010000000a64697642795a65726f2e0327020000000203160743036a0001033a0321071f000302000000020321057000030317031603190332072c0200000000020000003507430368010000002a78747a57697468647261776e206973206c657373207468616e206d696e58747a57697468647261776e2e0327071f00020200000002032105700002031603170317051f0200000023071f0003020000000203210570000303210317031603170317034c0317031703170316033a0322072f020000001507430368010000000a64697642795a65726f2e0327020000000203160321071f0004020000000203210570000403170317031603190332072c0200000000020000003b074303680100000030746f6b656e7357697468647261776e206973206c657373207468616e206d696e546f6b656e7357697468647261776e2e0327071f0003020000000203210570000303160317031705700003034b03210743035b000003190332072c02000000020311020000000b0743036801000000000327057000040321071f0005020000000203210570000503160316051f020000000203160329072f020000000e0723036e03620743036200000342020000000005700002051f020000000d0321051f020000000203170316034c03200342051f0200000004032103160346071f00050200000002032105700005031603160350051f020000000d0321051f020000000203170316034c0320034203210317031603170317071f00040200000002032105700004031603170317034c034b03210743035b000003190332072c02000000020311020000000b0743036801000000000327051f020000000403210317051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c03420342051f020000000d0321051f020000000203160317034c0320034c034203210317031703170316071f00020200000002032105700002034c034b03210743035b000003190332072c02000000020311020000000b0743036801000000000327051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c034203210317031703170317071f00030200000002032105700003034c0393072f020000001a07430368010000000f6e65676174697665206d7574657a2103270200000000051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342071f000302000000020321057000030316031703160555036c072f020000000403170327020000000005700003034f034d051f020000005f051f020000000d051f02000000060316031703160321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a000005700003057000040342034903540342034d053d036d034c031b034c031b034202000007d6072e02000003af051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e03270200000000032103170317034003190337072c0200000000020000002807430368010000001d4e4f572069732067726561746572207468616e20646561646c696e652e032703210317031607430362000003190337072c0200000000020000003507430368010000002a6d696e546f6b656e73426f75676874206d7573742062652067726561746572207468616e207a65726f2e0327051f02000000020321034c0317031703170317051f02000000060743036a00010322072f020000000b0743036801000000000327020000000203160743036200a80f033a0313051f02000000060743036a00010322072f020000000b0743036801000000000327020000000203160321051f020000000b0743036200a50f033a03120743036200a50f033a071f000302000000020321057000030317031703170316033a0322072f020000001507430368010000000a64697642795a65726f2e0327020000000203160321051f0200000052051f020000000603210317031603190328072c0200000000020000003507430368010000002a746f6b656e73426f75676874206973206c657373207468616e206d696e546f6b656e73426f756768742e03270321071f000302000000020321057000030317031703170316034b03210743035b000003190332072c02000000020311020000000b0743036801000000000327051f020000000405700002051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c03420321031703170317031703130312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342051f020000000d051f02000000060316034903540321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a0000057000030570000505700005051f020000000203420342034d051f0200000004053d036d031b0342020000041b051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e032703210317031703160743036a000003190337072c020000000002000000320743036801000000276d696e58747a426f75676874206d7573742062652067726561746572207468616e207a65726f2e03270321031703170317034003190337072c0200000000020000002807430368010000001d4e4f572069732067726561746572207468616e20646561646c696e652e03270321031703160743036200a50f033a071f0002020000000203210570000203170317031703160743036200a80f033a0312051f02000000020321034c031703160743036200a50f033a071f000302000000020321057000030317031703170317051f02000000060743036a00010322072f020000000b074303680100000000032702000000020316033a0322072f020000001507430368010000000a64697642795a65726f2e0327020000000203160743036a0001033a0321051f020000004e051f0200000008032103170317031603190328072c0200000000020000002f07430368010000002478747a426f75676874206973206c657373207468616e206d696e58747a426f756768742e0327051f0200000092034c03210317031703170316071f00020200000002032105700002031703160312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c03420321051f02000000ae051f020000000a03210317031703170317034c0393072f020000001a07430368010000000f6e65676174697665206d7574657a2103270200000000051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342071f00020200000002032105700002031603170555036c072f02000000020327020000000005700001034f034d051f020000006a051f0200000011032103170316051f0200000004031603160321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a0000057000030349035405700005051f020000000203420342034d053d036d034c031b034c031b03420200000b75072e0200000783072e0200000433051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e03270321031703170317034003190337072c0200000000020000002807430368010000001d4e4f572069732067726561746572207468616e20646561646c696e652e0327032103160317031607430362000003190337072c0200000000020000003507430368010000002a6d696e546f6b656e73426f75676874206d7573742062652067726561746572207468616e207a65726f2e032703210317031703160743036200a50f033a071f0002020000000203210570000203170317031703160743036200a80f033a0312051f02000000020321034c0317031703160743036200a50f033a071f000302000000020321057000030317031703170317051f02000000060743036a00010322072f020000000b074303680100000000032702000000020316033a0322072f020000001507430368010000000a64697642795a65726f2e0327020000000203160743036a0001033a051f02000000020321034c031703170316071f0003020000000203210570000303170317031703160312051f020000000405700002051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c034203210317031703170317071f00020200000002032105700002034c0393072f020000001a07430368010000000f6e65676174697665206d7574657a2103270200000000051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342071f000202000000020321057000020316031606550765036e07650362036b0000000b2578747a546f546f6b656e072f020000000403170327020000000005700002071f00030200000002032105700003032103170316051f02000000190321031603170316051f0200000008032103170317031703420342034c0320034d034c051f0200000017034c0321031703170316051f02000000060316031703170321031703170316031706550765036e0765036e036200000009257472616e73666572072f02000000040317032702000000000743036a0000057000030349035405700005051f020000000203420342034d053d036d034c031b051f0200000002034c034c031b03420200000344072e02000001720743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327031e0354034803190325072c02000000000200000020074303680100000015756e73616665557064617465546f6b656e506f6f6c03270321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000321031707430359030a051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203170316034c032003420342051f020000000d0321051f020000000203160317034c0320034c03420321031703170316031706550765036e055a03620000000b2567657442616c616e6365072f02000000040317032702000000000743036a000004490000001825757064617465546f6b656e506f6f6c496e7465726e616c034903540342034d051f0200000004053d036d031b034202000001c60743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327051f02000000020321034c031703160316072c0200000000020000003207430368010000002744657874657220646964206e6f7420696e6974696174652074686973206f7065726174696f6e2e0327051f02000000020321034c0317031703160317034803190325072c0200000000020000004e0743036801000000435468652073656e646572206973206e6f742074686520746f6b656e20636f6e7472616374206173736f6369617465642077697468207468697320636f6e74726163742e0327051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c034203210317074303590303051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203170316034c032003420342051f020000000d0321051f020000000203160317034c0320034c0342053d036d034202000003e6072e02000001bd051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327051f02000000020321034c0317031703160316034803190325072c0200000000020000002e07430368010000002373656e646572206973206e6f742074686520636f6e7472616374206d616e616765722e0327051f02000000020321034c0317031603170316033f072c0200000000020000003d07430368010000003243616e6e6f74206368616e6765207468652062616b6572207768696c6520667265657a6542616b657220697320747275652e032703210316051f02000000020317034e051f0200000073051f020000000403210317051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316034c03200342034c03420342051f020000000d0321051f020000000203160317034c0320034c0342053d036d031b0342020000021d072e0200000147051f02000000410321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000743036a0000031303190325072c0200000000020000001f074303680100000014416d6f756e74206d757374206265207a65726f2e0327051f02000000020321034c0317031703160316034803190325072c0200000000020000002e07430368010000002373656e646572206973206e6f742074686520636f6e7472616374206d616e616765722e0327051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203170316051f020000000d0321051f020000000203170316034c032003420342034c0342051f020000000d0321051f020000000203160317034c0320034c0342053d036d034202000000ca03200321031703160316072c020000002d07430368010000002273656c6649735570646174696e67546f6b656e206d7573742062652066616c73652e032702000000000321031703170317031703130312051f020000000403210317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317051f020000000d0321051f020000000203160317034c0320034c0342034c0342034c0342051f020000000d0321051f020000000203160317034c0320034c0342053d036d0342"; } let patches = diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/patched_contracts/expru1ukk6ZqdA32rFYFG7j1eGjfsatbdUZWz8Mi1kXWZYRZm4FZVe.diff b/src/proto_alpha/lib_protocol/test/integration/michelson/patched_contracts/expru1ukk6ZqdA32rFYFG7j1eGjfsatbdUZWz8Mi1kXWZYRZm4FZVe.diff index 612523f46d..a39f1be68b 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/patched_contracts/expru1ukk6ZqdA32rFYFG7j1eGjfsatbdUZWz8Mi1kXWZYRZm4FZVe.diff +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/patched_contracts/expru1ukk6ZqdA32rFYFG7j1eGjfsatbdUZWz8Mi1kXWZYRZm4FZVe.diff @@ -18,7 +18,17 @@ PUSH mutez 0 ; DIG 3 ; SELF ; -@@ -744,7 +744,7 @@ +@@ -720,7 +720,8 @@ + DIP 3 { DUP } ; + DIG 3 ; + SWAP ; +- SUB ; ++ SUB_MUTEZ ; ++ IF_NONE { PUSH string "negative mutez!"; FAILWITH } {} ; + DIP { DUP ; CDR } ; + DIP { DUP ; DIP { CAR } ; CDR } ; + DIP { DUP ; DIP { CAR } ; CDR } ; +@@ -744,7 +745,7 @@ CDR ; CAR ; CONTRACT unit ; @@ -27,7 +37,7 @@ DIG 3 ; UNIT ; TRANSFER_TOKENS ; -@@ -755,7 +755,7 @@ +@@ -755,7 +756,7 @@ CAR ; CDR ; CONTRACT %transfer (pair address (pair address nat)) ; @@ -36,7 +46,7 @@ PUSH mutez 0 ; DIG 3 ; DIG 4 ; -@@ -909,7 +909,7 @@ +@@ -909,7 +910,7 @@ CAR ; CDR ; CONTRACT %transfer (pair address (pair address nat)) ; @@ -45,7 +55,17 @@ PUSH mutez 0 ; DIG 3 ; DIG 5 ; -@@ -1074,7 +1074,7 @@ +@@ -1040,7 +1041,8 @@ + DUP ; + DIP { DIP { DUP ; CDR ; CDR ; CDR ; CDR } ; + SWAP ; +- SUB ; ++ SUB_MUTEZ ; ++ IF_NONE { PUSH string "negative mutez!"; FAILWITH } {} ; + DIP { DUP ; CDR } ; + DIP { DUP ; DIP { CAR } ; CDR } ; + DIP { DUP ; DIP { CAR } ; CDR } ; +@@ -1074,7 +1076,7 @@ CAR ; CDR ; CONTRACT %transfer (pair address (pair address nat)) ; @@ -54,7 +74,17 @@ PUSH mutez 0 ; DIG 3 ; SELF ; -@@ -1240,7 +1240,7 @@ +@@ -1217,7 +1219,8 @@ + DIP 2 { DUP } ; + DIG 2 ; + SWAP ; +- SUB ; ++ SUB_MUTEZ ; ++ IF_NONE { PUSH string "negative mutez!"; FAILWITH } {} ; + DIP { DUP ; CDR } ; + DIP { DUP ; DIP { CAR } ; CDR } ; + DIP { DUP ; DIP { CAR } ; CDR } ; +@@ -1240,7 +1243,7 @@ CAR ; CAR ; CONTRACT %xtzToToken (pair address (pair nat timestamp)) ; @@ -63,7 +93,7 @@ DIG 2 ; DIP 3 { DUP } ; DIG 3 ; -@@ -1260,7 +1260,7 @@ +@@ -1260,7 +1263,7 @@ CAR ; CDR ; CONTRACT %transfer (pair address (pair address nat)) ; @@ -72,7 +102,7 @@ PUSH mutez 0 ; DIG 3 ; SELF ; -@@ -1313,7 +1313,7 @@ +@@ -1313,7 +1316,7 @@ CAR ; CDR ; CONTRACT %getBalance (pair address (contract nat)) ; diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/patched_contracts/expru1ukk6ZqdA32rFYFG7j1eGjfsatbdUZWz8Mi1kXWZYRZm4FZVe.patched.tz b/src/proto_alpha/lib_protocol/test/integration/michelson/patched_contracts/expru1ukk6ZqdA32rFYFG7j1eGjfsatbdUZWz8Mi1kXWZYRZm4FZVe.patched.tz index da23abebee..ab599c15b3 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/patched_contracts/expru1ukk6ZqdA32rFYFG7j1eGjfsatbdUZWz8Mi1kXWZYRZm4FZVe.patched.tz +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/patched_contracts/expru1ukk6ZqdA32rFYFG7j1eGjfsatbdUZWz8Mi1kXWZYRZm4FZVe.patched.tz @@ -720,7 +720,8 @@ DIP 3 { DUP } ; DIG 3 ; SWAP ; - SUB ; + SUB_MUTEZ ; + IF_NONE { PUSH string "negative mutez!"; FAILWITH } {} ; DIP { DUP ; CDR } ; DIP { DUP ; DIP { CAR } ; CDR } ; DIP { DUP ; DIP { CAR } ; CDR } ; @@ -1040,7 +1041,8 @@ DUP ; DIP { DIP { DUP ; CDR ; CDR ; CDR ; CDR } ; SWAP ; - SUB ; + SUB_MUTEZ ; + IF_NONE { PUSH string "negative mutez!"; FAILWITH } {} ; DIP { DUP ; CDR } ; DIP { DUP ; DIP { CAR } ; CDR } ; DIP { DUP ; DIP { CAR } ; CDR } ; @@ -1217,7 +1219,8 @@ DIP 2 { DUP } ; DIG 2 ; SWAP ; - SUB ; + SUB_MUTEZ ; + IF_NONE { PUSH string "negative mutez!"; FAILWITH } {} ; DIP { DUP ; CDR } ; DIP { DUP ; DIP { CAR } ; CDR } ; DIP { DUP ; DIP { CAR } ; CDR } ; diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/patched_contracts/expruZKjVy3JbWcJmjtnvMGvRamkDhMgM3urGGdne3pkN9VKgK7VnD.diff b/src/proto_alpha/lib_protocol/test/integration/michelson/patched_contracts/expruZKjVy3JbWcJmjtnvMGvRamkDhMgM3urGGdne3pkN9VKgK7VnD.diff index f0144a636a..361a8c8b83 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/patched_contracts/expruZKjVy3JbWcJmjtnvMGvRamkDhMgM3urGGdne3pkN9VKgK7VnD.diff +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/patched_contracts/expruZKjVy3JbWcJmjtnvMGvRamkDhMgM3urGGdne3pkN9VKgK7VnD.diff @@ -10,3 +10,13 @@ { DIP { { DIP { DUP @amt } ; SWAP } } ; SWAP } ; UNIT ; TRANSFER_TOKENS @op ; +@@ -396,7 +397,8 @@ + SWAP } } ; + SWAP } ; + { CDR ; CDR ; CDR ; CDR ; CDR ; CAR %inBaker } ; +- SUB ; ++ SUB_MUTEZ ; ++ IF_NONE { PUSH string "negative mutez!"; FAILWITH } {} ; + PAIR %inBaker ; + SWAP ; + PAIR %totalSupply ; diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/patched_contracts/expruZKjVy3JbWcJmjtnvMGvRamkDhMgM3urGGdne3pkN9VKgK7VnD.patched.tz b/src/proto_alpha/lib_protocol/test/integration/michelson/patched_contracts/expruZKjVy3JbWcJmjtnvMGvRamkDhMgM3urGGdne3pkN9VKgK7VnD.patched.tz index 265a4774c7..e6278f487b 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/patched_contracts/expruZKjVy3JbWcJmjtnvMGvRamkDhMgM3urGGdne3pkN9VKgK7VnD.patched.tz +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/patched_contracts/expruZKjVy3JbWcJmjtnvMGvRamkDhMgM3urGGdne3pkN9VKgK7VnD.patched.tz @@ -397,7 +397,8 @@ SWAP } } ; SWAP } ; { CDR ; CDR ; CDR ; CDR ; CDR ; CAR %inBaker } ; - SUB ; + SUB_MUTEZ ; + IF_NONE { PUSH string "negative mutez!"; FAILWITH } {} ; PAIR %inBaker ; SWAP ; PAIR %totalSupply ; diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/patched_contracts/exprubv5oQmAUP8BwktmDgMWqTizYDJVhzHhJESGZhJ2GkHESZ1VWg.diff b/src/proto_alpha/lib_protocol/test/integration/michelson/patched_contracts/exprubv5oQmAUP8BwktmDgMWqTizYDJVhzHhJESGZhJ2GkHESZ1VWg.diff index 522e993afb..1367b47d72 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/patched_contracts/exprubv5oQmAUP8BwktmDgMWqTizYDJVhzHhJESGZhJ2GkHESZ1VWg.diff +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/patched_contracts/exprubv5oQmAUP8BwktmDgMWqTizYDJVhzHhJESGZhJ2GkHESZ1VWg.diff @@ -18,7 +18,17 @@ PUSH mutez 0 ; DIG 3 ; SELF ; -@@ -746,7 +746,7 @@ +@@ -722,7 +722,8 @@ + DIP 3 { DUP } ; + DIG 3 ; + SWAP ; +- SUB ; ++ SUB_MUTEZ ; ++ IF_NONE { PUSH string "negative mutez!"; FAILWITH } {} ; + DIP { DUP ; CDR } ; + DIP { DUP ; DIP { CAR } ; CDR } ; + DIP { DUP ; DIP { CAR } ; CDR } ; +@@ -746,7 +747,7 @@ CDR ; CAR ; CONTRACT unit ; @@ -27,7 +37,7 @@ DIG 3 ; UNIT ; TRANSFER_TOKENS ; -@@ -757,7 +757,7 @@ +@@ -757,7 +758,7 @@ CAR ; CDR ; CONTRACT %transfer (pair address (pair address nat)) ; @@ -36,7 +46,7 @@ PUSH mutez 0 ; DIG 3 ; DIG 4 ; -@@ -888,7 +888,7 @@ +@@ -888,7 +889,7 @@ CAR ; CDR ; CONTRACT %transfer (pair address (pair address nat)) ; @@ -45,7 +55,17 @@ PUSH mutez 0 ; DIG 3 ; DIG 5 ; -@@ -1028,7 +1028,7 @@ +@@ -994,7 +995,8 @@ + DUP ; + DIP { DIP { DUP ; CDR ; CDR ; CDR ; CDR } ; + SWAP ; +- SUB ; ++ SUB_MUTEZ ; ++ IF_NONE { PUSH string "negative mutez!"; FAILWITH } {} ; + DIP { DUP ; CDR } ; + DIP { DUP ; DIP { CAR } ; CDR } ; + DIP { DUP ; DIP { CAR } ; CDR } ; +@@ -1028,7 +1030,7 @@ CAR ; CDR ; CONTRACT %transfer (pair address (pair address nat)) ; @@ -54,7 +74,17 @@ PUSH mutez 0 ; DIG 3 ; SELF ; -@@ -1168,7 +1168,7 @@ +@@ -1145,7 +1147,8 @@ + DIP 2 { DUP } ; + DIG 2 ; + SWAP ; +- SUB ; ++ SUB_MUTEZ ; ++ IF_NONE { PUSH string "negative mutez!"; FAILWITH } {} ; + DIP { DUP ; CDR } ; + DIP { DUP ; DIP { CAR } ; CDR } ; + DIP { DUP ; DIP { CAR } ; CDR } ; +@@ -1168,7 +1171,7 @@ CAR ; CAR ; CONTRACT %xtzToToken (pair address (pair nat timestamp)) ; @@ -63,7 +93,7 @@ DIG 2 ; DIP 3 { DUP } ; DIG 3 ; -@@ -1188,7 +1188,7 @@ +@@ -1188,7 +1191,7 @@ CAR ; CDR ; CONTRACT %transfer (pair address (pair address nat)) ; @@ -72,7 +102,7 @@ PUSH mutez 0 ; DIG 3 ; SELF ; -@@ -1241,7 +1241,7 @@ +@@ -1241,7 +1244,7 @@ CAR ; CDR ; CONTRACT %getBalance (pair address (contract nat)) ; diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/patched_contracts/exprubv5oQmAUP8BwktmDgMWqTizYDJVhzHhJESGZhJ2GkHESZ1VWg.patched.tz b/src/proto_alpha/lib_protocol/test/integration/michelson/patched_contracts/exprubv5oQmAUP8BwktmDgMWqTizYDJVhzHhJESGZhJ2GkHESZ1VWg.patched.tz index ae1bef1807..55f8a34a50 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/patched_contracts/exprubv5oQmAUP8BwktmDgMWqTizYDJVhzHhJESGZhJ2GkHESZ1VWg.patched.tz +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/patched_contracts/exprubv5oQmAUP8BwktmDgMWqTizYDJVhzHhJESGZhJ2GkHESZ1VWg.patched.tz @@ -722,7 +722,8 @@ DIP 3 { DUP } ; DIG 3 ; SWAP ; - SUB ; + SUB_MUTEZ ; + IF_NONE { PUSH string "negative mutez!"; FAILWITH } {} ; DIP { DUP ; CDR } ; DIP { DUP ; DIP { CAR } ; CDR } ; DIP { DUP ; DIP { CAR } ; CDR } ; @@ -994,7 +995,8 @@ DUP ; DIP { DIP { DUP ; CDR ; CDR ; CDR ; CDR } ; SWAP ; - SUB ; + SUB_MUTEZ ; + IF_NONE { PUSH string "negative mutez!"; FAILWITH } {} ; DIP { DUP ; CDR } ; DIP { DUP ; DIP { CAR } ; CDR } ; DIP { DUP ; DIP { CAR } ; CDR } ; @@ -1145,7 +1147,8 @@ DIP 2 { DUP } ; DIG 2 ; SWAP ; - SUB ; + SUB_MUTEZ ; + IF_NONE { PUSH string "negative mutez!"; FAILWITH } {} ; DIP { DUP ; CDR } ; DIP { DUP ; DIP { CAR } ; CDR } ; DIP { DUP ; DIP { CAR } ; CDR } ; diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_patched_contracts.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_patched_contracts.ml index 13e5d58f6b..b952cb4e9b 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_patched_contracts.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_patched_contracts.ml @@ -159,7 +159,7 @@ module Legacy_patch_test (Patches : LEGACY_SCRIPT_PATCHES) : return () let typecheck_patched_script code () = - (* Number 3 below controls how much accounts should be + (* Number 3 below controls how many accounts should be created. This number shouldn't be too small or the context won't have enough tokens to form a roll. *) let* (block, _) = Context.init 3 in From c693cf956f31d97ba7c11601d928afdec209e75d Mon Sep 17 00:00:00 2001 From: Romain Bardou Date: Wed, 16 Mar 2022 11:43:05 +0100 Subject: [PATCH 070/100] Tezt: add --title, same as --test --- tezt/lib/cli.ml | 17 +++++++++++++---- tezt/lib/regression.ml | 4 ++-- tezt/lib/test.ml | 8 ++++---- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/tezt/lib/cli.ml b/tezt/lib/cli.ml index 1a58c07c74..e918c03f3f 100644 --- a/tezt/lib/cli.ml +++ b/tezt/lib/cli.ml @@ -268,21 +268,30 @@ let init ?args () = Arg.String (fun file -> options.files_to_run <- file :: options.files_to_run), " Same as --file." ); - ( "--test", + ( "--title", Arg.String (fun title -> options.tests_to_run <- title :: options.tests_to_run), " Only run tests which are exactly entitled TITLE (see \ SELECTING TESTS)." ); + ( "--test", + Arg.String + (fun title -> options.tests_to_run <- title :: options.tests_to_run), + "<TITLE> Same as --title." ); ( "-t", Arg.String (fun title -> options.tests_to_run <- title :: options.tests_to_run), - "<TITLE> Same as --test." ); - ( "--not-test", + "<TITLE> Same as --title." ); + ( "--not-title", Arg.String (fun title -> options.tests_not_to_run <- title :: options.tests_not_to_run), "<TITLE> Only run tests which are not exactly entitled TITLE (see \ SELECTING TESTS)." ); + ( "--not-test", + Arg.String + (fun title -> + options.tests_not_to_run <- title :: options.tests_not_to_run), + "<TITLE> Same as --not-title." ); ( "--global-timeout", Arg.Float (fun delay -> options.global_timeout <- Some delay), "<SECONDS> Fail if the set of tests takes more than SECONDS to run." @@ -416,7 +425,7 @@ let init ?args () = negate a tag, prefix it with a slash: /\n\n\ \ The title of a test is given by the ~title argument of Test.run. It \ is what is printed after [SUCCESS] (or [FAILURE] or [ABORTED]) in the \ - reports. Use --test (respectively --not-test) to select (respectively \ + reports. Use --title (respectively --not-title) to select (respectively \ unselect) a test by its title on the command-line.\n\n\ \ The file in which a test is implemented is specified by the ~__FILE__ \ argument of Test.run. In other words, it is the name of the file in \ diff --git a/tezt/lib/regression.ml b/tezt/lib/regression.ml index 1ff4d11bb5..2fb310adfe 100644 --- a/tezt/lib/regression.ml +++ b/tezt/lib/regression.ml @@ -96,7 +96,7 @@ let register ~__FILE__ ~title ~tags ~output_file f = then Test.fail "Regression output file not found: %s. To generate it, use: \ - --reset-regressions --test %s" + --reset-regressions --title %s" (Log.quote_shell stored_output_file) (Log.quote_shell title) ; let capture_f ~output_file = @@ -144,7 +144,7 @@ let register ~__FILE__ ~title ~tags ~output_file f = log_regression_diff diff ; Test.fail "Regression output file contains differences: %s. To accept the \ - differences, use: --reset-regressions --test %s" + differences, use: --reset-regressions --title %s" (Log.quote_shell stored_output_file) (Log.quote_shell title)) diff --git a/tezt/lib/test.ml b/tezt/lib/test.ml index 77e3a40dd2..74ca705d32 100644 --- a/tezt/lib/test.ml +++ b/tezt/lib/test.ml @@ -662,7 +662,7 @@ let suggest_jobs () = (fun test -> Printf.sprintf "%s %s" - (if negate then "--not-test" else "--test") + (if negate then "--not-title" else "--title") (Log.quote_shell (test : test).title)) job_tests) ^ " # " @@ -1043,7 +1043,7 @@ let run () = List.iter (fun f -> f ()) !before_test_run_functions ; (* Check command-line options. *) check_existence "--file" known_files Cli.options.files_to_run ; - check_existence "--test" known_titles Cli.options.tests_to_run ; + check_existence "--title" known_titles Cli.options.tests_to_run ; check_existence "tag" known_tags @@ -1058,7 +1058,7 @@ let run () = (fun x -> "--file " ^ Log.quote_shell x) Cli.options.files_to_run @ List.map - (fun x -> "--test " ^ Log.quote_shell x) + (fun x -> "--title " ^ Log.quote_shell x) Cli.options.tests_to_run @ Cli.options.tags_to_run @ List.map (sf "/%s") Cli.options.tags_not_to_run)) ; @@ -1139,7 +1139,7 @@ let run () = test.session_successful_runs + single_seconds time) | Failed _ -> Log.report - "Try again with: %s --verbose --test %s" + "Try again with: %s --verbose --title %s" Sys.argv.(0) (Log.quote_shell test.title) ; test.session_failed_runs <- From f46eb231bfc8a9e77ab15b98a06ad818e540dc50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Thir=C3=A9?= <francois.thire@nomadic-labs.com> Date: Mon, 14 Mar 2022 14:54:51 +0100 Subject: [PATCH 071/100] Protocol/Tx_rollup: Implement the merklisation of inboxes --- src/proto_alpha/bin_tx_rollup_node/RPC.ml | 35 +-- src/proto_alpha/bin_tx_rollup_node/daemon.ml | 4 - src/proto_alpha/bin_tx_rollup_node/inbox.ml | 18 -- src/proto_alpha/bin_tx_rollup_node/inbox.mli | 10 - src/proto_alpha/bin_tx_rollup_node/l2block.ml | 12 +- .../bin_tx_rollup_node/l2block.mli | 2 - .../lib_client/client_proto_context.ml | 22 +- .../lib_client/client_proto_context.mli | 3 +- .../client_proto_context_commands.ml | 17 +- src/proto_alpha/lib_plugin/plugin.ml | 56 +++- src/proto_alpha/lib_protocol/TEZOS_PROTOCOL | 3 +- src/proto_alpha/lib_protocol/alpha_context.ml | 5 - .../lib_protocol/alpha_context.mli | 56 +--- src/proto_alpha/lib_protocol/apply.ml | 2 + src/proto_alpha/lib_protocol/dune.inc | 10 +- .../lib_protocol/operation_repr.ml | 8 +- .../lib_protocol/operation_repr.mli | 1 + src/proto_alpha/lib_protocol/raw_context.ml | 24 ++ src/proto_alpha/lib_protocol/raw_context.mli | 8 + src/proto_alpha/lib_protocol/storage.ml | 26 +- src/proto_alpha/lib_protocol/storage.mli | 47 +-- .../lib_protocol/test/helpers/op.ml | 4 +- .../lib_protocol/test/helpers/op.mli | 1 + .../integration/operations/test_tx_rollup.ml | 195 +++++++----- .../lib_protocol/tx_rollup_commitment_repr.ml | 22 +- .../tx_rollup_commitment_repr.mli | 2 +- .../tx_rollup_commitment_storage.ml | 12 +- .../lib_protocol/tx_rollup_errors_repr.ml | 15 +- .../lib_protocol/tx_rollup_inbox_repr.ml | 143 ++++----- .../lib_protocol/tx_rollup_inbox_repr.mli | 79 ++--- .../lib_protocol/tx_rollup_inbox_storage.ml | 155 +++------ .../lib_protocol/tx_rollup_inbox_storage.mli | 46 +-- .../lib_protocol/tx_rollup_prefixes.ml | 2 + .../lib_protocol/tx_rollup_prefixes.mli | 3 + .../lib_protocol/tx_rollup_repr.ml | 6 + .../lib_protocol/tx_rollup_repr.mli | 2 + .../_regressions/rpc/alpha.client.mempool.out | 62 +++- tezt/_regressions/rpc/alpha.proxy.mempool.out | 62 +++- .../_regressions/tx_rollup_batch_encoding.out | 41 ++- .../tx_rollup_finalize_commitment_future.out | 41 ++- ...tx_rollup_finalize_commitment_no_batch.out | 29 ++ ...llup_finalize_commitment_no_commitment.out | 41 ++- ..._rollup_finalize_too_recent_commitment.out | 48 ++- .../tx_rollup_limit_empty_batch.out | 41 ++- .../tx_rollup_limit_maximum_size_batch.out | 41 ++- .../tx_rollup_limit_maximum_size_inbox.out | 294 +++++++++--------- .../_regressions/tx_rollup_rpc_commitment.out | 46 ++- tezt/_regressions/tx_rollup_rpc_inbox.out | 46 ++- .../tx_rollup_rpc_inbox_merkle_tree_hash.out | 23 ++ .../tx_rollup_rpc_inbox_merkle_tree_path.out | 68 ++++ .../tx_rollup_rpc_inbox_message_hash.out | 8 + ..._rollup_rpc_pending_bonded_commitments.out | 43 ++- tezt/_regressions/tx_rollup_rpc_state.out | 29 ++ tezt/lib_tezos/RPC.ml | 55 ++++ tezt/lib_tezos/RPC.mli | 31 ++ tezt/lib_tezos/client.ml | 12 +- tezt/lib_tezos/client.mli | 4 +- tezt/lib_tezos/operation.ml | 14 +- tezt/lib_tezos/operation.mli | 2 + tezt/lib_tezos/rollup.ml | 68 +++- tezt/lib_tezos/rollup.mli | 24 +- tezt/tests/tx_rollup.ml | 181 ++++++++--- tezt/tests/tx_rollup_node.ml | 75 ++--- 63 files changed, 1576 insertions(+), 909 deletions(-) create mode 100644 tezt/_regressions/tx_rollup_rpc_inbox_merkle_tree_hash.out create mode 100644 tezt/_regressions/tx_rollup_rpc_inbox_merkle_tree_path.out create mode 100644 tezt/_regressions/tx_rollup_rpc_inbox_message_hash.out diff --git a/src/proto_alpha/bin_tx_rollup_node/RPC.ml b/src/proto_alpha/bin_tx_rollup_node/RPC.ml index a406b01271..6c3a05d898 100644 --- a/src/proto_alpha/bin_tx_rollup_node/RPC.ml +++ b/src/proto_alpha/bin_tx_rollup_node/RPC.ml @@ -168,21 +168,9 @@ module Block = struct RPC_service.get_service ~description:"Get the tx-rollup-node inbox for a given block" ~query:RPC_query.empty - ~output: - Data_encoding.( - option - @@ merge_objs - (obj1 (req "hash" Alpha_context.Tx_rollup_inbox.hash_encoding)) - Inbox.encoding) + ~output:Data_encoding.(option Inbox.encoding) RPC_path.(path / "inbox") - let proto_inbox = - RPC_service.get_service - ~description:"Get the tx-rollup-node \"protocol\" inbox for a given block" - ~query:RPC_query.empty - ~output:(Data_encoding.option Alpha_context.Tx_rollup_inbox.encoding) - RPC_path.(path / "proto_inbox") - let block_of_id state block_id = let open Lwt_syntax in match block_id with @@ -234,26 +222,7 @@ module Block = struct | `Tezos_block b when Block_hash.(block.header.tezos_block <> b) -> (* Tezos block has no l2 inbox *) return None - | _ -> - return - (Some (Inbox.hash_contents block.inbox.contents, block.inbox)) - )) - - let () = - register proto_inbox @@ fun (state, block_id) () () -> - let*! hash = block_of_id state block_id in - match hash with - | None -> return None - | Some hash -> ( - let*! block = State.get_block state hash in - match block with - | None -> return None - | Some block -> ( - match block_id with - | `Tezos_block b when Block_hash.(block.header.tezos_block <> b) -> - (* Tezos block has no l2 inbox *) - return None - | _ -> return (Some (Inbox.to_protocol_inbox block.inbox)))) + | _ -> return (Some block.inbox))) let build_directory state = !directory diff --git a/src/proto_alpha/bin_tx_rollup_node/daemon.ml b/src/proto_alpha/bin_tx_rollup_node/daemon.ml index 07df2de32b..29b342c8e3 100644 --- a/src/proto_alpha/bin_tx_rollup_node/daemon.ml +++ b/src/proto_alpha/bin_tx_rollup_node/daemon.ml @@ -238,11 +238,9 @@ let create_genesis_block state tezos_block = let open Lwt_result_syntax in let ctxt = Context.empty state.State.context_index in let*! context_hash = Context.commit ctxt in - let inbox_hash = Tx_rollup_inbox.hash_inbox [] in let header : L2block.header = { level = Genesis; - inbox_hash; tezos_block; predecessor = L2block.genesis_hash state.rollup; (* Genesis block is its own predecessor *) @@ -276,7 +274,6 @@ let process_messages_and_inboxes (state : State.t) return (predecessor, predecessor_context) | Some inbox -> let*! context_hash = Context.commit context in - let inbox_hash = Inbox.hash_contents inbox.contents in let level = match predecessor.level with | Genesis -> L2block.Rollup_level Tx_rollup_level.root @@ -285,7 +282,6 @@ let process_messages_and_inboxes (state : State.t) let header : L2block.header = { level; - inbox_hash; tezos_block = current_hash; predecessor = L2block.hash_header predecessor; context = context_hash; diff --git a/src/proto_alpha/bin_tx_rollup_node/inbox.ml b/src/proto_alpha/bin_tx_rollup_node/inbox.ml index d98feea738..24ac43b07b 100644 --- a/src/proto_alpha/bin_tx_rollup_node/inbox.ml +++ b/src/proto_alpha/bin_tx_rollup_node/inbox.ml @@ -28,8 +28,6 @@ open Protocol open Alpha_context -type hash = Tx_rollup_inbox.hash - type message_result = | Interpreted of Tx_rollup_l2_apply.Message_result.t | Discarded of tztrace @@ -79,19 +77,3 @@ let encoding = (obj2 (req "contents" @@ list message_encoding) (req "cumulated_size" int31)) - -let to_protocol_contents contents = - List.map - (fun {message; _} -> Tx_rollup_message.hash_uncarbonated message) - contents - -let hash_contents contents = - Tx_rollup_inbox.hash_inbox @@ List.map (fun {message; _} -> message) contents - -let to_protocol_inbox {contents; cumulated_size} = - Tx_rollup_inbox. - { - contents = to_protocol_contents contents; - cumulated_size; - hash = hash_contents contents; - } diff --git a/src/proto_alpha/bin_tx_rollup_node/inbox.mli b/src/proto_alpha/bin_tx_rollup_node/inbox.mli index 68c8099e2d..338aab426a 100644 --- a/src/proto_alpha/bin_tx_rollup_node/inbox.mli +++ b/src/proto_alpha/bin_tx_rollup_node/inbox.mli @@ -31,9 +31,6 @@ open Protocol open Alpha_context -(** Alias for type of inbox hashes *) -type hash = Tx_rollup_inbox.hash - (** Result of application of an inbox message *) type message_result = | Interpreted of Tx_rollup_l2_apply.Message_result.t @@ -53,15 +50,8 @@ type message = { hashed messages. *) type t = {contents : message list; cumulated_size : int} -(** [to_protocol_inbox node_inbox] will hash the contents of [node_inbox] to - produces an [Tx_rollup_inbox.t]. *) -val to_protocol_inbox : t -> Tx_rollup_inbox.t - (** Encoding for inbox messages *) val message_encoding : message Data_encoding.t (** Encoding for inboxes *) val encoding : t Data_encoding.t - -(** Hash contents of inbox. This gives the inbox hash. *) -val hash_contents : message list -> hash diff --git a/src/proto_alpha/bin_tx_rollup_node/l2block.ml b/src/proto_alpha/bin_tx_rollup_node/l2block.ml index 0dd526743e..0c553d04ba 100644 --- a/src/proto_alpha/bin_tx_rollup_node/l2block.ml +++ b/src/proto_alpha/bin_tx_rollup_node/l2block.ml @@ -47,7 +47,6 @@ type level = Genesis | Rollup_level of Tx_rollup_level.t type header = { level : level; - inbox_hash : Tx_rollup_inbox.hash; tezos_block : Block_hash.t; predecessor : hash; context : Tx_rollup_l2_context_hash.t; @@ -95,13 +94,12 @@ let level_to_string = function let header_encoding = let open Data_encoding in conv - (fun {level; inbox_hash; tezos_block; predecessor; context} -> - (level, inbox_hash, tezos_block, predecessor, context)) - (fun (level, inbox_hash, tezos_block, predecessor, context) -> - {level; inbox_hash; tezos_block; predecessor; context}) - (obj5 + (fun {level; tezos_block; predecessor; context} -> + (level, tezos_block, predecessor, context)) + (fun (level, tezos_block, predecessor, context) -> + {level; tezos_block; predecessor; context}) + (obj4 (req "level" level_encoding) - (req "inbox_hash" Tx_rollup_inbox.hash_encoding) (req "tezos_block" Block_hash.encoding) (req "predecessor" Hash.encoding) (req "context" Tx_rollup_l2_context_hash.encoding)) diff --git a/src/proto_alpha/bin_tx_rollup_node/l2block.mli b/src/proto_alpha/bin_tx_rollup_node/l2block.mli index 64830612be..1ef6de4439 100644 --- a/src/proto_alpha/bin_tx_rollup_node/l2block.mli +++ b/src/proto_alpha/bin_tx_rollup_node/l2block.mli @@ -44,8 +44,6 @@ type level = (** Type of L2 block headers *) type header = { level : level; (** The level of the L2 block *) - inbox_hash : Tx_rollup_inbox.hash; - (** The hash of the inbox's contents associated with this L2 block *) tezos_block : Block_hash.t; (** The Tezos block on which this L2 block in anchored, i.e. the Tezos block in which the inbox was sent *) diff --git a/src/proto_alpha/lib_client/client_proto_context.ml b/src/proto_alpha/lib_client/client_proto_context.ml index 2cb4b8f06e..6054f27455 100644 --- a/src/proto_alpha/lib_client/client_proto_context.ml +++ b/src/proto_alpha/lib_client/client_proto_context.ml @@ -864,8 +864,8 @@ let submit_tx_rollup_batch (cctxt : #full) ~chain ~block ?confirmations ?dry_run let submit_tx_rollup_commitment (cctxt : #full) ~chain ~block ?confirmations ?dry_run ?verbose_signing ?simulation ?fee ?gas_limit ?storage_limit - ?counter ~source ~src_pk ~src_sk ~fee_parameter ~level ~inbox_hash ~batches - ~predecessor ~tx_rollup () = + ?counter ~source ~src_pk ~src_sk ~fee_parameter ~level ~inbox_merkle_root + ~batches ~predecessor ~tx_rollup () = Environment.wrap_tzresult (Tx_rollup_level.of_int32 level) >>?= fun level -> List.map_es (fun root -> @@ -881,9 +881,12 @@ let submit_tx_rollup_commitment (cctxt : #full) ~chain ~block ?confirmations (fun pred_str -> Tx_rollup_commitment_hash.of_b58check_exn pred_str) predecessor in - let inbox_hash = Tx_rollup_inbox.hash_of_b58check_exn inbox_hash in + (match Tx_rollup_inbox.Merkle.root_of_b58check_opt inbox_merkle_root with + | Some content -> return content + | None -> failwith "%s is not a valid inbox merkle root" inbox_merkle_root) + >>=? fun inbox_merkle_root -> let commitment : Tx_rollup_commitment.t = - {level; messages; predecessor; inbox_hash} + {level; messages; predecessor; inbox_merkle_root} in let contents : Kind.tx_rollup_commit Annotated_manager_operation.annotated_list = @@ -991,7 +994,8 @@ let submit_tx_rollup_remove_commitment (cctxt : #full) ~chain ~block let submit_tx_rollup_rejection (cctxt : #full) ~chain ~block ?confirmations ?dry_run ?verbose_signing ?simulation ?fee ?gas_limit ?storage_limit ?counter ~source ~src_pk ~src_sk ~fee_parameter ~level ~tx_rollup ~message - ~message_position ~context_hash ~withdrawals_merkle_root ~proof () = + ~message_position ~message_path ~context_hash ~withdrawals_merkle_root + ~proof () = (match Data_encoding.Json.from_string message with | Ok json -> return json | Error err -> failwith "Message is not a valid JSON-encoded message: %s" err) @@ -1013,6 +1017,13 @@ let submit_tx_rollup_rejection (cctxt : #full) ~chain ~block ?confirmations "%s is not a valid notation for a withdraw list hash" withdrawals_merkle_root) >>=? fun withdrawals_merkle_root -> + (match Data_encoding.Json.from_string message_path with + | Ok json -> + Data_encoding.Json.destruct Tx_rollup_inbox.Merkle.path_encoding json + |> return + | Error err -> + failwith "Message path is not a valid JSON-encoded message: %s" err) + >>=? fun message_path -> let contents : Kind.tx_rollup_rejection Annotated_manager_operation.annotated_list = Annotated_manager_operation.Single_manager @@ -1026,6 +1037,7 @@ let submit_tx_rollup_rejection (cctxt : #full) ~chain ~block ?confirmations level; message; message_position; + message_path; previous_message_result = {context_hash; withdrawals_merkle_root}; proof; })) diff --git a/src/proto_alpha/lib_client/client_proto_context.mli b/src/proto_alpha/lib_client/client_proto_context.mli index effd467ea0..c5de55c8da 100644 --- a/src/proto_alpha/lib_client/client_proto_context.mli +++ b/src/proto_alpha/lib_client/client_proto_context.mli @@ -485,7 +485,7 @@ val submit_tx_rollup_commitment : src_sk:Client_keys.sk_uri -> fee_parameter:Injection.fee_parameter -> level:int32 -> - inbox_hash:string -> + inbox_merkle_root:string -> batches:string -> predecessor:string option -> tx_rollup:Tx_rollup.t -> @@ -565,6 +565,7 @@ val submit_tx_rollup_rejection : tx_rollup:Tx_rollup.t -> message:string -> message_position:int -> + message_path:string -> context_hash:string -> withdrawals_merkle_root:string -> proof:bool -> diff --git a/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml b/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml index 27e272bc01..073933ddb0 100644 --- a/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml +++ b/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml @@ -2271,10 +2271,8 @@ let commands_rw () = ~desc:"The level" Client_proto_args.int_parameter @@ Clic.param - ~name:"inbox_hash" - ~desc: - "the hash of the inbox to commit to, in b58check notation \ - (starting with the prefix i)." + ~name:"inbox_merkle_root" + ~desc:"the inbox merkle root to commit to in b58check notation." Client_proto_args.string_parameter @@ Clic.param ~name:"predecessor" @@ -2306,7 +2304,7 @@ let commands_rw () = fee_cap, burn_cap ) level - inbox_hash + inbox_merkle_root predecessor batches tx_rollup @@ -2349,7 +2347,7 @@ let commands_rw () = ~fee_parameter ~tx_rollup ~level - ~inbox_hash + ~inbox_merkle_root ~batches ~predecessor () @@ -2528,6 +2526,11 @@ let commands_rw () = ~name:"message_position" ~desc:"position of the message being rejected in the inbox" int_parameter + @@ prefix "and" @@ prefix "path" + @@ Clic.param + ~name:"message_path" + ~desc:"merkle path of the message being rejected in the inbox" + string_parameter @@ prefix "with" @@ prefix "proof" @@ tx_rollup_proof_param @@ prefixes ["with"; "agreed"; "context"; "hash"] @@ Clic.param @@ -2559,6 +2562,7 @@ let commands_rw () = level message message_position + message_path proof context_hash withdrawals_merkle_root @@ -2601,6 +2605,7 @@ let commands_rw () = ~level ~message ~message_position + ~message_path ~proof ~context_hash ~withdrawals_merkle_root diff --git a/src/proto_alpha/lib_plugin/plugin.ml b/src/proto_alpha/lib_plugin/plugin.ml index 8e353635a1..5d5426addd 100644 --- a/src/proto_alpha/lib_plugin/plugin.ml +++ b/src/proto_alpha/lib_plugin/plugin.ml @@ -3024,6 +3024,45 @@ module RPC = struct LB_pass)) ~output:(obj1 (req "protocol_data" bytes)) RPC_path.(path / "protocol_data") + + module Tx_rollup = struct + open Data_encoding + + let path = RPC_path.(path / "tx_rollup") + + module Inbox = struct + let path = RPC_path.(path / "inbox") + + let message_hash = + RPC_service.post_service + ~description:"Compute the hash of a message" + ~query:RPC_query.empty + ~input:(obj1 (req "message" Tx_rollup_message.encoding)) + ~output:(obj1 (req "hash" Tx_rollup_message.hash_encoding)) + RPC_path.(path / "message_hash") + + let merkle_tree_hash = + RPC_service.post_service + ~description:"Compute the merkle tree hash of an inbox" + ~query:RPC_query.empty + ~input: + (obj1 + (req "message_hashes" (list Tx_rollup_message.hash_encoding))) + ~output:(obj1 (req "hash" Tx_rollup_inbox.Merkle.root_encoding)) + RPC_path.(path / "merkle_tree_hash") + + let merkle_tree_path = + RPC_service.post_service + ~description:"Compute a path of an inbox message in a merkle tree" + ~query:RPC_query.empty + ~input: + (obj2 + (req "message_hashes" (list Tx_rollup_message.hash_encoding)) + (req "position" int16)) + ~output:(obj1 (req "path" Tx_rollup_inbox.Merkle.path_encoding)) + RPC_path.(path / "merkle_tree_path") + end + end end let register () = @@ -3055,7 +3094,22 @@ module RPC = struct seed_nonce_hash; proof_of_work_nonce; liquidity_baking_toggle_vote; - })) + })) ; + Registration.register0_noctxt + ~chunked:true + S.Tx_rollup.Inbox.message_hash + (fun () message -> return (Tx_rollup_message.hash_uncarbonated message)) ; + Registration.register0_noctxt + ~chunked:true + S.Tx_rollup.Inbox.merkle_tree_hash + (fun () message_hashes -> + return (Tx_rollup_inbox.Merkle.merklize_list message_hashes)) ; + Registration.register0_noctxt + ~chunked:true + S.Tx_rollup.Inbox.merkle_tree_path + (fun () (message_hashes, position) -> + Lwt.return + (Tx_rollup_inbox.Merkle.compute_path message_hashes position)) module Manager = struct let[@coq_axiom_with_reason "cast on e"] operations ctxt block ~branch diff --git a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL index 0f4d060409..21c4ccf2ff 100644 --- a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL +++ b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL @@ -14,6 +14,7 @@ "Block_payload_hash", "Origination_nonce", "Tx_rollup_prefixes", + "Merkle_list", "Slot_repr", "Tez_repr", @@ -184,8 +185,6 @@ "Tx_rollup_services", "Alpha_services", - "Merkle_list", - "Main" ] } diff --git a/src/proto_alpha/lib_protocol/alpha_context.ml b/src/proto_alpha/lib_protocol/alpha_context.ml index 585aea7b0d..165d5d20bf 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.ml +++ b/src/proto_alpha/lib_protocol/alpha_context.ml @@ -295,11 +295,6 @@ end module Tx_rollup_inbox = struct include Tx_rollup_inbox_repr include Tx_rollup_inbox_storage - - module Internal_for_tests = struct - include Tx_rollup_inbox_repr - include Tx_rollup_inbox_storage - end end module Tx_rollup_commitment = struct diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index cf947263bc..bc7d9cffe9 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -1725,37 +1725,25 @@ end (** This module re-exports definitions from {!Tx_rollup_inbox_repr} and {!Tx_rollup_inbox_storage}. *) module Tx_rollup_inbox : sig - type hash - - type t = { - contents : Tx_rollup_message.hash list; - cumulated_size : int; - hash : hash; - } - - val compare_hash : hash -> hash -> int + module Merkle : sig + type root - val equal_hash : hash -> hash -> bool + type path - val pp_hash : Format.formatter -> hash -> unit - - val hash_of_bytes_exn : bytes -> hash - - val hash_of_bytes_opt : bytes -> hash option + val path_encoding : path Data_encoding.t - val hash_of_b58check_exn : string -> hash + val root_encoding : root Data_encoding.t - val hash_of_b58check_opt : string -> hash option - - val hash_encoding : hash Data_encoding.t + val root_of_b58check_opt : string -> root option - val hash_to_bytes : hash -> bytes + val compute_path : Tx_rollup_message.hash list -> int -> path tzresult - val hash_to_b58check : hash -> string + val merklize_list : Tx_rollup_message.hash list -> root + end - val extend_hash : hash -> Tx_rollup_message.hash -> hash + type t = {inbox_length : int; cumulated_size : int; merkle_root : Merkle.root} - val hash_inbox : Tx_rollup_message.t list -> hash + val ( = ) : t -> t -> bool val pp : Format.formatter -> t -> unit @@ -1768,12 +1756,6 @@ module Tx_rollup_inbox : sig Tx_rollup_message.t -> (context * Tx_rollup_state.t) tzresult Lwt.t - val message_hashes : - context -> - Tx_rollup_level.t -> - Tx_rollup.t -> - (context * Tx_rollup_message.hash list) tzresult Lwt.t - val size : context -> Tx_rollup_level.t -> @@ -1795,17 +1777,8 @@ module Tx_rollup_inbox : sig Tx_rollup.t -> position:int -> Tx_rollup_message.t -> + Merkle.path -> context tzresult Lwt.t - - module Internal_for_tests : sig - type metadata = {inbox_length : int32; cumulated_size : int; hash : hash} - - val get_metadata : - context -> - Tx_rollup_level.t -> - Tx_rollup.t -> - (context * metadata) tzresult Lwt.t - end end (** This simply re-exports [Tx_rollup_commitment_repr] *) @@ -1826,7 +1799,7 @@ module Tx_rollup_commitment : sig level : Tx_rollup_level.t; messages : Tx_rollup_message_result_hash.t list; predecessor : Tx_rollup_commitment_hash.t option; - inbox_hash : Tx_rollup_inbox.hash; + inbox_merkle_root : Tx_rollup_inbox.Merkle.root; } include Compare.S with type t := t @@ -1970,7 +1943,7 @@ module Tx_rollup_errors : sig position : int; length : int; } - | Wrong_message_hash + | Wrong_message_path of {expected : Tx_rollup_inbox.Merkle.root} | No_finalized_commitment_for_level of { level : Tx_rollup_level.t; window : (Tx_rollup_level.t * Tx_rollup_level.t) option; @@ -2860,6 +2833,7 @@ and _ manager_operation = level : Tx_rollup_level.t; message : Tx_rollup_message.t; message_position : int; + message_path : Tx_rollup_inbox.Merkle.path; previous_message_result : Tx_rollup_commitment.message_result; proof : Tx_rollup_l2_proof.t; } diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index 49284944c6..ab2b6ae961 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -1709,6 +1709,7 @@ let apply_external_manager_operation_content : message; previous_message_result; message_position; + message_path; } -> Tx_rollup_state.get ctxt tx_rollup >>=? fun (ctxt, state) -> (* Check [level] *) @@ -1742,6 +1743,7 @@ let apply_external_manager_operation_content : tx_rollup ~position:message_position message + message_path >>=? fun ctxt -> (* Check [proof] *) Tx_rollup_l2_verifier.verify_proof diff --git a/src/proto_alpha/lib_protocol/dune.inc b/src/proto_alpha/lib_protocol/dune.inc index de7d31cf75..9460ba726d 100644 --- a/src/proto_alpha/lib_protocol/dune.inc +++ b/src/proto_alpha/lib_protocol/dune.inc @@ -40,6 +40,7 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end block_payload_hash.mli block_payload_hash.ml origination_nonce.mli origination_nonce.ml tx_rollup_prefixes.mli tx_rollup_prefixes.ml + merkle_list.mli merkle_list.ml slot_repr.mli slot_repr.ml tez_repr.mli tez_repr.ml period_repr.mli period_repr.ml @@ -195,7 +196,6 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end voting_services.mli voting_services.ml tx_rollup_services.mli tx_rollup_services.ml alpha_services.mli alpha_services.ml - merkle_list.mli merkle_list.ml main.mli main.ml (:src_dir TEZOS_PROTOCOL)) (action @@ -217,6 +217,7 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end block_payload_hash.mli block_payload_hash.ml origination_nonce.mli origination_nonce.ml tx_rollup_prefixes.mli tx_rollup_prefixes.ml + merkle_list.mli merkle_list.ml slot_repr.mli slot_repr.ml tez_repr.mli tez_repr.ml period_repr.mli period_repr.ml @@ -372,7 +373,6 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end voting_services.mli voting_services.ml tx_rollup_services.mli tx_rollup_services.ml alpha_services.mli alpha_services.ml - merkle_list.mli merkle_list.ml main.mli main.ml (:src_dir TEZOS_PROTOCOL)) (action (with-stdout-to %{targets} @@ -394,6 +394,7 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end block_payload_hash.mli block_payload_hash.ml origination_nonce.mli origination_nonce.ml tx_rollup_prefixes.mli tx_rollup_prefixes.ml + merkle_list.mli merkle_list.ml slot_repr.mli slot_repr.ml tez_repr.mli tez_repr.ml period_repr.mli period_repr.ml @@ -549,7 +550,6 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end voting_services.mli voting_services.ml tx_rollup_services.mli tx_rollup_services.ml alpha_services.mli alpha_services.ml - merkle_list.mli merkle_list.ml main.mli main.ml) (action (write-file %{targets} @@ -593,6 +593,7 @@ include Tezos_raw_protocol_alpha.Main Block_payload_hash Origination_nonce Tx_rollup_prefixes + Merkle_list Slot_repr Tez_repr Period_repr @@ -748,7 +749,6 @@ include Tezos_raw_protocol_alpha.Main Voting_services Tx_rollup_services Alpha_services - Merkle_list Main)) (install @@ -811,6 +811,7 @@ include Tezos_raw_protocol_alpha.Main block_payload_hash.mli block_payload_hash.ml origination_nonce.mli origination_nonce.ml tx_rollup_prefixes.mli tx_rollup_prefixes.ml + merkle_list.mli merkle_list.ml slot_repr.mli slot_repr.ml tez_repr.mli tez_repr.ml period_repr.mli period_repr.ml @@ -966,7 +967,6 @@ include Tezos_raw_protocol_alpha.Main voting_services.mli voting_services.ml tx_rollup_services.mli tx_rollup_services.ml alpha_services.mli alpha_services.ml - merkle_list.mli merkle_list.ml main.mli main.ml (:src_dir TEZOS_PROTOCOL)) (action (run %{bin:tezos-protocol-compiler} -no-hash-check .))) diff --git a/src/proto_alpha/lib_protocol/operation_repr.ml b/src/proto_alpha/lib_protocol/operation_repr.ml index 468e530e92..24cf9a9377 100644 --- a/src/proto_alpha/lib_protocol/operation_repr.ml +++ b/src/proto_alpha/lib_protocol/operation_repr.ml @@ -321,6 +321,7 @@ and _ manager_operation = level : Tx_rollup_level_repr.t; message : Tx_rollup_message_repr.t; message_position : int; + message_path : Tx_rollup_inbox_repr.Merkle.path; previous_message_result : Tx_rollup_commitment_repr.message_result; proof : Tx_rollup_l2_proof.t; } @@ -713,11 +714,12 @@ module Encoding = struct tag = tx_rollup_operation_rejection_tag; name = "tx_rollup_rejection"; encoding = - obj6 + obj7 (req "rollup" Tx_rollup_repr.encoding) (req "level" Tx_rollup_level_repr.encoding) (req "message" Tx_rollup_message_repr.encoding) (req "message_position" n) + (req "message_path" Tx_rollup_inbox_repr.Merkle.path_encoding) (req "previous_message_result" Tx_rollup_commitment_repr.message_result_encoding) @@ -733,6 +735,7 @@ module Encoding = struct level; message; message_position; + message_path; previous_message_result; proof; } -> @@ -740,6 +743,7 @@ module Encoding = struct level, message, Z.of_int message_position, + message_path, previous_message_result, proof )); inj = @@ -747,6 +751,7 @@ module Encoding = struct level, message, message_position, + message_path, previous_message_result, proof ) -> Tx_rollup_rejection @@ -755,6 +760,7 @@ module Encoding = struct level; message; message_position = Z.to_int message_position; + message_path; previous_message_result; proof; }); diff --git a/src/proto_alpha/lib_protocol/operation_repr.mli b/src/proto_alpha/lib_protocol/operation_repr.mli index e86162b789..19d787633d 100644 --- a/src/proto_alpha/lib_protocol/operation_repr.mli +++ b/src/proto_alpha/lib_protocol/operation_repr.mli @@ -366,6 +366,7 @@ and _ manager_operation = level : Tx_rollup_level_repr.t; message : Tx_rollup_message_repr.t; message_position : int; + message_path : Tx_rollup_inbox_repr.Merkle.path; previous_message_result : Tx_rollup_commitment_repr.message_result; proof : Tx_rollup_l2_proof.t; } diff --git a/src/proto_alpha/lib_protocol/raw_context.ml b/src/proto_alpha/lib_protocol/raw_context.ml index 8ff9fe29f3..fc27377f97 100644 --- a/src/proto_alpha/lib_protocol/raw_context.ml +++ b/src/proto_alpha/lib_protocol/raw_context.ml @@ -227,6 +227,8 @@ type back = { Cycle_repr.Map.t; stake_distribution_for_current_cycle : Tez_repr.t Signature.Public_key_hash.Map.t option; + tx_rollup_current_messages : + Tx_rollup_inbox_repr.Merkle.tree Tx_rollup_repr.Map.t; } (* @@ -782,6 +784,7 @@ let prepare ~level ~predecessor_timestamp ~timestamp ctxt = non_consensus_operations_rev = []; sampler_state = Cycle_repr.Map.empty; stake_distribution_for_current_cycle = None; + tx_rollup_current_messages = Tx_rollup_repr.Map.empty; }; } @@ -1325,3 +1328,24 @@ module Consensus : update_consensus_with ctxt (fun ctxt -> Raw_consensus.set_grand_parent_branch ctxt branch) end + +module Tx_rollup = struct + let add_message ctxt rollup message = + let root = ref Tx_rollup_inbox_repr.Merkle.(root empty) in + let updater element = + let tree = + Option.value element ~default:Tx_rollup_inbox_repr.Merkle.(empty) + in + let tree = Tx_rollup_inbox_repr.Merkle.add_message tree message in + root := Tx_rollup_inbox_repr.Merkle.root tree ; + Some tree + in + let map = + Tx_rollup_repr.Map.update + rollup + updater + ctxt.back.tx_rollup_current_messages + in + let back = {ctxt.back with tx_rollup_current_messages = map} in + ({ctxt with back}, !root) +end diff --git a/src/proto_alpha/lib_protocol/raw_context.mli b/src/proto_alpha/lib_protocol/raw_context.mli index cc706de324..8491761ec3 100644 --- a/src/proto_alpha/lib_protocol/raw_context.mli +++ b/src/proto_alpha/lib_protocol/raw_context.mli @@ -356,3 +356,11 @@ module Consensus : and type 'a slot_map := 'a Slot_repr.Map.t and type slot_set := Slot_repr.Set.t and type round := Round_repr.t + +module Tx_rollup : sig + val add_message : + t -> + Tx_rollup_repr.t -> + Tx_rollup_message_repr.hash -> + t * Tx_rollup_inbox_repr.Merkle.root +end diff --git a/src/proto_alpha/lib_protocol/storage.ml b/src/proto_alpha/lib_protocol/storage.ml index d9b03f7b74..58f94546e8 100644 --- a/src/proto_alpha/lib_protocol/storage.ml +++ b/src/proto_alpha/lib_protocol/storage.ml @@ -1421,19 +1421,19 @@ module Tx_rollup = struct Make_indexed_subcontext (Make_subcontext (Registered) (Level_context.Raw_context) (struct - let name = ["tx_rollup"] + let name = ["tx_rollup_by_level"] end)) (Make_index (Tx_rollup_repr.Index)) - module Inbox_metadata = + module Inbox = Level_tx_rollup_context.Make_carbonated_map (struct - let name = ["inbox_size"] + let name = ["inbox"] end) (struct - type t = Tx_rollup_inbox_repr.metadata + type t = Tx_rollup_inbox_repr.t - let encoding = Tx_rollup_inbox_repr.metadata_encoding + let encoding = Tx_rollup_inbox_repr.encoding end) module Int32_index = struct @@ -1463,22 +1463,6 @@ module Tx_rollup = struct (Make_index (Int32_index)) (Tx_rollup_withdraw_repr.Withdrawal_accounting) - module Message_indexed_context = - Make_subcontext (Registered) (Level_tx_rollup_context.Raw_context) - (struct - let name = ["inbox_contents"] - end) - - module Inbox_contents = - Make_indexed_carbonated_data_storage - (Message_indexed_context) - (Make_index (Int32_index)) - (struct - type t = Tx_rollup_message_repr.hash - - let encoding = Tx_rollup_message_repr.hash_encoding - end) - module Level_indexed_context = Make_indexed_subcontext (Make_subcontext (Registered) (Raw_context) diff --git a/src/proto_alpha/lib_protocol/storage.mli b/src/proto_alpha/lib_protocol/storage.mli index 85cbaa74bf..4adfe7ce44 100644 --- a/src/proto_alpha/lib_protocol/storage.mli +++ b/src/proto_alpha/lib_protocol/storage.mli @@ -615,14 +615,13 @@ module Tx_rollup : sig and type value = Tx_rollup_state_repr.t and type t := Raw_context.t - (** Each inbox has a set of metadata attached to it. See - {!Tx_rollup_inbox_repr.metadata} for a description of the actual - content. *) - module Inbox_metadata : + (** The representation of an inbox. See {!Tx_rollup_inbox_repr.t} + for a description of the actual content. *) + module Inbox : Non_iterable_indexed_carbonated_data_storage with type t := Raw_context.t * Tx_rollup_level_repr.t and type key = Tx_rollup_repr.t - and type value = Tx_rollup_inbox_repr.metadata + and type value = Tx_rollup_inbox_repr.t (** A carbonated storage of the set of withdrawals consumed of those potentially associated to each message @@ -634,40 +633,7 @@ module Tx_rollup : sig and type key = int32 and type value = Tx_rollup_withdraw_repr.Withdrawal_accounting.t - (** A carbonated storage to store the hashes of the messages - appended in an inbox. The key is the batch number, which is - sequentially assigned from 0. - - The actual content is already stored in the block (as part of - the operations), so by only storing the hashes we avoid - unnecessary storage duplication. *) - module Inbox_contents : sig - include - Non_iterable_indexed_carbonated_data_storage - with type t := - (Raw_context.t * Tx_rollup_level_repr.t) * Tx_rollup_repr.t - and type key = int32 - and type value = Tx_rollup_message_repr.hash - - (** [list_values ?offset ?length ((ctxt, tx_level), rollup)] - returns the list of message hashes of the inbox of [rollup] at - [tx_level]. - - [length] and [offset] can be used to retrieve a subset of the - result. [length] is the maximum number of elements to fetch. A - negative [length] produces an empty list of results. [offset] - is the number of elements to ignore. If [offset] is negative, - then it is treated as if it were equal to [0]. - - {b: Note:} This is the same HACK as [Big_map.Contents]. **) - val list_values : - ?offset:int -> - ?length:int -> - (Raw_context.t * Tx_rollup_level_repr.t) * Tx_rollup_repr.t -> - (Raw_context.t * Tx_rollup_message_repr.hash list) tzresult Lwt.t - end - - (* A rollup can have at most one commitment per rollup level. Some + (** A rollup can have at most one commitment per rollup level. Some metadata are saved in addition to the commitment itself. See {!Tx_rollup_commitment_repr.Submitted_commitment.t} for the exact content. *) @@ -677,13 +643,12 @@ module Tx_rollup : sig and type value = Tx_rollup_commitment_repr.Submitted_commitment.t and type t := Raw_context.t - (* This stores information about which contracts have bonds + (** This stores information about which contracts have bonds for each rollup, and how many commitments those bonds stake. *) module Commitment_bond : Non_iterable_indexed_carbonated_data_storage with type key = Tx_rollup_repr.t * Signature.public_key_hash - (* The value here is the number of unfinalized commitments *) and type value = int and type t := Raw_context.t end diff --git a/src/proto_alpha/lib_protocol/test/helpers/op.ml b/src/proto_alpha/lib_protocol/test/helpers/op.ml index 9b087d3f4d..8dcfec4200 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/op.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/op.ml @@ -640,7 +640,8 @@ let tx_rollup_withdraw ?counter ?fee ?gas_limit ?storage_limit ctxt let tx_rollup_reject ?counter ?fee ?gas_limit ?storage_limit ctxt (source : Contract.t) (tx_rollup : Tx_rollup.t) (level : Tx_rollup_level.t) - (message : Tx_rollup_message.t) ~(message_position : int) ~(proof : bool) + (message : Tx_rollup_message.t) ~(message_position : int) + ~(message_path : Tx_rollup_inbox.Merkle.path) ~(proof : bool) ~(previous_message_result : Tx_rollup_commitment.message_result) = manager_operation ?counter @@ -655,6 +656,7 @@ let tx_rollup_reject ?counter ?fee ?gas_limit ?storage_limit ctxt level; message; message_position; + message_path; proof; previous_message_result; }) diff --git a/src/proto_alpha/lib_protocol/test/helpers/op.mli b/src/proto_alpha/lib_protocol/test/helpers/op.mli index b4aa981b5e..267f857997 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/op.mli +++ b/src/proto_alpha/lib_protocol/test/helpers/op.mli @@ -352,6 +352,7 @@ val tx_rollup_reject : Tx_rollup_level.t -> Tx_rollup_message.t -> message_position:int -> + message_path:Tx_rollup_inbox.Merkle.path -> proof:bool -> previous_message_result:Tx_rollup_commitment.message_result -> Operation.packed tzresult Lwt.t diff --git a/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml b/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml index 0fe2d435fb..67e963c2e8 100644 --- a/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml +++ b/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml @@ -146,25 +146,6 @@ let inbox_burn state size = the inbox. *) let burn_per_byte state = inbox_burn state 1 -(** [check_batch_in_inbox inbox n expected] checks that the [n]th - element of [inbox] is a batch equal to [expected]. *) -let check_batch_in_inbox : - t -> Tx_rollup_inbox.t -> int -> string -> unit tzresult Lwt.t = - fun ctxt inbox n expected -> - let (expected_batch, _) = Tx_rollup_message.make_batch expected in - Environment.wrap_tzresult (Tx_rollup_message.hash ctxt expected_batch) - >>?= fun (_ctxt, expected_hash) -> - match List.nth inbox.contents n with - | Some content -> - Alcotest.( - check - message_hash_testable - "Expected batch with a different content" - content - expected_hash) ; - return_unit - | _ -> Alcotest.fail "Selected message in the inbox is not a batch" - (** [context_init n] initializes a context with no consensus rewards to not interfere with balances prediction. It returns the created context and [n] contracts. *) @@ -243,8 +224,7 @@ let public_key_hash_testable = let raw_level_testable = Alcotest.testable Raw_level.pp Raw_level.( = ) -let inbox_hash_testable = - Alcotest.testable Tx_rollup_inbox.pp_hash Tx_rollup_inbox.equal_hash +let inbox_testable = Alcotest.testable Tx_rollup_inbox.pp Tx_rollup_inbox.( = ) let rng_state = Random.State.make_self_init () @@ -312,16 +292,10 @@ let merkle_root_empty_withdraw_list = Tx_rollup_withdraw.merkelize_list [] is expensive *) let make_commitment_for_batch i level tx_rollup withdraw_list = let ctxt = Incremental.alpha_ctxt i in - wrap - (Alpha_context.Tx_rollup_inbox.Internal_for_tests.get_metadata - ctxt - level - tx_rollup) + wrap (Alpha_context.Tx_rollup_inbox.get ctxt level tx_rollup) >>=? fun (ctxt, metadata) -> - List.init - ~when_negative_length:[] - (Int32.to_int metadata.inbox_length) - (fun _ -> Tx_rollup_commitment.empty_l2_context_hash) + List.init ~when_negative_length:[] metadata.inbox_length (fun _ -> + Tx_rollup_commitment.empty_l2_context_hash) >>?= fun batches_result -> let messages = List.mapi @@ -344,8 +318,9 @@ let make_commitment_for_batch i level tx_rollup withdraw_list = | (_, Some {commitment; _}) -> Some (Tx_rollup_commitment.hash commitment) )) >>=? fun predecessor -> + let inbox_merkle_root = metadata.merkle_root in let commitment : Tx_rollup_commitment.t = - {level; messages; predecessor; inbox_hash = metadata.hash} + {level; messages; predecessor; inbox_merkle_root} in return (commitment, batches_result) @@ -544,16 +519,20 @@ let test_add_batch () = let contents = String.make contents_size 'c' in init_originate_and_submit ~batch:contents () >>=? fun ((contract, balance), state, tx_rollup, b) -> - Context.Tx_rollup.inbox (B b) tx_rollup Tx_rollup_level.root - >>=? fun {contents; cumulated_size; hash} -> - let length = List.length contents in - let expected_hash = - Tx_rollup_inbox.hash_of_b58check_exn - "txi369dxdaFA9LzUXUcY4MHafPDizuLnrHXuQzRXQyrPGFdMu3Eq3" + Context.Tx_rollup.inbox (B b) tx_rollup Tx_rollup_level.root >>=? fun inbox -> + let contents_hash = + Tx_rollup_message.(make_batch contents |> fst |> hash_uncarbonated) + in + let merkle_root = Tx_rollup_inbox.Merkle.merklize_list [contents_hash] in + let expected_inbox = + Tx_rollup_inbox. + {inbox_length = 1; cumulated_size = contents_size; merkle_root} in - Alcotest.(check int "Expect an inbox with a single item" 1 length) ; - Alcotest.(check int "Expect cumulated size" contents_size cumulated_size) ; - Alcotest.(check inbox_hash_testable "Expect hash" expected_hash hash) ; + Alcotest.check + inbox_testable + "Expected inbox is not the computed one" + expected_inbox + inbox ; inbox_burn state contents_size >>?= fun cost -> Assert.balance_was_debited ~loc:__LOC__ (B b) contract balance cost @@ -604,22 +583,28 @@ let test_add_two_batches () = its successor. *) Context.Tx_rollup.inbox (B b) tx_rollup Tx_rollup_level.(succ root) >>=? fun inbox -> - let length = List.length inbox.contents in - let expected_cumulated_size = contents_size1 + contents_size2 in - - Alcotest.(check int "Expect an inbox with two items" 2 length) ; + Incremental.begin_construction b >>=? fun _incr -> + let contents1_hash = + Tx_rollup_message.hash_uncarbonated + (Tx_rollup_message.make_batch contents1 |> fst) + in + let contents2_hash = + Tx_rollup_message.hash_uncarbonated + (Tx_rollup_message.make_batch contents2 |> fst) + in + let merkle_root = + Tx_rollup_inbox.Merkle.merklize_list [contents1_hash; contents2_hash] + in + let expected_inbox = + Tx_rollup_inbox.{inbox_length = 2; cumulated_size = 5 + 6; merkle_root} + in Alcotest.( check - int - "Expect cumulated size" - expected_cumulated_size - inbox.cumulated_size) ; - - Incremental.begin_construction b >>=? fun incr -> - let ctxt = Incremental.alpha_ctxt incr in - check_batch_in_inbox ctxt inbox 0 contents1 >>=? fun () -> - check_batch_in_inbox ctxt inbox 1 contents2 >>=? fun () -> - inbox_burn state expected_cumulated_size >>?= fun cost -> + inbox_testable + "The expected inbox is not the computed one" + inbox + expected_inbox) ; + inbox_burn state expected_inbox.cumulated_size >>?= fun cost -> Assert.balance_was_debited ~loc:__LOC__ (B b) contract balance cost (** Try to add a batch too large in an inbox. *) @@ -746,7 +731,6 @@ let test_inbox_count_too_big () = tickets to a transaction rollup. *) let test_valid_deposit () = let (_, _, pkh) = gen_l2_account () in - context_init1 () >>=? fun (b, account) -> originate b account >>=? fun (b, tx_rollup) -> Contract_helpers.originate_contract @@ -768,22 +752,30 @@ let test_valid_deposit () = ~parameters >>=? fun operation -> Block.bake ~operation b >>=? fun b -> - Incremental.begin_construction b >|=? Incremental.alpha_ctxt >>=? fun ctxt -> - Context.Tx_rollup.inbox (B b) tx_rollup Tx_rollup_level.root >>=? function - | {contents = [hash]; _} -> - let ticket_hash = make_unit_ticket_key ~ticketer:contract tx_rollup in - let (message, _size) = - Tx_rollup_message.make_deposit - (is_implicit_exn account) - (Tx_rollup_l2_address.Indexable.value pkh) - ticket_hash - (Tx_rollup_l2_qty.of_int64_exn 10L) - in - Environment.wrap_tzresult (Tx_rollup_message.hash ctxt message) - >>?= fun (_ctxt, expected) -> - Alcotest.(check message_hash_testable "deposit" hash expected) ; - return_unit - | _ -> Alcotest.fail "The inbox has not the expected shape" + Incremental.begin_construction b >|=? Incremental.alpha_ctxt >>=? fun _ctxt -> + Context.Tx_rollup.inbox (B b) tx_rollup Tx_rollup_level.root >>=? fun inbox -> + let ticket_hash = make_unit_ticket_key ~ticketer:contract tx_rollup in + let (message, cumulated_size) = + Tx_rollup_message.make_deposit + (is_implicit_exn account) + (Tx_rollup_l2_address.Indexable.value pkh) + ticket_hash + (Tx_rollup_l2_qty.of_int64_exn 10L) + in + let merkle_root = + Tx_rollup_inbox.Merkle.merklize_list + [Tx_rollup_message.hash_uncarbonated message] + in + let expected_inbox = + Tx_rollup_inbox.{inbox_length = 1; cumulated_size; merkle_root} + in + Alcotest.( + check + inbox_testable + "Expected inbox different from the computed one" + inbox + expected_inbox) ; + return_unit (** [test_valid_deposit_inexistant_rollup] checks that the Michelson interpreter checks the existence of a transaction rollup prior to @@ -1531,6 +1523,12 @@ module Rejection = struct >>=? fun (i, contract1, tx_rollup, level, message) -> let proof = true in let (message, _size) = Tx_rollup_message.make_batch message in + let message_hash = Tx_rollup_message.hash_uncarbonated message in + let message_path = + match Tx_rollup_inbox.Merkle.(compute_path [message_hash] 0) with + | Error _ -> assert false + | Ok path -> path + in Op.tx_rollup_reject (I i) contract1 @@ -1538,6 +1536,7 @@ module Rejection = struct level message ~message_position:0 + ~message_path ~proof ~previous_message_result: { @@ -1558,6 +1557,12 @@ module Rejection = struct >>=? fun (i, contract1, tx_rollup, level, message) -> let proof = false in let (message, _size) = Tx_rollup_message.make_batch message in + let message_hash = Tx_rollup_message.hash_uncarbonated message in + let message_path = + match Tx_rollup_inbox.Merkle.(compute_path [message_hash] 0) with + | Error _ -> assert false + | Ok path -> path + in Op.tx_rollup_reject (I i) contract1 @@ -1565,6 +1570,7 @@ module Rejection = struct level message ~message_position:0 + ~message_path ~proof ~previous_message_result: { @@ -1598,6 +1604,12 @@ module Rejection = struct Tx_rollup_withdraw.empty_withdrawals_merkle_root; } in + let message_hash = Tx_rollup_message.hash_uncarbonated message in + let message_path = + match Tx_rollup_inbox.Merkle.(compute_path [message_hash] 0) with + | Error _ -> assert false + | Ok path -> path + in Op.tx_rollup_reject (I i) contract1 @@ -1605,6 +1617,7 @@ module Rejection = struct level message ~message_position:0 + ~message_path ~proof ~previous_message_result >>=? fun op -> @@ -1644,6 +1657,12 @@ module Rejection = struct let level = Tx_rollup_level.root in let proof = true in let (message, _size) = Tx_rollup_message.make_batch message in + let message_hash = Tx_rollup_message.hash_uncarbonated message in + let message_path = + match Tx_rollup_inbox.Merkle.(compute_path [message_hash] 0) with + | Error _ -> assert false + | Ok path -> path + in Op.tx_rollup_reject (I i) contract1 @@ -1651,6 +1670,7 @@ module Rejection = struct level message ~message_position:0 + ~message_path ~proof ~previous_message_result: { @@ -1691,6 +1711,12 @@ module Rejection = struct Incremental.add_operation i op >>=? fun i -> let proof = true in let (message, _size) = Tx_rollup_message.make_batch message in + let message_hash = Tx_rollup_message.hash_uncarbonated message in + let message_path = + match Tx_rollup_inbox.Merkle.(compute_path [message_hash] 0) with + | Error _ -> assert false + | Ok path -> path + in Op.tx_rollup_reject (I i) contract1 @@ -1698,6 +1724,7 @@ module Rejection = struct level message ~message_position:0 + ~message_path ~proof ~previous_message_result: { @@ -1725,6 +1752,12 @@ module Rejection = struct >>=? fun (i, contract1, tx_rollup, level, _message) -> let proof = true in let (message, _size) = Tx_rollup_message.make_batch "wrong message" in + let message_hash = Tx_rollup_message.hash_uncarbonated message in + let message_path = + match Tx_rollup_inbox.Merkle.(compute_path [message_hash] 0) with + | Error _ -> assert false + | Ok path -> path + in Op.tx_rollup_reject (I i) contract1 @@ -1732,6 +1765,7 @@ module Rejection = struct level message ~message_position:0 + ~message_path ~proof ~previous_message_result: { @@ -1740,13 +1774,15 @@ module Rejection = struct Tx_rollup_withdraw.empty_withdrawals_merkle_root; } >>=? fun op -> - Incremental.add_operation - i - op - ~expect_failure:(check_proto_error Tx_rollup_errors.Wrong_message_hash) + let expected = + Tx_rollup_inbox.Merkle.root_of_b58check_opt + "txi1pvHiq799LSL2SXnRipQoCmSHnJ3SYH6SqjvJEQEKyfCLj3hCh" + |> Option.value_f ~default:(fun () -> assert false) + in + let error = Tx_rollup_errors.Wrong_message_path {expected} in + Incremental.add_operation i op ~expect_failure:(check_proto_error error) >>=? fun i -> ignore i ; - return () (** [test_wrong_message_position] tests that rejection successfully fails @@ -1756,6 +1792,12 @@ module Rejection = struct >>=? fun (i, contract1, tx_rollup, level, message) -> let proof = true in let (message, _size) = Tx_rollup_message.make_batch message in + let message_hash = Tx_rollup_message.hash_uncarbonated message in + let message_path = + match Tx_rollup_inbox.Merkle.(compute_path [message_hash] 0) with + | Error _ -> assert false + | Ok path -> path + in Op.tx_rollup_reject (I i) contract1 @@ -1763,6 +1805,7 @@ module Rejection = struct level message ~message_position:1 + ~message_path ~proof ~previous_message_result: { diff --git a/src/proto_alpha/lib_protocol/tx_rollup_commitment_repr.ml b/src/proto_alpha/lib_protocol/tx_rollup_commitment_repr.ml index c411bc17ce..0470f49448 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_commitment_repr.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_commitment_repr.ml @@ -115,7 +115,7 @@ type t = { level : Tx_rollup_level_repr.t; messages : Message_result_hash.t list; predecessor : Commitment_hash.t option; - inbox_hash : Tx_rollup_inbox_repr.hash; + inbox_merkle_root : Tx_rollup_inbox_repr.Merkle.root; } let compare_or cmp c1 c2 f = match cmp c1 c2 with 0 -> f () | diff -> diff @@ -133,22 +133,24 @@ include Compare.Make (struct r1.predecessor r2.predecessor (fun () -> - Tx_rollup_inbox_repr.compare_hash r1.inbox_hash r2.inbox_hash))) + Tx_rollup_inbox_repr.Merkle.compare + r1.inbox_merkle_root + r2.inbox_merkle_root))) end) let pp : Format.formatter -> t -> unit = fun fmt t -> Format.fprintf fmt - "commitment %a : messages = %a predecessor %a for inbox %a" + "commitment %a : messages = %a predecessor %a for inbox with merkle root %a" Tx_rollup_level_repr.pp t.level (Format.pp_print_list Message_result_hash.pp) t.messages (Format.pp_print_option Commitment_hash.pp) t.predecessor - Tx_rollup_inbox_repr.pp_hash - t.inbox_hash + Tx_rollup_inbox_repr.Merkle.pp_root + t.inbox_merkle_root (* FIXME/TORU: We need a test that checks that. *) let empty_l2_context_hash = @@ -169,15 +171,15 @@ let initial_message_result_hash = let encoding = let open Data_encoding in conv - (fun {level; messages; predecessor; inbox_hash} -> - (level, messages, predecessor, inbox_hash)) - (fun (level, messages, predecessor, inbox_hash) -> - {level; messages; predecessor; inbox_hash}) + (fun {level; messages; predecessor; inbox_merkle_root} -> + (level, messages, predecessor, inbox_merkle_root)) + (fun (level, messages, predecessor, inbox_merkle_root) -> + {level; messages; predecessor; inbox_merkle_root}) (obj4 (req "level" Tx_rollup_level_repr.encoding) (req "batches" (list Message_result_hash.encoding)) (req "predecessor" (option Commitment_hash.encoding)) - (req "inbox_hash" Tx_rollup_inbox_repr.hash_encoding)) + (req "inbox_merkle_root" Tx_rollup_inbox_repr.Merkle.root_encoding)) let hash c = let bytes = Data_encoding.Binary.to_bytes_exn encoding c in diff --git a/src/proto_alpha/lib_protocol/tx_rollup_commitment_repr.mli b/src/proto_alpha/lib_protocol/tx_rollup_commitment_repr.mli index b42e321afc..446361ea4e 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_commitment_repr.mli +++ b/src/proto_alpha/lib_protocol/tx_rollup_commitment_repr.mli @@ -82,7 +82,7 @@ type t = { level : Tx_rollup_level_repr.t; messages : Message_result_hash.t list; predecessor : Commitment_hash.t option; - inbox_hash : Tx_rollup_inbox_repr.hash; + inbox_merkle_root : Tx_rollup_inbox_repr.Merkle.root; } include Compare.S with type t := t diff --git a/src/proto_alpha/lib_protocol/tx_rollup_commitment_storage.ml b/src/proto_alpha/lib_protocol/tx_rollup_commitment_storage.ml index 289870d423..7b012ec710 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_commitment_storage.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_commitment_storage.ml @@ -147,15 +147,15 @@ let check_commitment_predecessor ctxt state commitment = | (None, None) -> return ctxt | (provided, expected) -> fail (Wrong_predecessor_hash {provided; expected}) -let check_commitment_batches_and_inbox_hash ctxt tx_rollup commitment = - Tx_rollup_inbox_storage.get_metadata ctxt commitment.level tx_rollup - >>=? fun (ctxt, {inbox_length; hash; _}) -> +let check_commitment_batches_and_merkle_root ctxt tx_rollup commitment = + Tx_rollup_inbox_storage.get ctxt commitment.level tx_rollup + >>=? fun (ctxt, {inbox_length; merkle_root; _}) -> fail_unless - Compare.List_length_with.(commitment.messages = Int32.to_int inbox_length) + Compare.List_length_with.(commitment.messages = inbox_length) Wrong_batch_count >>=? fun () -> fail_unless - (Tx_rollup_inbox_repr.equal_hash commitment.inbox_hash hash) + Tx_rollup_inbox_repr.Merkle.(commitment.inbox_merkle_root = merkle_root) Wrong_inbox_hash >>=? fun () -> return ctxt @@ -171,7 +171,7 @@ let add_commitment ctxt tx_rollup state pkh commitment = (* Check the commitment has the correct values *) check_commitment_level state commitment >>?= fun () -> check_commitment_predecessor ctxt state commitment >>=? fun ctxt -> - check_commitment_batches_and_inbox_hash ctxt tx_rollup commitment + check_commitment_batches_and_merkle_root ctxt tx_rollup commitment >>=? fun ctxt -> (* Everything has been sorted out, let’s update the storage *) let current_level = (Raw_context.current_level ctxt).level in diff --git a/src/proto_alpha/lib_protocol/tx_rollup_errors_repr.ml b/src/proto_alpha/lib_protocol/tx_rollup_errors_repr.ml index cdf38070e4..ef89d54d7f 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_errors_repr.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_errors_repr.ml @@ -60,7 +60,7 @@ type error += position : int; length : int; } - | Wrong_message_hash + | Wrong_message_path of {expected : Tx_rollup_inbox_repr.Merkle.root} | No_finalized_commitment_for_level of { level : Tx_rollup_level_repr.t; window : (Tx_rollup_level_repr.t * Tx_rollup_level_repr.t) option; @@ -384,13 +384,14 @@ let () = register_error_kind `Branch ~id:"tx_rollup_wrong_message_hash" - ~title:"Wrong message hash in rejection." + ~title:"Wrong message path in rejection." ~description: - "This rejection has sent a message with a hash that doesn't match the \ - stored one" - unit - (function Wrong_message_hash -> Some () | _ -> None) - (fun () -> Wrong_message_hash) ; + "This rejection has sent a message and a path that does not fit the \ + current merkle root hash in the corresponding inbox" + (obj1 + (req "expected_merkle_root" Tx_rollup_inbox_repr.Merkle.root_encoding)) + (function Wrong_message_path {expected} -> Some expected | _ -> None) + (fun expected -> Wrong_message_path {expected}) ; (* No_finalized_commitment_for_level *) register_error_kind `Temporary diff --git a/src/proto_alpha/lib_protocol/tx_rollup_inbox_repr.ml b/src/proto_alpha/lib_protocol/tx_rollup_inbox_repr.ml index f23160668e..fe5bc644a6 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_inbox_repr.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_inbox_repr.ml @@ -25,106 +25,101 @@ (* *) (*****************************************************************************) -let hash_size = Tx_rollup_prefixes.inbox_hash.hash_size +module El = struct + type t = Tx_rollup_message_repr.hash -module Inbox_hash = - Blake2B.Make - (Base58) - (struct - let name = "Tx_rollup_inbox_hash" + let to_bytes = + Data_encoding.Binary.to_bytes_exn Tx_rollup_message_repr.hash_encoding +end - let title = "The hash of a transaction rollup inbox" +module Prefix = struct + let name = "Inbox_list_hash" - let b58check_prefix = Tx_rollup_prefixes.inbox_hash.b58check_prefix + let title = "A merkle root hash for inboxes" - let size = Some hash_size - end) + let b58check_prefix = Tx_rollup_prefixes.inbox_list_hash.b58check_prefix -let () = - Tx_rollup_prefixes.(check_encoding inbox_hash Inbox_hash.b58check_encoding) + let size = Some Tx_rollup_prefixes.inbox_list_hash.hash_size +end -type hash = Inbox_hash.t +module H = Blake2B.Make (Base58) (Prefix) +module Merkle_list = Merkle_list.Make (El) (H) -let compare_hash = Inbox_hash.compare +module Merkle = struct + type tree = Merkle_list.t -let equal_hash = Inbox_hash.equal + type root = Merkle_list.h -let pp_hash = Inbox_hash.pp + type path = Merkle_list.path -let hash_of_bytes_exn = Inbox_hash.of_bytes_exn + let empty = Merkle_list.nil -let hash_of_bytes_opt = Inbox_hash.of_bytes_opt + let root = Merkle_list.root -let hash_of_b58check_exn = Inbox_hash.of_b58check_exn + let ( = ) = H.( = ) -let hash_of_b58check_opt = Inbox_hash.of_b58check_opt + let compare = H.compare -let hash_encoding = Inbox_hash.encoding + let root_encoding = H.encoding -let hash_to_bytes = Inbox_hash.to_bytes + let root_of_b58check_opt = H.of_b58check_opt -let hash_to_b58check = Inbox_hash.to_b58check + let pp_root = H.pp -let extend_hash inbox_hash msg_hash = - let open Data_encoding.Binary in - let inbox_hash = to_bytes_exn hash_encoding inbox_hash in - let msg_hash = to_bytes_exn Tx_rollup_message_repr.hash_encoding msg_hash in - Inbox_hash.hash_bytes [inbox_hash; msg_hash] + let path_encoding = Merkle_list.path_encoding -let hash_hashed_inbox message_hashes = - List.fold_left - extend_hash - (Inbox_hash.hash_bytes [Bytes.make hash_size @@ Char.chr 0]) - message_hashes + let add_message = Merkle_list.snoc -let hash_inbox messages = - let message_hashes = - List.map Tx_rollup_message_repr.hash_uncarbonated messages - in - hash_hashed_inbox message_hashes + let tree_of_messages = List.fold_left Merkle_list.snoc Merkle_list.nil -type t = { - contents : Tx_rollup_message_repr.hash list; - cumulated_size : int; - hash : hash; -} + let compute_path messages position = + let tree = tree_of_messages messages in + Merkle_list.compute_path tree position -let pp fmt {contents; cumulated_size; hash} = - Format.fprintf - fmt - "tx rollup inbox: %d messages using %d bytes with hash %a" - (List.length contents) - cumulated_size - pp_hash - hash + let check_path = Merkle_list.check_path + + let merklize_list messages = + let tree = tree_of_messages messages in + root tree +end + +type t = {inbox_length : int; cumulated_size : int; merkle_root : Merkle.root} + +let ( = ) + { + inbox_length = inbox_length_left; + cumulated_size = cumulated_size_left; + merkle_root = merkle_root_left; + } + { + inbox_length = inbox_length_right; + cumulated_size = cumulated_size_right; + merkle_root = merkle_root_right; + } = + Compare.Int.(inbox_length_left = inbox_length_right) + && Compare.Int.(cumulated_size_left = cumulated_size_right) + && Merkle.(merkle_root_left = merkle_root_right) let encoding = let open Data_encoding in conv - (fun {contents; cumulated_size; hash} -> (contents, cumulated_size, hash)) - (fun (contents, cumulated_size, hash) -> {contents; cumulated_size; hash}) + (fun {inbox_length; cumulated_size; merkle_root} -> + (inbox_length, cumulated_size, merkle_root)) + (fun (inbox_length, cumulated_size, merkle_root) -> + {inbox_length; cumulated_size; merkle_root}) (obj3 - (req "contents" @@ list Tx_rollup_message_repr.hash_encoding) + (req "inbox_length" int31) (req "cumulated_size" int31) - (req "hash" hash_encoding)) + (req "merkle_root" Merkle.root_encoding)) -type metadata = {inbox_length : int32; cumulated_size : int; hash : hash} +let empty = + {inbox_length = 0; cumulated_size = 0; merkle_root = Merkle_list.empty} -let metadata_encoding = - let open Data_encoding in - conv - (fun {inbox_length; cumulated_size; hash} -> - (inbox_length, cumulated_size, hash)) - (fun (inbox_length, cumulated_size, hash) -> - {inbox_length; cumulated_size; hash}) - (obj3 - (req "inbox_length" int32) - (req "cumulated_size" int31) - (req "hash" hash_encoding)) - -let empty_metadata = - { - inbox_length = 0l; - cumulated_size = 0; - hash = Inbox_hash.hash_bytes [Bytes.make hash_size @@ Char.chr 0]; - } +let pp fmt {inbox_length; cumulated_size; merkle_root} = + Format.fprintf + fmt + "Inbox with length %d, size %d and merkle root %a" + inbox_length + cumulated_size + Merkle.pp_root + merkle_root diff --git a/src/proto_alpha/lib_protocol/tx_rollup_inbox_repr.mli b/src/proto_alpha/lib_protocol/tx_rollup_inbox_repr.mli index 669bcc11be..32869aa9fb 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_inbox_repr.mli +++ b/src/proto_alpha/lib_protocol/tx_rollup_inbox_repr.mli @@ -25,73 +25,54 @@ (* *) (*****************************************************************************) -(** The type of hashes used to identify an inbox based on its - contents. For an inbox containing the messages hashes [h1; h2; - .. ; hn], its hash is computed with [H(.. H(H(empty + h1) + h2) - .. + hn)] *) -type hash +module Merkle : sig + (** See {Merkle_List} for the documentation of those functions. *) -val compare_hash : hash -> hash -> int + type tree -val equal_hash : hash -> hash -> bool + type root -val pp_hash : Format.formatter -> hash -> unit + type path -val hash_of_bytes_exn : bytes -> hash + val empty : tree -val hash_of_bytes_opt : bytes -> hash option + val root : tree -> root -val hash_of_b58check_exn : string -> hash + val ( = ) : root -> root -> bool -val hash_of_b58check_opt : string -> hash option + val compare : root -> root -> int -val hash_encoding : hash Data_encoding.t + val root_encoding : root Data_encoding.t -val hash_to_bytes : hash -> bytes + val root_of_b58check_opt : string -> root option -val hash_to_b58check : hash -> string + val pp_root : Format.formatter -> root -> unit -(** [extend_hash inbox_hash hash] computes [H(inbox_hash + hash)], - which is used to identify an inbox identified by [inbox_hash] - after appending a new message identified by [hash]. *) -val extend_hash : hash -> Tx_rollup_message_repr.hash -> hash + val path_encoding : path Data_encoding.t -(** [hash_inbox messages] hashes a list of messages, starting - from an empty inbox and recursively running extend_hash on - each. *) -val hash_inbox : Tx_rollup_message_repr.t list -> hash + val add_message : tree -> Tx_rollup_message_repr.hash -> tree -(** [hash_hashed_inbox messages] hashes a list of already-hashed - messages, starting from an empty inbox and recursively running - extend_hash on each. *) -val hash_hashed_inbox : Tx_rollup_message_repr.hash list -> hash + val compute_path : Tx_rollup_message_repr.hash list -> int -> path tzresult -(** An inbox gathers, for a given Tezos level, messages crafted by the - layer-1 for the layer-2 to interpret. + val check_path : + path -> int -> Tx_rollup_message_repr.hash -> root -> bool tzresult - The structure comprises two fields: (1) [contents] is the list of - message hashes, and (2) [cumulated_size] is the quantity of bytes - allocated by the related messages. + (** [merklize_list messages] construct a merkle root by build a + tree, appending the [messages] one by one in the same order of + the list and finally computing the root. *) + val merklize_list : Tx_rollup_message_repr.hash list -> root +end - We recall that a transaction rollup can have up to one inbox per - Tezos level, starting from its origination. See - {!Storage.Tx_rollup} for more information. *) -type t = { - contents : Tx_rollup_message_repr.hash list; - cumulated_size : int; - hash : hash; -} - -val pp : Format.formatter -> t -> unit - -val encoding : t Data_encoding.t - -(** The metadata for an inbox stores the [cumulated_size] in bytes for +(** The view of an inbox: stores the [cumulated_size] in bytes for the inbox, the [inbox_length] ({i i.e.}, the number of messages), and the cumulative [hash] of the inbox contents. For newly created inboxes, the [hash] is initialized as an array 32 null byte. *) -type metadata = {inbox_length : int32; cumulated_size : int; hash : hash} +type t = {inbox_length : int; cumulated_size : int; merkle_root : Merkle.root} -val metadata_encoding : metadata Data_encoding.t +val ( = ) : t -> t -> bool -val empty_metadata : metadata +val encoding : t Data_encoding.t + +val empty : t + +val pp : Format.formatter -> t -> unit diff --git a/src/proto_alpha/lib_protocol/tx_rollup_inbox_storage.ml b/src/proto_alpha/lib_protocol/tx_rollup_inbox_storage.ml index f3c6202e0a..07fe36c7f9 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_inbox_storage.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_inbox_storage.ml @@ -33,7 +33,7 @@ let size : Tx_rollup_repr.t -> (Raw_context.t * int) tzresult Lwt.t = fun ctxt level tx_rollup -> - Storage.Tx_rollup.Inbox_metadata.find (ctxt, level) tx_rollup >>=? function + Storage.Tx_rollup.Inbox.find (ctxt, level) tx_rollup >>=? function | (ctxt, Some {cumulated_size; _}) -> return (ctxt, cumulated_size) | (ctxt, None) -> (* @@ -44,52 +44,13 @@ let size : Tx_rollup_state_storage.assert_exist ctxt tx_rollup >>=? fun _ctxt -> fail (Inbox_does_not_exist (tx_rollup, level)) -let message_hashes_opt : - Raw_context.t -> - Tx_rollup_level_repr.t -> - Tx_rollup_repr.t -> - (Raw_context.t * Tx_rollup_message_repr.hash list option) tzresult Lwt.t = - fun ctxt level tx_rollup -> - Storage.Tx_rollup.Inbox_contents.list_values ((ctxt, level), tx_rollup) - >>=? function - | (ctxt, []) -> - (* - Prior to returning [None], we check whether or not the - transaction rollup address is valid, to raise the appropriate eror - if need be. - *) - Tx_rollup_state_storage.assert_exist ctxt tx_rollup >>=? fun ctxt -> - return (ctxt, None) - | (ctxt, contents) -> return (ctxt, Some contents) - -let message_hashes : - Raw_context.t -> - Tx_rollup_level_repr.t -> - Tx_rollup_repr.t -> - (Raw_context.t * Tx_rollup_message_repr.hash list) tzresult Lwt.t = - fun ctxt level tx_rollup -> - message_hashes_opt ctxt level tx_rollup >>=? function - | (ctxt, Some messages) -> return (ctxt, messages) - | (_, None) -> - fail (Tx_rollup_errors_repr.Inbox_does_not_exist (tx_rollup, level)) - let find : Raw_context.t -> Tx_rollup_level_repr.t -> Tx_rollup_repr.t -> (Raw_context.t * Tx_rollup_inbox_repr.t option) tzresult Lwt.t = fun ctxt level tx_rollup -> - let open Tx_rollup_inbox_repr in - (* - [messages_opt] checks whether or not [tx_rollup] is valid, so - we do not have to do it here. - *) - message_hashes_opt ctxt level tx_rollup >>=? function - | (ctxt, Some contents) -> - size ctxt level tx_rollup >>=? fun (ctxt, cumulated_size) -> - let hash = Tx_rollup_inbox_repr.hash_hashed_inbox contents in - return (ctxt, Some {cumulated_size; contents; hash}) - | (ctxt, None) -> return (ctxt, None) + Storage.Tx_rollup.Inbox.find (ctxt, level) tx_rollup let get : Raw_context.t -> @@ -97,18 +58,14 @@ let get : Tx_rollup_repr.t -> (Raw_context.t * Tx_rollup_inbox_repr.t) tzresult Lwt.t = fun ctxt level tx_rollup -> - (* - [inbox_opt] checks whether or not [tx_rollup] is valid, so we - don’t have to do it here. - *) find ctxt level tx_rollup >>=? function - | (ctxt, Some res) -> return (ctxt, res) | (_, None) -> fail (Inbox_does_not_exist (tx_rollup, level)) + | (ctxt, Some inbox) -> return (ctxt, inbox) -(** [prepare_metadata ctxt rollup state level] prepares the metadata +(** [prepare_inbox ctxt rollup state level] prepares the metadata for an inbox at [level], which may imply creating it if it does not already exist. *) -let prepare_metadata : +let prepare_inbox : Raw_context.t -> Tx_rollup_repr.t -> Tx_rollup_state_repr.t -> @@ -116,7 +73,7 @@ let prepare_metadata : (Raw_context.t * Tx_rollup_state_repr.t * Tx_rollup_level_repr.t - * Tx_rollup_inbox_repr.metadata) + * Tx_rollup_inbox_repr.t) tzresult Lwt.t = fun ctxt rollup state level -> @@ -133,7 +90,7 @@ let prepare_metadata : fail (Internal_error "Trying to write into an inbox from the past") | Some (tx_lvl, tezos_lvl) when Raw_level_repr.(tezos_lvl = level) -> (* An inbox should already exists *) - Storage.Tx_rollup.Inbox_metadata.get (ctxt, tx_lvl) rollup + Storage.Tx_rollup.Inbox.get (ctxt, tx_lvl) rollup >>=? fun (ctxt, metadata) -> return (ctxt, state, tx_lvl, metadata) | _ -> let pred_level = @@ -183,26 +140,24 @@ let prepare_metadata : (* We need a new inbox *) Tx_rollup_state_repr.record_inbox_creation state level >>?= fun (state, tx_level) -> - let metadata = Tx_rollup_inbox_repr.empty_metadata in - Storage.Tx_rollup.Inbox_metadata.init (ctxt, tx_level) rollup metadata - >>=? fun (ctxt, _) -> return (ctxt, state, tx_level, metadata) + let inbox = Tx_rollup_inbox_repr.empty in + Storage.Tx_rollup.Inbox.init (ctxt, tx_level) rollup inbox + >>=? fun (ctxt, _) -> return (ctxt, state, tx_level, inbox) -(** [update_metadata metadata msg_size] updates [metadata] to account +(** [update_inbox inbox msg_size] updates [metadata] to account for a new message of [msg_size] bytes. *) -let update_metadata : - Tx_rollup_inbox_repr.metadata -> - Tx_rollup_message_repr.hash -> +let update_inbox : + Tx_rollup_inbox_repr.t -> int -> - Tx_rollup_inbox_repr.metadata tzresult = - fun metadata msg_hash msg_size -> - let hash = Tx_rollup_inbox_repr.extend_hash metadata.hash msg_hash in - ok - Tx_rollup_inbox_repr. - { - inbox_length = Int32.succ metadata.inbox_length; - cumulated_size = msg_size + metadata.cumulated_size; - hash; - } + Tx_rollup_inbox_repr.Merkle.root -> + Tx_rollup_inbox_repr.t = + fun metadata msg_size merkle_root -> + Tx_rollup_inbox_repr. + { + inbox_length = 1 + metadata.inbox_length; + cumulated_size = msg_size + metadata.cumulated_size; + merkle_root; + } let append_message : Raw_context.t -> @@ -214,17 +169,20 @@ let append_message : let level = (Raw_context.current_level ctxt).level in let message_size = Tx_rollup_message_repr.size message in (* Update the burn cost to pay for appending new messages *) - prepare_metadata ctxt rollup state level - >>=? fun (ctxt, new_state, tx_level, metadata) -> + prepare_inbox ctxt rollup state level + >>=? fun (ctxt, new_state, tx_level, inbox) -> fail_when Compare.Int.( - Int32.to_int metadata.inbox_length + inbox.inbox_length >= Constants_storage.tx_rollup_max_messages_per_inbox ctxt) (Inbox_count_would_exceed_limit rollup) >>=? fun () -> Tx_rollup_message_builder.hash ctxt message >>?= fun (ctxt, message_hash) -> - update_metadata metadata message_hash message_size >>?= fun new_metadata -> - let new_size = new_metadata.cumulated_size in + let (ctxt, inbox_merkle_root) = + Raw_context.Tx_rollup.add_message ctxt rollup message_hash + in + let new_inbox = update_inbox inbox message_size inbox_merkle_root in + let new_size = new_inbox.cumulated_size in let inbox_limit = Constants_storage.tx_rollup_hard_size_limit_per_inbox ctxt in @@ -233,39 +191,17 @@ let append_message : (Inbox_size_would_exceed_limit rollup) >>=? fun () -> (* Checks have passed, so we can actually record in the storage. *) - Storage.Tx_rollup.Inbox_metadata.add (ctxt, tx_level) rollup new_metadata - >>=? fun (ctxt, _, _) -> - Storage.Tx_rollup.Inbox_contents.add - ((ctxt, tx_level), rollup) - metadata.inbox_length - message_hash + Storage.Tx_rollup.Inbox.add (ctxt, tx_level) rollup new_inbox >>=? fun (ctxt, _, _) -> return (ctxt, new_state) -let get_metadata : - Raw_context.t -> - Tx_rollup_level_repr.t -> - Tx_rollup_repr.t -> - (Raw_context.t * Tx_rollup_inbox_repr.metadata) tzresult Lwt.t = - fun ctxt level tx_rollup -> - Storage.Tx_rollup.Inbox_metadata.find (ctxt, level) tx_rollup >>=? function - | (_, None) -> fail (Inbox_does_not_exist (tx_rollup, level)) - | (ctxt, Some metadata) -> return (ctxt, metadata) - let remove : Raw_context.t -> Tx_rollup_level_repr.t -> Tx_rollup_repr.t -> Raw_context.t tzresult Lwt.t = fun ctxt level rollup -> - let rec remove_messages ctxt i len = - if Compare.Int32.(i < len) then - Storage.Tx_rollup.Inbox_contents.remove ((ctxt, level), rollup) i - >>=? fun (ctxt, _, _) -> remove_messages ctxt (Int32.succ i) len - else return ctxt - in - get_metadata ctxt level rollup >>=? fun (ctxt, metadata) -> - Storage.Tx_rollup.Inbox_metadata.remove (ctxt, level) rollup - >>=? fun (ctxt, _, _) -> remove_messages ctxt 0l metadata.inbox_length + Storage.Tx_rollup.Inbox.remove (ctxt, level) rollup >|=? fun (ctxt, _, _) -> + ctxt let check_message_hash : Raw_context.t -> @@ -273,19 +209,16 @@ let check_message_hash : Tx_rollup_repr.t -> position:int -> Tx_rollup_message_repr.t -> + Tx_rollup_inbox_repr.Merkle.path -> Raw_context.t tzresult Lwt.t = - fun ctxt level tx_rollup ~position message -> - Storage.Tx_rollup.Inbox_contents.list_values ((ctxt, level), tx_rollup) - >>=? fun (ctxt, messages) -> - Option.value_e - ~error: - (Error_monad.trace_of_error - (Wrong_message_position - {level; position; length = List.length messages})) - @@ List.nth_opt messages position - >>?= fun expected_hash -> - Tx_rollup_message_builder.hash ctxt message >>?= fun (ctxt, actual_hash) -> - fail_unless - (Tx_rollup_message_repr.hash_equal actual_hash expected_hash) - Wrong_message_hash + fun ctxt level tx_rollup ~position message path -> + Storage.Tx_rollup.Inbox.get (ctxt, level) tx_rollup >>=? fun (ctxt, inbox) -> + let message_hash = Tx_rollup_message_repr.hash_uncarbonated message in + Tx_rollup_inbox_repr.Merkle.check_path + path + position + message_hash + inbox.merkle_root + >>?= fun b -> + fail_unless b (Wrong_message_path {expected = inbox.merkle_root}) >>=? fun () -> return ctxt diff --git a/src/proto_alpha/lib_protocol/tx_rollup_inbox_storage.mli b/src/proto_alpha/lib_protocol/tx_rollup_inbox_storage.mli index f5e03110ee..e371af4bd8 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_inbox_storage.mli +++ b/src/proto_alpha/lib_protocol/tx_rollup_inbox_storage.mli @@ -56,20 +56,6 @@ val append_message : Tx_rollup_message_repr.t -> (Raw_context.t * Tx_rollup_state_repr.t) tzresult Lwt.t -(** [message_hashes ctxt level tx_rollup] returns the list of messages - hashes stored in the inbox of [tx_rollup] at level [level]. - - Returns the errors - - {ul {li [Tx_rollup_does_not_exist] iff [tx_rollup] does not exist} - {li [Inbox_does_not_exist] iff [tx_rollup] exists, but does - not have an inbox at level [level]. }} *) -val message_hashes : - Raw_context.t -> - Tx_rollup_level_repr.t -> - Tx_rollup_repr.t -> - (Raw_context.t * Tx_rollup_message_repr.hash list) tzresult Lwt.t - (** [size ctxt level tx_rollup] returns the number of bytes allocated by the messages of the inbox of [tx_rollup] at level [level]. @@ -89,9 +75,8 @@ val size : Returns the errors - {ul {li [Tx_rollup_does_not_exist] iff [tx_rollup] does not exist} - {li [Inbox_does_not_exist] iff [tx_rollup] exists, but does - not have an inbox at level [level]. }} *) + {ul {li [Inbox_does_not_exist] iff [tx_rollup] does not have an + inbox at level [level]. }} *) val get : Raw_context.t -> Tx_rollup_level_repr.t -> @@ -99,26 +84,18 @@ val get : (Raw_context.t * Tx_rollup_inbox_repr.t) tzresult Lwt.t (** [find ctxt level tx_rollup] returns the inbox of [tx_rollup] at - level [level], or [None] if said inbox does not exist. + level [level]. - Returns the [Tx_rollup_does_not_exist] error iff [tx_rollup] does - not exist. *) + Returns [None] when the similar function [get] returns an + error. *) val find : Raw_context.t -> Tx_rollup_level_repr.t -> Tx_rollup_repr.t -> (Raw_context.t * Tx_rollup_inbox_repr.t option) tzresult Lwt.t -(** [get_metadata ctxt level tx_rollup] returns the metadata for an inbox: - its count, byte size, next and previous levels, and hash. *) -val get_metadata : - Raw_context.t -> - Tx_rollup_level_repr.t -> - Tx_rollup_repr.t -> - (Raw_context.t * Tx_rollup_inbox_repr.metadata) tzresult Lwt.t - (** [remove ctxt level tx_rollup] removes from the context the - metadata and the contents of the inbox of [level]. + inbox of [level]. This function will returns the error [Inbox_does_not_exist] if there is no inbox for [level] in the storage. It is the @@ -130,15 +107,16 @@ val remove : Tx_rollup_repr.t -> Raw_context.t tzresult Lwt.t -(** [check_message ctxt level tx_rollup index message] checks that - the message at [index] in the inbox for [level] on [tx_rollup] - has the same hash as [message]. If there is no message - at that index, [Wrong_message_position] is returned. If the - hash doesn't match, [Wrong_message_hash] is returned. *) +(** [check_message_hash ctxt level tx_rollup position message path] + checks that [message] is part of the [tx_rollup] inbox for [level] + by checking the merkelised proof given by [path]. + + If the proof failed, returns [Wrong_message_path]. *) val check_message_hash : Raw_context.t -> Tx_rollup_level_repr.t -> Tx_rollup_repr.t -> position:int -> Tx_rollup_message_repr.t -> + Tx_rollup_inbox_repr.Merkle.path -> Raw_context.t tzresult Lwt.t diff --git a/src/proto_alpha/lib_protocol/tx_rollup_prefixes.ml b/src/proto_alpha/lib_protocol/tx_rollup_prefixes.ml index 6586032562..c464fe7702 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_prefixes.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_prefixes.ml @@ -54,6 +54,8 @@ let inbox_hash = b58check_size = 53; } +let inbox_list_hash = inbox_hash + let message_hash = { b58check_prefix = "\079\149\030"; diff --git a/src/proto_alpha/lib_protocol/tx_rollup_prefixes.mli b/src/proto_alpha/lib_protocol/tx_rollup_prefixes.mli index 1a07e3695d..bccca0173a 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_prefixes.mli +++ b/src/proto_alpha/lib_protocol/tx_rollup_prefixes.mli @@ -51,6 +51,9 @@ val message_result_hash : t (** See {!Tx_rollup_withdraw_repr}. *) val withdraw_list_hash : t +(** See {!Tx_rollup_inbox_repr.inbox_hash}. *) +val inbox_list_hash : t + (** [check_encoding spec encoding] checks that [encoding] satisfies [spec]. Raises an exception otherwise. *) val check_encoding : t -> 'a Base58.encoding -> unit diff --git a/src/proto_alpha/lib_protocol/tx_rollup_repr.ml b/src/proto_alpha/lib_protocol/tx_rollup_repr.ml index 92f5d5ef72..defb74482f 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_repr.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_repr.ml @@ -168,3 +168,9 @@ module Set = Set.Make (struct include Compare_impl end) + +module Map = Map.Make (struct + type t = tx_rollup + + include Compare_impl +end) diff --git a/src/proto_alpha/lib_protocol/tx_rollup_repr.mli b/src/proto_alpha/lib_protocol/tx_rollup_repr.mli index 6c7cb21a5f..fc0934aefd 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_repr.mli +++ b/src/proto_alpha/lib_protocol/tx_rollup_repr.mli @@ -95,3 +95,5 @@ type deposit_parameters = { } module Set : Set.S with type elt = tx_rollup + +module Map : Map.S with type key = tx_rollup diff --git a/tezt/_regressions/rpc/alpha.client.mempool.out b/tezt/_regressions/rpc/alpha.client.mempool.out index ab77570bc4..1506748cf5 100644 --- a/tezt/_regressions/rpc/alpha.client.mempool.out +++ b/tezt/_regressions/rpc/alpha.client.mempool.out @@ -651,6 +651,10 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' "title": "An Ed25519 public key hash (Base58Check-encoded)", "$ref": "#/definitions/unistring" }, + "Inbox_list_hash": { + "title": "A merkle root hash for inboxes (Base58Check-encoded)", + "$ref": "#/definitions/unistring" + }, "Message_result_hash": { "title": "A message result (Base58Check-encoded)", "$ref": "#/definitions/unistring" @@ -679,10 +683,6 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' "title": "A Ed25519, Secp256k1, or P256 public key hash (Base58Check-encoded)", "$ref": "#/definitions/unistring" }, - "Tx_rollup_inbox_hash": { - "title": "The hash of a transaction rollup inbox (Base58Check-encoded)", - "$ref": "#/definitions/unistring" - }, "Tx_rollup_l2_address": { "title": "The hash of a BLS public key used to identify a L2 ticket holders (Base58Check-encoded)", "$ref": "#/definitions/unistring" @@ -1953,12 +1953,12 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' } ] }, - "inbox_hash": { - "$ref": "#/definitions/Tx_rollup_inbox_hash" + "inbox_merkle_root": { + "$ref": "#/definitions/Inbox_list_hash" } }, "required": [ - "inbox_hash", + "inbox_merkle_root", "predecessor", "batches", "level" @@ -2264,6 +2264,12 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' "message_position": { "$ref": "#/definitions/positive_bignum" }, + "message_path": { + "type": "array", + "items": { + "$ref": "#/definitions/Inbox_list_hash" + } + }, "previous_message_result": { "type": "object", "properties": { @@ -2287,6 +2293,7 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' "required": [ "proof", "previous_message_result", + "message_path", "message_position", "message", "level", @@ -5034,6 +5041,24 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' }, "kind": "named" }, + { + "kind": "dyn", + "num_fields": 1, + "size": "Uint30" + }, + { + "name": "message_path", + "layout": { + "layout": { + "kind": "Bytes" + }, + "kind": "Seq" + }, + "data_kind": { + "kind": "Variable" + }, + "kind": "named" + }, { "name": "previous_message_result", "layout": { @@ -6685,7 +6710,7 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' "kind": "named" }, { - "name": "inbox_hash", + "name": "inbox_merkle_root", "layout": { "kind": "Bytes" }, @@ -7951,6 +7976,10 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' "title": "An Ed25519 public key hash (Base58Check-encoded)", "$ref": "#/definitions/unistring" }, + "Inbox_list_hash": { + "title": "A merkle root hash for inboxes (Base58Check-encoded)", + "$ref": "#/definitions/unistring" + }, "Message_result_hash": { "title": "A message result (Base58Check-encoded)", "$ref": "#/definitions/unistring" @@ -7979,10 +8008,6 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' "title": "A Ed25519, Secp256k1, or P256 public key hash (Base58Check-encoded)", "$ref": "#/definitions/unistring" }, - "Tx_rollup_inbox_hash": { - "title": "The hash of a transaction rollup inbox (Base58Check-encoded)", - "$ref": "#/definitions/unistring" - }, "Tx_rollup_l2_address": { "title": "The hash of a BLS public key used to identify a L2 ticket holders (Base58Check-encoded)", "$ref": "#/definitions/unistring" @@ -9253,12 +9278,12 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' } ] }, - "inbox_hash": { - "$ref": "#/definitions/Tx_rollup_inbox_hash" + "inbox_merkle_root": { + "$ref": "#/definitions/Inbox_list_hash" } }, "required": [ - "inbox_hash", + "inbox_merkle_root", "predecessor", "batches", "level" @@ -9564,6 +9589,12 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' "message_position": { "$ref": "#/definitions/positive_bignum" }, + "message_path": { + "type": "array", + "items": { + "$ref": "#/definitions/Inbox_list_hash" + } + }, "previous_message_result": { "type": "object", "properties": { @@ -9587,6 +9618,7 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' "required": [ "proof", "previous_message_result", + "message_path", "message_position", "message", "level", diff --git a/tezt/_regressions/rpc/alpha.proxy.mempool.out b/tezt/_regressions/rpc/alpha.proxy.mempool.out index a330373947..7d8f2a4a00 100644 --- a/tezt/_regressions/rpc/alpha.proxy.mempool.out +++ b/tezt/_regressions/rpc/alpha.proxy.mempool.out @@ -672,6 +672,10 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' "title": "An Ed25519 public key hash (Base58Check-encoded)", "$ref": "#/definitions/unistring" }, + "Inbox_list_hash": { + "title": "A merkle root hash for inboxes (Base58Check-encoded)", + "$ref": "#/definitions/unistring" + }, "Message_result_hash": { "title": "A message result (Base58Check-encoded)", "$ref": "#/definitions/unistring" @@ -700,10 +704,6 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' "title": "A Ed25519, Secp256k1, or P256 public key hash (Base58Check-encoded)", "$ref": "#/definitions/unistring" }, - "Tx_rollup_inbox_hash": { - "title": "The hash of a transaction rollup inbox (Base58Check-encoded)", - "$ref": "#/definitions/unistring" - }, "Tx_rollup_l2_address": { "title": "The hash of a BLS public key used to identify a L2 ticket holders (Base58Check-encoded)", "$ref": "#/definitions/unistring" @@ -1974,12 +1974,12 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' } ] }, - "inbox_hash": { - "$ref": "#/definitions/Tx_rollup_inbox_hash" + "inbox_merkle_root": { + "$ref": "#/definitions/Inbox_list_hash" } }, "required": [ - "inbox_hash", + "inbox_merkle_root", "predecessor", "batches", "level" @@ -2285,6 +2285,12 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' "message_position": { "$ref": "#/definitions/positive_bignum" }, + "message_path": { + "type": "array", + "items": { + "$ref": "#/definitions/Inbox_list_hash" + } + }, "previous_message_result": { "type": "object", "properties": { @@ -2308,6 +2314,7 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' "required": [ "proof", "previous_message_result", + "message_path", "message_position", "message", "level", @@ -5055,6 +5062,24 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' }, "kind": "named" }, + { + "kind": "dyn", + "num_fields": 1, + "size": "Uint30" + }, + { + "name": "message_path", + "layout": { + "layout": { + "kind": "Bytes" + }, + "kind": "Seq" + }, + "data_kind": { + "kind": "Variable" + }, + "kind": "named" + }, { "name": "previous_message_result", "layout": { @@ -6706,7 +6731,7 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' "kind": "named" }, { - "name": "inbox_hash", + "name": "inbox_merkle_root", "layout": { "kind": "Bytes" }, @@ -7972,6 +7997,10 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' "title": "An Ed25519 public key hash (Base58Check-encoded)", "$ref": "#/definitions/unistring" }, + "Inbox_list_hash": { + "title": "A merkle root hash for inboxes (Base58Check-encoded)", + "$ref": "#/definitions/unistring" + }, "Message_result_hash": { "title": "A message result (Base58Check-encoded)", "$ref": "#/definitions/unistring" @@ -8000,10 +8029,6 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' "title": "A Ed25519, Secp256k1, or P256 public key hash (Base58Check-encoded)", "$ref": "#/definitions/unistring" }, - "Tx_rollup_inbox_hash": { - "title": "The hash of a transaction rollup inbox (Base58Check-encoded)", - "$ref": "#/definitions/unistring" - }, "Tx_rollup_l2_address": { "title": "The hash of a BLS public key used to identify a L2 ticket holders (Base58Check-encoded)", "$ref": "#/definitions/unistring" @@ -9274,12 +9299,12 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' } ] }, - "inbox_hash": { - "$ref": "#/definitions/Tx_rollup_inbox_hash" + "inbox_merkle_root": { + "$ref": "#/definitions/Inbox_list_hash" } }, "required": [ - "inbox_hash", + "inbox_merkle_root", "predecessor", "batches", "level" @@ -9585,6 +9610,12 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' "message_position": { "$ref": "#/definitions/positive_bignum" }, + "message_path": { + "type": "array", + "items": { + "$ref": "#/definitions/Inbox_list_hash" + } + }, "previous_message_result": { "type": "object", "properties": { @@ -9608,6 +9639,7 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' "required": [ "proof", "previous_message_result", + "message_path", "message_position", "message", "level", diff --git a/tezt/_regressions/tx_rollup_batch_encoding.out b/tezt/_regressions/tx_rollup_batch_encoding.out index 74993a4c9b..fee5052f59 100644 --- a/tezt/_regressions/tx_rollup_batch_encoding.out +++ b/tezt/_regressions/tx_rollup_batch_encoding.out @@ -1,8 +1,37 @@ tezt/_regressions/tx_rollup_batch_encoding.out +./tezos-client --wait none originate tx rollup from '[PUBLIC_KEY_HASH]' --burn-cap 9999999 --storage-limit 60000 +Node is bootstrapped. +Estimated gas: 1410.040 units (will add 100 for safety) +Operation successfully injected in the node. +Operation hash is '[OPERATION_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [OPERATION_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [PUBLIC_KEY_HASH] + Fee to the baker: ꜩ0.000378 + Expected counter: 1 + Gas limit: 1511 + Storage limit: 60000 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000378 + payload fees(the block proposer) ....... +ꜩ0.000378 + Tx rollup origination: + From: [PUBLIC_KEY_HASH] + This tx rollup origination operation was successfully applied + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ15 + storage fees ........................... +ꜩ15 + Consumed gas: 1410.040 + Originated tx rollup: [TX_ROLLUP_HASH] + + ./tezos-client --wait none submit tx rollup batch 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' Node is bootstrapped. -Estimated gas: 2257.992 units (will add 100 for safety) +Estimated gas: 2021.864 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -13,17 +42,17 @@ and/or an external block explorer to make sure that it has been included. This sequence of operations was run: Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.000741 + Fee to the baker: ꜩ0.000718 Expected counter: 2 - Gas limit: 2358 + Gas limit: 2122 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.000741 - payload fees(the block proposer) ....... +ꜩ0.000741 + [PUBLIC_KEY_HASH] ... -ꜩ0.000718 + payload fees(the block proposer) ....... +ꜩ0.000718 Tx rollup transaction:[TX_ROLLUP_HASH], 256 bytes, From: [PUBLIC_KEY_HASH] This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2257.992 + Consumed gas: 2021.864 "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" diff --git a/tezt/_regressions/tx_rollup_finalize_commitment_future.out b/tezt/_regressions/tx_rollup_finalize_commitment_future.out index e8b78fd166..6f42e5f4c2 100644 --- a/tezt/_regressions/tx_rollup_finalize_commitment_future.out +++ b/tezt/_regressions/tx_rollup_finalize_commitment_future.out @@ -1,8 +1,37 @@ tezt/_regressions/tx_rollup_finalize_commitment_future.out +./tezos-client --wait none originate tx rollup from '[PUBLIC_KEY_HASH]' --burn-cap 9999999 --storage-limit 60000 +Node is bootstrapped. +Estimated gas: 1410.040 units (will add 100 for safety) +Operation successfully injected in the node. +Operation hash is '[OPERATION_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [OPERATION_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [PUBLIC_KEY_HASH] + Fee to the baker: ꜩ0.000378 + Expected counter: 1 + Gas limit: 1511 + Storage limit: 60000 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000378 + payload fees(the block proposer) ....... +ꜩ0.000378 + Tx rollup origination: + From: [PUBLIC_KEY_HASH] + This tx rollup origination operation was successfully applied + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ15 + storage fees ........................... +ꜩ15 + Consumed gas: 1410.040 + Originated tx rollup: [TX_ROLLUP_HASH] + + ./tezos-client --wait none submit tx rollup batch 626c6f62 to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' Node is bootstrapped. -Estimated gas: 2257.424 units (will add 100 for safety) +Estimated gas: 2021.296 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -13,18 +42,18 @@ and/or an external block explorer to make sure that it has been included. This sequence of operations was run: Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.000489 + Fee to the baker: ꜩ0.000466 Expected counter: 2 - Gas limit: 2358 + Gas limit: 2122 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.000489 - payload fees(the block proposer) ....... +ꜩ0.000489 + [PUBLIC_KEY_HASH] ... -ꜩ0.000466 + payload fees(the block proposer) ....... +ꜩ0.000466 Tx rollup transaction:[TX_ROLLUP_HASH], 4 bytes, From: [PUBLIC_KEY_HASH] This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2257.424 + Consumed gas: 2021.296 ./tezos-client --wait none submit tx rollup finalize commitment to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' diff --git a/tezt/_regressions/tx_rollup_finalize_commitment_no_batch.out b/tezt/_regressions/tx_rollup_finalize_commitment_no_batch.out index 1037266852..276a8a2049 100644 --- a/tezt/_regressions/tx_rollup_finalize_commitment_no_batch.out +++ b/tezt/_regressions/tx_rollup_finalize_commitment_no_batch.out @@ -1,5 +1,34 @@ tezt/_regressions/tx_rollup_finalize_commitment_no_batch.out +./tezos-client --wait none originate tx rollup from '[PUBLIC_KEY_HASH]' --burn-cap 9999999 --storage-limit 60000 +Node is bootstrapped. +Estimated gas: 1410.040 units (will add 100 for safety) +Operation successfully injected in the node. +Operation hash is '[OPERATION_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [OPERATION_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [PUBLIC_KEY_HASH] + Fee to the baker: ꜩ0.000378 + Expected counter: 1 + Gas limit: 1511 + Storage limit: 60000 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000378 + payload fees(the block proposer) ....... +ꜩ0.000378 + Tx rollup origination: + From: [PUBLIC_KEY_HASH] + This tx rollup origination operation was successfully applied + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ15 + storage fees ........................... +ꜩ15 + Consumed gas: 1410.040 + Originated tx rollup: [TX_ROLLUP_HASH] + + ./tezos-client --wait none submit tx rollup finalize commitment to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' Node is bootstrapped. This simulation failed: diff --git a/tezt/_regressions/tx_rollup_finalize_commitment_no_commitment.out b/tezt/_regressions/tx_rollup_finalize_commitment_no_commitment.out index 76c9943953..4c1cdc1b9b 100644 --- a/tezt/_regressions/tx_rollup_finalize_commitment_no_commitment.out +++ b/tezt/_regressions/tx_rollup_finalize_commitment_no_commitment.out @@ -1,8 +1,37 @@ tezt/_regressions/tx_rollup_finalize_commitment_no_commitment.out +./tezos-client --wait none originate tx rollup from '[PUBLIC_KEY_HASH]' --burn-cap 9999999 --storage-limit 60000 +Node is bootstrapped. +Estimated gas: 1410.040 units (will add 100 for safety) +Operation successfully injected in the node. +Operation hash is '[OPERATION_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [OPERATION_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [PUBLIC_KEY_HASH] + Fee to the baker: ꜩ0.000378 + Expected counter: 1 + Gas limit: 1511 + Storage limit: 60000 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000378 + payload fees(the block proposer) ....... +ꜩ0.000378 + Tx rollup origination: + From: [PUBLIC_KEY_HASH] + This tx rollup origination operation was successfully applied + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ15 + storage fees ........................... +ꜩ15 + Consumed gas: 1410.040 + Originated tx rollup: [TX_ROLLUP_HASH] + + ./tezos-client --wait none submit tx rollup batch 626c6f62 to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' Node is bootstrapped. -Estimated gas: 2257.424 units (will add 100 for safety) +Estimated gas: 2021.296 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -13,18 +42,18 @@ and/or an external block explorer to make sure that it has been included. This sequence of operations was run: Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.000489 + Fee to the baker: ꜩ0.000466 Expected counter: 2 - Gas limit: 2358 + Gas limit: 2122 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.000489 - payload fees(the block proposer) ....... +ꜩ0.000489 + [PUBLIC_KEY_HASH] ... -ꜩ0.000466 + payload fees(the block proposer) ....... +ꜩ0.000466 Tx rollup transaction:[TX_ROLLUP_HASH], 4 bytes, From: [PUBLIC_KEY_HASH] This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2257.424 + Consumed gas: 2021.296 ./tezos-client --wait none submit tx rollup finalize commitment to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' diff --git a/tezt/_regressions/tx_rollup_finalize_too_recent_commitment.out b/tezt/_regressions/tx_rollup_finalize_too_recent_commitment.out index 9674716175..d860b47c42 100644 --- a/tezt/_regressions/tx_rollup_finalize_too_recent_commitment.out +++ b/tezt/_regressions/tx_rollup_finalize_too_recent_commitment.out @@ -1,8 +1,37 @@ tezt/_regressions/tx_rollup_finalize_too_recent_commitment.out +./tezos-client --wait none originate tx rollup from '[PUBLIC_KEY_HASH]' --burn-cap 9999999 --storage-limit 60000 +Node is bootstrapped. +Estimated gas: 1410.040 units (will add 100 for safety) +Operation successfully injected in the node. +Operation hash is '[OPERATION_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [OPERATION_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [PUBLIC_KEY_HASH] + Fee to the baker: ꜩ0.000378 + Expected counter: 1 + Gas limit: 1511 + Storage limit: 60000 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000378 + payload fees(the block proposer) ....... +ꜩ0.000378 + Tx rollup origination: + From: [PUBLIC_KEY_HASH] + This tx rollup origination operation was successfully applied + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ15 + storage fees ........................... +ꜩ15 + Consumed gas: 1410.040 + Originated tx rollup: [TX_ROLLUP_HASH] + + ./tezos-client --wait none submit tx rollup batch 626c6f62 to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' Node is bootstrapped. -Estimated gas: 2257.424 units (will add 100 for safety) +Estimated gas: 2021.296 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -13,24 +42,19 @@ and/or an external block explorer to make sure that it has been included. This sequence of operations was run: Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.000489 + Fee to the baker: ꜩ0.000466 Expected counter: 2 - Gas limit: 2358 + Gas limit: 2122 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.000489 - payload fees(the block proposer) ....... +ꜩ0.000489 + [PUBLIC_KEY_HASH] ... -ꜩ0.000466 + payload fees(the block proposer) ....... +ꜩ0.000466 Tx rollup transaction:[TX_ROLLUP_HASH], 4 bytes, From: [PUBLIC_KEY_HASH] This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2257.424 - + Consumed gas: 2021.296 -./tezos-client rpc get '/chains/main/blocks/head/context/tx_rollup/[TX_ROLLUP_HASH]/inbox/0' -{ "contents": [ "[TX_ROLLUP_MESSAGE_HASH]" ], - "cumulated_size": 4, - "hash": "[TX_ROLLUP_INBOX_HASH]" } ./tezos-client --wait none submit tx rollup commitment 0 '[TX_ROLLUP_INBOX_HASH]' '[TX_ROLLUP_MESSAGE_RESULT_HASH]' to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' Node is bootstrapped. @@ -52,7 +76,7 @@ This sequence of operations was run: Balance updates: [PUBLIC_KEY_HASH] ... -ꜩ0.000697 payload fees(the block proposer) ....... +ꜩ0.000697 - Tx rollup commitment:[TX_ROLLUP_HASH], commitment 0 : messages = [TX_ROLLUP_MESSAGE_RESULT_HASH] predecessor for inbox [TX_ROLLUP_INBOX_HASH] + Tx rollup commitment:[TX_ROLLUP_HASH], commitment 0 : messages = [TX_ROLLUP_MESSAGE_RESULT_HASH] predecessor for inbox with merkle root [TX_ROLLUP_INBOX_HASH] From: [PUBLIC_KEY_HASH] This tx rollup commit operation was successfully applied Balance updates: diff --git a/tezt/_regressions/tx_rollup_limit_empty_batch.out b/tezt/_regressions/tx_rollup_limit_empty_batch.out index 261baf5d50..72eb78e785 100644 --- a/tezt/_regressions/tx_rollup_limit_empty_batch.out +++ b/tezt/_regressions/tx_rollup_limit_empty_batch.out @@ -1,8 +1,37 @@ tezt/_regressions/tx_rollup_limit_empty_batch.out +./tezos-client --wait none originate tx rollup from '[PUBLIC_KEY_HASH]' --burn-cap 9999999 --storage-limit 60000 +Node is bootstrapped. +Estimated gas: 1410.040 units (will add 100 for safety) +Operation successfully injected in the node. +Operation hash is '[OPERATION_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [OPERATION_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [PUBLIC_KEY_HASH] + Fee to the baker: ꜩ0.000378 + Expected counter: 1 + Gas limit: 1511 + Storage limit: 60000 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000378 + payload fees(the block proposer) ....... +ꜩ0.000378 + Tx rollup origination: + From: [PUBLIC_KEY_HASH] + This tx rollup origination operation was successfully applied + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ15 + storage fees ........................... +ꜩ15 + Consumed gas: 1410.040 + Originated tx rollup: [TX_ROLLUP_HASH] + + ./tezos-client --wait none submit tx rollup batch to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' Node is bootstrapped. -Estimated gas: 2257.416 units (will add 100 for safety) +Estimated gas: 2021.288 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -13,16 +42,16 @@ and/or an external block explorer to make sure that it has been included. This sequence of operations was run: Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.000485 + Fee to the baker: ꜩ0.000462 Expected counter: 2 - Gas limit: 2358 + Gas limit: 2122 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.000485 - payload fees(the block proposer) ....... +ꜩ0.000485 + [PUBLIC_KEY_HASH] ... -ꜩ0.000462 + payload fees(the block proposer) ....... +ꜩ0.000462 Tx rollup transaction:[TX_ROLLUP_HASH], 0 bytes, From: [PUBLIC_KEY_HASH] This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2257.416 + Consumed gas: 2021.288 diff --git a/tezt/_regressions/tx_rollup_limit_maximum_size_batch.out b/tezt/_regressions/tx_rollup_limit_maximum_size_batch.out index 2ab87a8ed5..850cc88cb8 100644 --- a/tezt/_regressions/tx_rollup_limit_maximum_size_batch.out +++ b/tezt/_regressions/tx_rollup_limit_maximum_size_batch.out @@ -1,8 +1,37 @@ tezt/_regressions/tx_rollup_limit_maximum_size_batch.out +./tezos-client --wait none originate tx rollup from '[PUBLIC_KEY_HASH]' --burn-cap 9999999 --storage-limit 60000 +Node is bootstrapped. +Estimated gas: 1410.040 units (will add 100 for safety) +Operation successfully injected in the node. +Operation hash is '[OPERATION_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [OPERATION_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [PUBLIC_KEY_HASH] + Fee to the baker: ꜩ0.000378 + Expected counter: 1 + Gas limit: 1511 + Storage limit: 60000 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000378 + payload fees(the block proposer) ....... +ꜩ0.000378 + Tx rollup origination: + From: [PUBLIC_KEY_HASH] + This tx rollup origination operation was successfully applied + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ15 + storage fees ........................... +ꜩ15 + Consumed gas: 1410.040 + Originated tx rollup: [TX_ROLLUP_HASH] + + ./tezos-client --wait none submit tx rollup batch 6262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262 to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' Node is bootstrapped. -Estimated gas: 2268.666 units (will add 100 for safety) +Estimated gas: 2032.538 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -13,18 +42,18 @@ and/or an external block explorer to make sure that it has been included. This sequence of operations was run: Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.005486 + Fee to the baker: ꜩ0.005463 Expected counter: 2 - Gas limit: 2369 + Gas limit: 2133 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.005486 - payload fees(the block proposer) ....... +ꜩ0.005486 + [PUBLIC_KEY_HASH] ... -ꜩ0.005463 + payload fees(the block proposer) ....... +ꜩ0.005463 Tx rollup transaction:[TX_ROLLUP_HASH], 5000 bytes, From: [PUBLIC_KEY_HASH] This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2268.666 + Consumed gas: 2032.538 ./tezos-client --wait none submit tx rollup batch 636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363 to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' diff --git a/tezt/_regressions/tx_rollup_limit_maximum_size_inbox.out b/tezt/_regressions/tx_rollup_limit_maximum_size_inbox.out index a381fbbb72..ed8a6aaff4 100644 --- a/tezt/_regressions/tx_rollup_limit_maximum_size_inbox.out +++ b/tezt/_regressions/tx_rollup_limit_maximum_size_inbox.out @@ -1,8 +1,37 @@ tezt/_regressions/tx_rollup_limit_maximum_size_inbox.out +./tezos-client --wait none originate tx rollup from '[PUBLIC_KEY_HASH]' --burn-cap 9999999 --storage-limit 60000 +Node is bootstrapped. +Estimated gas: 1410.040 units (will add 100 for safety) +Operation successfully injected in the node. +Operation hash is '[OPERATION_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [OPERATION_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [PUBLIC_KEY_HASH] + Fee to the baker: ꜩ0.000378 + Expected counter: 1 + Gas limit: 1511 + Storage limit: 60000 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000378 + payload fees(the block proposer) ....... +ꜩ0.000378 + Tx rollup origination: + From: [PUBLIC_KEY_HASH] + This tx rollup origination operation was successfully applied + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ15 + storage fees ........................... +ꜩ15 + Consumed gas: 1410.040 + Originated tx rollup: [TX_ROLLUP_HASH] + + ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap1 Node is bootstrapped. -Estimated gas: 2268.666 units (will add 100 for safety) +Estimated gas: 2032.538 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -13,23 +42,23 @@ and/or an external block explorer to make sure that it has been included. This sequence of operations was run: Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.005486 + Fee to the baker: ꜩ0.005463 Expected counter: 2 - Gas limit: 2369 + Gas limit: 2133 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.005486 - payload fees(the block proposer) ....... +ꜩ0.005486 + [PUBLIC_KEY_HASH] ... -ꜩ0.005463 + payload fees(the block proposer) ....... +ꜩ0.005463 Tx rollup transaction:[TX_ROLLUP_HASH], 5000 bytes, From: [PUBLIC_KEY_HASH] This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2268.666 + Consumed gas: 2032.538 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap2 Node is bootstrapped. -Estimated gas: 2268.666 units (will add 100 for safety) +Estimated gas: 2032.538 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -40,23 +69,23 @@ and/or an external block explorer to make sure that it has been included. This sequence of operations was run: Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.005486 + Fee to the baker: ꜩ0.005463 Expected counter: 1 - Gas limit: 2369 + Gas limit: 2133 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.005486 - payload fees(the block proposer) ....... +ꜩ0.005486 + [PUBLIC_KEY_HASH] ... -ꜩ0.005463 + payload fees(the block proposer) ....... +ꜩ0.005463 Tx rollup transaction:[TX_ROLLUP_HASH], 5000 bytes, From: [PUBLIC_KEY_HASH] This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2268.666 + Consumed gas: 2032.538 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap3 Node is bootstrapped. -Estimated gas: 2268.666 units (will add 100 for safety) +Estimated gas: 2032.538 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -67,23 +96,23 @@ and/or an external block explorer to make sure that it has been included. This sequence of operations was run: Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.005486 + Fee to the baker: ꜩ0.005463 Expected counter: 1 - Gas limit: 2369 + Gas limit: 2133 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.005486 - payload fees(the block proposer) ....... +ꜩ0.005486 + [PUBLIC_KEY_HASH] ... -ꜩ0.005463 + payload fees(the block proposer) ....... +ꜩ0.005463 Tx rollup transaction:[TX_ROLLUP_HASH], 5000 bytes, From: [PUBLIC_KEY_HASH] This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2268.666 + Consumed gas: 2032.538 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap4 Node is bootstrapped. -Estimated gas: 2268.666 units (will add 100 for safety) +Estimated gas: 2032.538 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -94,23 +123,23 @@ and/or an external block explorer to make sure that it has been included. This sequence of operations was run: Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.005486 + Fee to the baker: ꜩ0.005463 Expected counter: 1 - Gas limit: 2369 + Gas limit: 2133 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.005486 - payload fees(the block proposer) ....... +ꜩ0.005486 + [PUBLIC_KEY_HASH] ... -ꜩ0.005463 + payload fees(the block proposer) ....... +ꜩ0.005463 Tx rollup transaction:[TX_ROLLUP_HASH], 5000 bytes, From: [PUBLIC_KEY_HASH] This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2268.666 + Consumed gas: 2032.538 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap5 Node is bootstrapped. -Estimated gas: 2268.666 units (will add 100 for safety) +Estimated gas: 2032.538 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -121,24 +150,24 @@ and/or an external block explorer to make sure that it has been included. This sequence of operations was run: Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.005486 + Fee to the baker: ꜩ0.005463 Expected counter: 1 - Gas limit: 2369 + Gas limit: 2133 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.005486 - payload fees(the block proposer) ....... +ꜩ0.005486 + [PUBLIC_KEY_HASH] ... -ꜩ0.005463 + payload fees(the block proposer) ....... +ꜩ0.005463 Tx rollup transaction:[TX_ROLLUP_HASH], 5000 bytes, From: [PUBLIC_KEY_HASH] This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2268.666 + Consumed gas: 2032.538 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap6 Node is bootstrapped. Estimated storage: no bytes added -Estimated gas: 2268.666 units (will add 100 for safety) +Estimated gas: 2032.538 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -163,24 +192,24 @@ This sequence of operations was run: Consumed gas: 1000 Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.00539 + Fee to the baker: ꜩ0.005367 Expected counter: 2 - Gas limit: 2369 + Gas limit: 2133 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.00539 - payload fees(the block proposer) ....... +ꜩ0.00539 + [PUBLIC_KEY_HASH] ... -ꜩ0.005367 + payload fees(the block proposer) ....... +ꜩ0.005367 Tx rollup transaction:[TX_ROLLUP_HASH], 5000 bytes, From: [PUBLIC_KEY_HASH] This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2268.666 + Consumed gas: 2032.538 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap7 Node is bootstrapped. Estimated storage: no bytes added -Estimated gas: 2268.666 units (will add 100 for safety) +Estimated gas: 2032.538 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -205,24 +234,24 @@ This sequence of operations was run: Consumed gas: 1000 Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.00539 + Fee to the baker: ꜩ0.005367 Expected counter: 2 - Gas limit: 2369 + Gas limit: 2133 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.00539 - payload fees(the block proposer) ....... +ꜩ0.00539 + [PUBLIC_KEY_HASH] ... -ꜩ0.005367 + payload fees(the block proposer) ....... +ꜩ0.005367 Tx rollup transaction:[TX_ROLLUP_HASH], 5000 bytes, From: [PUBLIC_KEY_HASH] This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2268.666 + Consumed gas: 2032.538 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap8 Node is bootstrapped. Estimated storage: no bytes added -Estimated gas: 2268.666 units (will add 100 for safety) +Estimated gas: 2032.538 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -247,24 +276,24 @@ This sequence of operations was run: Consumed gas: 1000 Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.00539 + Fee to the baker: ꜩ0.005367 Expected counter: 2 - Gas limit: 2369 + Gas limit: 2133 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.00539 - payload fees(the block proposer) ....... +ꜩ0.00539 + [PUBLIC_KEY_HASH] ... -ꜩ0.005367 + payload fees(the block proposer) ....... +ꜩ0.005367 Tx rollup transaction:[TX_ROLLUP_HASH], 5000 bytes, From: [PUBLIC_KEY_HASH] This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2268.666 + Consumed gas: 2032.538 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap9 Node is bootstrapped. Estimated storage: no bytes added -Estimated gas: 2268.666 units (will add 100 for safety) +Estimated gas: 2032.538 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -289,24 +318,24 @@ This sequence of operations was run: Consumed gas: 1000 Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.00539 + Fee to the baker: ꜩ0.005367 Expected counter: 2 - Gas limit: 2369 + Gas limit: 2133 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.00539 - payload fees(the block proposer) ....... +ꜩ0.00539 + [PUBLIC_KEY_HASH] ... -ꜩ0.005367 + payload fees(the block proposer) ....... +ꜩ0.005367 Tx rollup transaction:[TX_ROLLUP_HASH], 5000 bytes, From: [PUBLIC_KEY_HASH] This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2268.666 + Consumed gas: 2032.538 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap10 Node is bootstrapped. Estimated storage: no bytes added -Estimated gas: 2268.666 units (will add 100 for safety) +Estimated gas: 2032.538 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -331,24 +360,24 @@ This sequence of operations was run: Consumed gas: 1000 Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.00539 + Fee to the baker: ꜩ0.005367 Expected counter: 2 - Gas limit: 2369 + Gas limit: 2133 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.00539 - payload fees(the block proposer) ....... +ꜩ0.00539 + [PUBLIC_KEY_HASH] ... -ꜩ0.005367 + payload fees(the block proposer) ....... +ꜩ0.005367 Tx rollup transaction:[TX_ROLLUP_HASH], 5000 bytes, From: [PUBLIC_KEY_HASH] This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2268.666 + Consumed gas: 2032.538 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap11 Node is bootstrapped. Estimated storage: no bytes added -Estimated gas: 2268.666 units (will add 100 for safety) +Estimated gas: 2032.538 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -373,24 +402,24 @@ This sequence of operations was run: Consumed gas: 1000 Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.00539 + Fee to the baker: ꜩ0.005367 Expected counter: 2 - Gas limit: 2369 + Gas limit: 2133 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.00539 - payload fees(the block proposer) ....... +ꜩ0.00539 + [PUBLIC_KEY_HASH] ... -ꜩ0.005367 + payload fees(the block proposer) ....... +ꜩ0.005367 Tx rollup transaction:[TX_ROLLUP_HASH], 5000 bytes, From: [PUBLIC_KEY_HASH] This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2268.666 + Consumed gas: 2032.538 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap12 Node is bootstrapped. Estimated storage: no bytes added -Estimated gas: 2268.666 units (will add 100 for safety) +Estimated gas: 2032.538 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -415,24 +444,24 @@ This sequence of operations was run: Consumed gas: 1000 Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.00539 + Fee to the baker: ꜩ0.005367 Expected counter: 2 - Gas limit: 2369 + Gas limit: 2133 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.00539 - payload fees(the block proposer) ....... +ꜩ0.00539 + [PUBLIC_KEY_HASH] ... -ꜩ0.005367 + payload fees(the block proposer) ....... +ꜩ0.005367 Tx rollup transaction:[TX_ROLLUP_HASH], 5000 bytes, From: [PUBLIC_KEY_HASH] This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2268.666 + Consumed gas: 2032.538 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap13 Node is bootstrapped. Estimated storage: no bytes added -Estimated gas: 2268.666 units (will add 100 for safety) +Estimated gas: 2032.538 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -457,24 +486,24 @@ This sequence of operations was run: Consumed gas: 1000 Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.00539 + Fee to the baker: ꜩ0.005367 Expected counter: 2 - Gas limit: 2369 + Gas limit: 2133 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.00539 - payload fees(the block proposer) ....... +ꜩ0.00539 + [PUBLIC_KEY_HASH] ... -ꜩ0.005367 + payload fees(the block proposer) ....... +ꜩ0.005367 Tx rollup transaction:[TX_ROLLUP_HASH], 5000 bytes, From: [PUBLIC_KEY_HASH] This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2268.666 + Consumed gas: 2032.538 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap14 Node is bootstrapped. Estimated storage: no bytes added -Estimated gas: 2268.666 units (will add 100 for safety) +Estimated gas: 2032.538 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -499,24 +528,24 @@ This sequence of operations was run: Consumed gas: 1000 Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.00539 + Fee to the baker: ꜩ0.005367 Expected counter: 2 - Gas limit: 2369 + Gas limit: 2133 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.00539 - payload fees(the block proposer) ....... +ꜩ0.00539 + [PUBLIC_KEY_HASH] ... -ꜩ0.005367 + payload fees(the block proposer) ....... +ꜩ0.005367 Tx rollup transaction:[TX_ROLLUP_HASH], 5000 bytes, From: [PUBLIC_KEY_HASH] This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2268.666 + Consumed gas: 2032.538 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap15 Node is bootstrapped. Estimated storage: no bytes added -Estimated gas: 2268.666 units (will add 100 for safety) +Estimated gas: 2032.538 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -541,24 +570,24 @@ This sequence of operations was run: Consumed gas: 1000 Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.00539 + Fee to the baker: ꜩ0.005367 Expected counter: 2 - Gas limit: 2369 + Gas limit: 2133 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.00539 - payload fees(the block proposer) ....... +ꜩ0.00539 + [PUBLIC_KEY_HASH] ... -ꜩ0.005367 + payload fees(the block proposer) ....... +ꜩ0.005367 Tx rollup transaction:[TX_ROLLUP_HASH], 5000 bytes, From: [PUBLIC_KEY_HASH] This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2268.666 + Consumed gas: 2032.538 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap16 Node is bootstrapped. Estimated storage: no bytes added -Estimated gas: 2268.666 units (will add 100 for safety) +Estimated gas: 2032.538 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -583,24 +612,24 @@ This sequence of operations was run: Consumed gas: 1000 Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.00539 + Fee to the baker: ꜩ0.005367 Expected counter: 2 - Gas limit: 2369 + Gas limit: 2133 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.00539 - payload fees(the block proposer) ....... +ꜩ0.00539 + [PUBLIC_KEY_HASH] ... -ꜩ0.005367 + payload fees(the block proposer) ....... +ꜩ0.005367 Tx rollup transaction:[TX_ROLLUP_HASH], 5000 bytes, From: [PUBLIC_KEY_HASH] This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2268.666 + Consumed gas: 2032.538 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap17 Node is bootstrapped. Estimated storage: no bytes added -Estimated gas: 2268.666 units (will add 100 for safety) +Estimated gas: 2032.538 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -625,24 +654,24 @@ This sequence of operations was run: Consumed gas: 1000 Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.00539 + Fee to the baker: ꜩ0.005367 Expected counter: 2 - Gas limit: 2369 + Gas limit: 2133 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.00539 - payload fees(the block proposer) ....... +ꜩ0.00539 + [PUBLIC_KEY_HASH] ... -ꜩ0.005367 + payload fees(the block proposer) ....... +ꜩ0.005367 Tx rollup transaction:[TX_ROLLUP_HASH], 5000 bytes, From: [PUBLIC_KEY_HASH] This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2268.666 + Consumed gas: 2032.538 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap18 Node is bootstrapped. Estimated storage: no bytes added -Estimated gas: 2268.666 units (will add 100 for safety) +Estimated gas: 2032.538 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -667,24 +696,24 @@ This sequence of operations was run: Consumed gas: 1000 Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.00539 + Fee to the baker: ꜩ0.005367 Expected counter: 2 - Gas limit: 2369 + Gas limit: 2133 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.00539 - payload fees(the block proposer) ....... +ꜩ0.00539 + [PUBLIC_KEY_HASH] ... -ꜩ0.005367 + payload fees(the block proposer) ....... +ꜩ0.005367 Tx rollup transaction:[TX_ROLLUP_HASH], 5000 bytes, From: [PUBLIC_KEY_HASH] This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2268.666 + Consumed gas: 2032.538 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap19 Node is bootstrapped. Estimated storage: no bytes added -Estimated gas: 2268.666 units (will add 100 for safety) +Estimated gas: 2032.538 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -709,24 +738,24 @@ This sequence of operations was run: Consumed gas: 1000 Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.00539 + Fee to the baker: ꜩ0.005367 Expected counter: 2 - Gas limit: 2369 + Gas limit: 2133 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.00539 - payload fees(the block proposer) ....... +ꜩ0.00539 + [PUBLIC_KEY_HASH] ... -ꜩ0.005367 + payload fees(the block proposer) ....... +ꜩ0.005367 Tx rollup transaction:[TX_ROLLUP_HASH], 5000 bytes, From: [PUBLIC_KEY_HASH] This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2268.666 + Consumed gas: 2032.538 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap20 Node is bootstrapped. Estimated storage: no bytes added -Estimated gas: 2268.666 units (will add 100 for safety) +Estimated gas: 2032.538 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -751,41 +780,20 @@ This sequence of operations was run: Consumed gas: 1000 Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.00539 + Fee to the baker: ꜩ0.005367 Expected counter: 2 - Gas limit: 2369 + Gas limit: 2133 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.00539 - payload fees(the block proposer) ....... +ꜩ0.00539 + [PUBLIC_KEY_HASH] ... -ꜩ0.005367 + payload fees(the block proposer) ....... +ꜩ0.005367 Tx rollup transaction:[TX_ROLLUP_HASH], 5000 bytes, From: [PUBLIC_KEY_HASH] This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2268.666 + Consumed gas: 2032.538 ./tezos-client rpc get '/chains/main/blocks/head/context/tx_rollup/[TX_ROLLUP_HASH]/inbox/0' -{ "contents": - [ "[TX_ROLLUP_MESSAGE_HASH]", - "[TX_ROLLUP_MESSAGE_HASH]", - "[TX_ROLLUP_MESSAGE_HASH]", - "[TX_ROLLUP_MESSAGE_HASH]", - "[TX_ROLLUP_MESSAGE_HASH]", - "[TX_ROLLUP_MESSAGE_HASH]", - "[TX_ROLLUP_MESSAGE_HASH]", - "[TX_ROLLUP_MESSAGE_HASH]", - "[TX_ROLLUP_MESSAGE_HASH]", - "[TX_ROLLUP_MESSAGE_HASH]", - "[TX_ROLLUP_MESSAGE_HASH]", - "[TX_ROLLUP_MESSAGE_HASH]", - "[TX_ROLLUP_MESSAGE_HASH]", - "[TX_ROLLUP_MESSAGE_HASH]", - "[TX_ROLLUP_MESSAGE_HASH]", - "[TX_ROLLUP_MESSAGE_HASH]", - "[TX_ROLLUP_MESSAGE_HASH]", - "[TX_ROLLUP_MESSAGE_HASH]", - "[TX_ROLLUP_MESSAGE_HASH]", - "[TX_ROLLUP_MESSAGE_HASH]" ], - "cumulated_size": 100000, - "hash": "[TX_ROLLUP_INBOX_HASH]" } +{ "inbox_length": 20, "cumulated_size": 100000, + "merkle_root": "[TX_ROLLUP_INBOX_HASH]" } diff --git a/tezt/_regressions/tx_rollup_rpc_commitment.out b/tezt/_regressions/tx_rollup_rpc_commitment.out index 8e0775b3b7..b468828cfd 100644 --- a/tezt/_regressions/tx_rollup_rpc_commitment.out +++ b/tezt/_regressions/tx_rollup_rpc_commitment.out @@ -1,8 +1,37 @@ tezt/_regressions/tx_rollup_rpc_commitment.out +./tezos-client --wait none originate tx rollup from '[PUBLIC_KEY_HASH]' --burn-cap 9999999 --storage-limit 60000 +Node is bootstrapped. +Estimated gas: 1410.040 units (will add 100 for safety) +Operation successfully injected in the node. +Operation hash is '[OPERATION_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [OPERATION_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [PUBLIC_KEY_HASH] + Fee to the baker: ꜩ0.000378 + Expected counter: 1 + Gas limit: 1511 + Storage limit: 60000 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000378 + payload fees(the block proposer) ....... +ꜩ0.000378 + Tx rollup origination: + From: [PUBLIC_KEY_HASH] + This tx rollup origination operation was successfully applied + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ15 + storage fees ........................... +ꜩ15 + Consumed gas: 1410.040 + Originated tx rollup: [TX_ROLLUP_HASH] + + ./tezos-client --wait none submit tx rollup batch 626c6f62 to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' Node is bootstrapped. -Estimated gas: 2257.424 units (will add 100 for safety) +Estimated gas: 2021.296 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -13,18 +42,18 @@ and/or an external block explorer to make sure that it has been included. This sequence of operations was run: Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.000489 + Fee to the baker: ꜩ0.000466 Expected counter: 2 - Gas limit: 2358 + Gas limit: 2122 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.000489 - payload fees(the block proposer) ....... +ꜩ0.000489 + [PUBLIC_KEY_HASH] ... -ꜩ0.000466 + payload fees(the block proposer) ....... +ꜩ0.000466 Tx rollup transaction:[TX_ROLLUP_HASH], 4 bytes, From: [PUBLIC_KEY_HASH] This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2257.424 + Consumed gas: 2021.296 ./tezos-client --wait none submit tx rollup commitment 0 '[TX_ROLLUP_INBOX_HASH]' '[TX_ROLLUP_MESSAGE_RESULT_HASH]' to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' @@ -47,7 +76,7 @@ This sequence of operations was run: Balance updates: [PUBLIC_KEY_HASH] ... -ꜩ0.000697 payload fees(the block proposer) ....... +ꜩ0.000697 - Tx rollup commitment:[TX_ROLLUP_HASH], commitment 0 : messages = [TX_ROLLUP_MESSAGE_RESULT_HASH] predecessor for inbox [TX_ROLLUP_INBOX_HASH] + Tx rollup commitment:[TX_ROLLUP_HASH], commitment 0 : messages = [TX_ROLLUP_MESSAGE_RESULT_HASH] predecessor for inbox with merkle root [TX_ROLLUP_INBOX_HASH] From: [PUBLIC_KEY_HASH] This tx rollup commit operation was successfully applied Balance updates: @@ -61,6 +90,7 @@ This sequence of operations was run: { "level": 0, "batches": [ "[TX_ROLLUP_MESSAGE_RESULT_HASH]" ], "predecessor": null, - "inbox_hash": "[TX_ROLLUP_INBOX_HASH]" }, + "inbox_merkle_root": + "[TX_ROLLUP_INBOX_HASH]" }, "commitment_hash": "[TX_ROLLUP_COMMITMENT_HASH]", "committer": "[PUBLIC_KEY_HASH]", "submitted_at": 5 } diff --git a/tezt/_regressions/tx_rollup_rpc_inbox.out b/tezt/_regressions/tx_rollup_rpc_inbox.out index 6071ed3b49..9f02e4d0dc 100644 --- a/tezt/_regressions/tx_rollup_rpc_inbox.out +++ b/tezt/_regressions/tx_rollup_rpc_inbox.out @@ -1,8 +1,37 @@ tezt/_regressions/tx_rollup_rpc_inbox.out +./tezos-client --wait none originate tx rollup from '[PUBLIC_KEY_HASH]' --burn-cap 9999999 --storage-limit 60000 +Node is bootstrapped. +Estimated gas: 1410.040 units (will add 100 for safety) +Operation successfully injected in the node. +Operation hash is '[OPERATION_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [OPERATION_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [PUBLIC_KEY_HASH] + Fee to the baker: ꜩ0.000378 + Expected counter: 1 + Gas limit: 1511 + Storage limit: 60000 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000378 + payload fees(the block proposer) ....... +ꜩ0.000378 + Tx rollup origination: + From: [PUBLIC_KEY_HASH] + This tx rollup origination operation was successfully applied + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ15 + storage fees ........................... +ꜩ15 + Consumed gas: 1410.040 + Originated tx rollup: [TX_ROLLUP_HASH] + + ./tezos-client --wait none submit tx rollup batch 626c6f62 to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' Node is bootstrapped. -Estimated gas: 2257.424 units (will add 100 for safety) +Estimated gas: 2021.296 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -13,21 +42,20 @@ and/or an external block explorer to make sure that it has been included. This sequence of operations was run: Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.000489 + Fee to the baker: ꜩ0.000466 Expected counter: 2 - Gas limit: 2358 + Gas limit: 2122 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.000489 - payload fees(the block proposer) ....... +ꜩ0.000489 + [PUBLIC_KEY_HASH] ... -ꜩ0.000466 + payload fees(the block proposer) ....... +ꜩ0.000466 Tx rollup transaction:[TX_ROLLUP_HASH], 4 bytes, From: [PUBLIC_KEY_HASH] This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2257.424 + Consumed gas: 2021.296 ./tezos-client rpc get '/chains/main/blocks/head/context/tx_rollup/[TX_ROLLUP_HASH]/inbox/0' -{ "contents": [ "[TX_ROLLUP_MESSAGE_HASH]" ], - "cumulated_size": 4, - "hash": "[TX_ROLLUP_INBOX_HASH]" } +{ "inbox_length": 1, "cumulated_size": 4, + "merkle_root": "[TX_ROLLUP_INBOX_HASH]" } diff --git a/tezt/_regressions/tx_rollup_rpc_inbox_merkle_tree_hash.out b/tezt/_regressions/tx_rollup_rpc_inbox_merkle_tree_hash.out new file mode 100644 index 0000000000..439b29c52b --- /dev/null +++ b/tezt/_regressions/tx_rollup_rpc_inbox_merkle_tree_hash.out @@ -0,0 +1,23 @@ +tezt/_regressions/tx_rollup_rpc_inbox_merkle_tree_hash.out + +./tezos-client rpc post /chains/main/blocks/head/helpers/forge/tx_rollup/inbox/message_hash with '{ + "message": { + "batch": "blob" + } +}' + +./tezos-client rpc post /chains/main/blocks/head/helpers/forge/tx_rollup/inbox/message_hash with '{ + "message": { + "batch": "gloubiboulga" + } +}' +{ "hash": "[TX_ROLLUP_MESSAGE_HASH]" } +{ "hash": "[TX_ROLLUP_MESSAGE_HASH]" } + +./tezos-client rpc post /chains/main/blocks/head/helpers/forge/tx_rollup/inbox/merkle_tree_hash with '{ + "message_hashes": [ + "[TX_ROLLUP_MESSAGE_HASH]", + "[TX_ROLLUP_MESSAGE_HASH]" + ] +}' +{ "hash": "[TX_ROLLUP_INBOX_HASH]" } diff --git a/tezt/_regressions/tx_rollup_rpc_inbox_merkle_tree_path.out b/tezt/_regressions/tx_rollup_rpc_inbox_merkle_tree_path.out new file mode 100644 index 0000000000..76a9e1e10e --- /dev/null +++ b/tezt/_regressions/tx_rollup_rpc_inbox_merkle_tree_path.out @@ -0,0 +1,68 @@ +tezt/_regressions/tx_rollup_rpc_inbox_merkle_tree_path.out + +./tezos-client rpc post /chains/main/blocks/head/helpers/forge/tx_rollup/inbox/message_hash with '{ + "message": { + "batch": "Kouroukoukou" + } +}' + +./tezos-client rpc post /chains/main/blocks/head/helpers/forge/tx_rollup/inbox/message_hash with '{ + "message": { + "batch": "roukoukou" + } +}' + +./tezos-client rpc post /chains/main/blocks/head/helpers/forge/tx_rollup/inbox/message_hash with '{ + "message": { + "batch": "stach" + } +}' + +./tezos-client rpc post /chains/main/blocks/head/helpers/forge/tx_rollup/inbox/message_hash with '{ + "message": { + "batch": "stach" + } +}' +{ "hash": "[TX_ROLLUP_MESSAGE_HASH]" } +{ "hash": "[TX_ROLLUP_MESSAGE_HASH]" } +{ "hash": "[TX_ROLLUP_MESSAGE_HASH]" } +{ "hash": "[TX_ROLLUP_MESSAGE_HASH]" } + +./tezos-client rpc post /chains/main/blocks/head/helpers/forge/tx_rollup/inbox/merkle_tree_path with '{ + "message_hashes": [ + "[TX_ROLLUP_MESSAGE_HASH]", + "[TX_ROLLUP_MESSAGE_HASH]", + "[TX_ROLLUP_MESSAGE_HASH]", + "[TX_ROLLUP_MESSAGE_HASH]" + ], + "position": 3 +}' +{ "path": + [ "[TX_ROLLUP_INBOX_HASH]", + "[TX_ROLLUP_INBOX_HASH]" ] } + +./tezos-client rpc post /chains/main/blocks/head/helpers/forge/tx_rollup/inbox/merkle_tree_path with '{ + "message_hashes": [ + "[TX_ROLLUP_MESSAGE_HASH]", + "[TX_ROLLUP_MESSAGE_HASH]", + "[TX_ROLLUP_MESSAGE_HASH]", + "[TX_ROLLUP_MESSAGE_HASH]" + ], + "position": 0 +}' +{ "path": + [ "[TX_ROLLUP_INBOX_HASH]", + "[TX_ROLLUP_INBOX_HASH]" ] } + +./tezos-client rpc post /chains/main/blocks/head/helpers/forge/tx_rollup/inbox/merkle_tree_path with '{ + "message_hashes": [ + "[TX_ROLLUP_MESSAGE_HASH]", + "[TX_ROLLUP_MESSAGE_HASH]", + "[TX_ROLLUP_MESSAGE_HASH]", + "[TX_ROLLUP_MESSAGE_HASH]" + ], + "position": 4 +}' +Fatal error: + Command failed: Merkle_list_invalid_position + diff --git a/tezt/_regressions/tx_rollup_rpc_inbox_message_hash.out b/tezt/_regressions/tx_rollup_rpc_inbox_message_hash.out new file mode 100644 index 0000000000..47106bb015 --- /dev/null +++ b/tezt/_regressions/tx_rollup_rpc_inbox_message_hash.out @@ -0,0 +1,8 @@ +tezt/_regressions/tx_rollup_rpc_inbox_message_hash.out + +./tezos-client rpc post /chains/main/blocks/head/helpers/forge/tx_rollup/inbox/message_hash with '{ + "message": { + "batch": "blob" + } +}' +{ "hash": "[TX_ROLLUP_MESSAGE_HASH]" } diff --git a/tezt/_regressions/tx_rollup_rpc_pending_bonded_commitments.out b/tezt/_regressions/tx_rollup_rpc_pending_bonded_commitments.out index 63fb69deb5..0af0bfcfa3 100644 --- a/tezt/_regressions/tx_rollup_rpc_pending_bonded_commitments.out +++ b/tezt/_regressions/tx_rollup_rpc_pending_bonded_commitments.out @@ -1,8 +1,37 @@ tezt/_regressions/tx_rollup_rpc_pending_bonded_commitments.out +./tezos-client --wait none originate tx rollup from '[PUBLIC_KEY_HASH]' --burn-cap 9999999 --storage-limit 60000 +Node is bootstrapped. +Estimated gas: 1410.040 units (will add 100 for safety) +Operation successfully injected in the node. +Operation hash is '[OPERATION_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [OPERATION_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [PUBLIC_KEY_HASH] + Fee to the baker: ꜩ0.000378 + Expected counter: 1 + Gas limit: 1511 + Storage limit: 60000 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000378 + payload fees(the block proposer) ....... +ꜩ0.000378 + Tx rollup origination: + From: [PUBLIC_KEY_HASH] + This tx rollup origination operation was successfully applied + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ15 + storage fees ........................... +ꜩ15 + Consumed gas: 1410.040 + Originated tx rollup: [TX_ROLLUP_HASH] + + ./tezos-client --wait none submit tx rollup batch 626c6f62 to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' Node is bootstrapped. -Estimated gas: 2257.424 units (will add 100 for safety) +Estimated gas: 2021.296 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -13,18 +42,18 @@ and/or an external block explorer to make sure that it has been included. This sequence of operations was run: Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.000489 + Fee to the baker: ꜩ0.000466 Expected counter: 2 - Gas limit: 2358 + Gas limit: 2122 Storage limit: 0 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.000489 - payload fees(the block proposer) ....... +ꜩ0.000489 + [PUBLIC_KEY_HASH] ... -ꜩ0.000466 + payload fees(the block proposer) ....... +ꜩ0.000466 Tx rollup transaction:[TX_ROLLUP_HASH], 4 bytes, From: [PUBLIC_KEY_HASH] This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2257.424 + Consumed gas: 2021.296 ./tezos-client --wait none submit tx rollup commitment 0 '[TX_ROLLUP_INBOX_HASH]' '[TX_ROLLUP_MESSAGE_RESULT_HASH]' to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' @@ -47,7 +76,7 @@ This sequence of operations was run: Balance updates: [PUBLIC_KEY_HASH] ... -ꜩ0.000697 payload fees(the block proposer) ....... +ꜩ0.000697 - Tx rollup commitment:[TX_ROLLUP_HASH], commitment 0 : messages = [TX_ROLLUP_MESSAGE_RESULT_HASH] predecessor for inbox [TX_ROLLUP_INBOX_HASH] + Tx rollup commitment:[TX_ROLLUP_HASH], commitment 0 : messages = [TX_ROLLUP_MESSAGE_RESULT_HASH] predecessor for inbox with merkle root [TX_ROLLUP_INBOX_HASH] From: [PUBLIC_KEY_HASH] This tx rollup commit operation was successfully applied Balance updates: diff --git a/tezt/_regressions/tx_rollup_rpc_state.out b/tezt/_regressions/tx_rollup_rpc_state.out index d2c0a6d100..e9578fad78 100644 --- a/tezt/_regressions/tx_rollup_rpc_state.out +++ b/tezt/_regressions/tx_rollup_rpc_state.out @@ -1,5 +1,34 @@ tezt/_regressions/tx_rollup_rpc_state.out +./tezos-client --wait none originate tx rollup from '[PUBLIC_KEY_HASH]' --burn-cap 9999999 --storage-limit 60000 +Node is bootstrapped. +Estimated gas: 1410.040 units (will add 100 for safety) +Operation successfully injected in the node. +Operation hash is '[OPERATION_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [OPERATION_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [PUBLIC_KEY_HASH] + Fee to the baker: ꜩ0.000378 + Expected counter: 1 + Gas limit: 1511 + Storage limit: 60000 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000378 + payload fees(the block proposer) ....... +ꜩ0.000378 + Tx rollup origination: + From: [PUBLIC_KEY_HASH] + This tx rollup origination operation was successfully applied + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ15 + storage fees ........................... +ꜩ15 + Consumed gas: 1410.040 + Originated tx rollup: [TX_ROLLUP_HASH] + + ./tezos-client rpc get '/chains/main/blocks/head/context/tx_rollup/[TX_ROLLUP_HASH]/state' { "last_removed_commitment_hashes": null, "commitment_tail_level": null, "oldest_inbox_level": null, "commitment_head_level": null, diff --git a/tezt/lib_tezos/RPC.ml b/tezt/lib_tezos/RPC.ml index 6bacd17732..47f1d6dde4 100644 --- a/tezt/lib_tezos/RPC.ml +++ b/tezt/lib_tezos/RPC.ml @@ -580,6 +580,61 @@ module Tx_rollup = struct sub_path ~chain ~block ~rollup ["pending_bonded_commitments"; pkh] in Client.Spawn.rpc ?endpoint ?hooks GET path client + + module Forge = struct + module Inbox = struct + let message_hash ?endpoint ?hooks ?(chain = "main") ?(block = "head") + ~data client = + let path = + [ + "chains"; + chain; + "blocks"; + block; + "helpers"; + "forge"; + "tx_rollup"; + "inbox"; + "message_hash"; + ] + in + Client.Spawn.rpc ?endpoint ?hooks ~data POST path client + + let merkle_tree_hash ?endpoint ?hooks ?(chain = "main") ?(block = "head") + ~data client = + let path = + [ + "chains"; + chain; + "blocks"; + block; + "helpers"; + "forge"; + "tx_rollup"; + "inbox"; + "merkle_tree_hash"; + ] + in + Client.Spawn.rpc ?endpoint ?hooks ~data POST path client + + let merkle_tree_path ?endpoint ?hooks ?(chain = "main") ?(block = "head") + ~data client = + let path = + [ + "chains"; + chain; + "blocks"; + block; + "helpers"; + "forge"; + "tx_rollup"; + "inbox"; + "merkle_tree_path"; + ] + in + Client.Spawn.rpc ?endpoint ?hooks ~data POST path client + end + end end module Sc_rollup = struct diff --git a/tezt/lib_tezos/RPC.mli b/tezt/lib_tezos/RPC.mli index 44d6e73ada..24d3bda9e6 100644 --- a/tezt/lib_tezos/RPC.mli +++ b/tezt/lib_tezos/RPC.mli @@ -900,6 +900,37 @@ module Tx_rollup : sig pkh:string -> Client.t -> JSON.t Process.runnable + + module Forge : sig + module Inbox : sig + val message_hash : + ?endpoint:Client.endpoint -> + ?hooks:Process.hooks -> + ?chain:string -> + ?block:string -> + data:JSON.u -> + Client.t -> + JSON.t Process.runnable + + val merkle_tree_hash : + ?endpoint:Client.endpoint -> + ?hooks:Process.hooks -> + ?chain:string -> + ?block:string -> + data:JSON.u -> + Client.t -> + JSON.t Process.runnable + + val merkle_tree_path : + ?endpoint:Client.endpoint -> + ?hooks:Process.hooks -> + ?chain:string -> + ?block:string -> + data:JSON.u -> + Client.t -> + JSON.t Process.runnable + end + end end module Sc_rollup : sig diff --git a/tezt/lib_tezos/client.ml b/tezt/lib_tezos/client.ml index d66ad41b90..c7ac0b7bfa 100644 --- a/tezt/lib_tezos/client.ml +++ b/tezt/lib_tezos/client.ml @@ -1185,9 +1185,10 @@ let sign_block client block_hex ~delegate = module Tx_rollup = struct let originate ?(wait = "none") ?(burn_cap = Tez.of_int 9_999_999) - ?(storage_limit = 60_000) ~src client = + ?(storage_limit = 60_000) ?hooks ~src client = let process = spawn_command + ?hooks client [ "--wait"; @@ -1242,7 +1243,7 @@ module Tx_rollup = struct {value = process; run = parse} let submit_commitment ?(wait = "none") ?burn_cap ?storage_limit ?hooks ~level - ~roots ~predecessor ~inbox_hash ~rollup ~src client = + ~roots ~predecessor ~inbox_merkle_root ~rollup ~src client = let process = let predecessor = Option.value ~default:"" predecessor in spawn_command @@ -1255,7 +1256,7 @@ module Tx_rollup = struct "rollup"; "commitment"; Int.to_string level; - inbox_hash; + inbox_merkle_root; predecessor; ] @ [String.concat "!" roots] @@ -1315,8 +1316,8 @@ module Tx_rollup = struct {value = process; run = parse} let submit_rejection ?(wait = "none") ?burn_cap ?storage_limit ?hooks ~level - ~message ~position ~proof ~context_hash ~withdraw_list_hash ~rollup ~src - client = + ~message ~position ~path ~proof ~context_hash ~withdraw_list_hash ~rollup + ~src client = let process = spawn_command ?hooks @@ -1326,6 +1327,7 @@ module Tx_rollup = struct @ ["at"; "level"; string_of_int level] @ ["message"; message] @ ["at"; "position"; string_of_int position] + @ ["and"; "path"; path] @ ["with"; "proof"; string_of_bool proof] @ ["with"; "agreed"; "context"; "hash"; context_hash] @ ["and"; "withdraw"; "list"; withdraw_list_hash] diff --git a/tezt/lib_tezos/client.mli b/tezt/lib_tezos/client.mli index 145803198a..27004b61cf 100644 --- a/tezt/lib_tezos/client.mli +++ b/tezt/lib_tezos/client.mli @@ -904,6 +904,7 @@ module Tx_rollup : sig ?wait:string -> ?burn_cap:Tez.t -> ?storage_limit:int -> + ?hooks:Process.hooks -> src:string -> t -> string Process.runnable @@ -929,7 +930,7 @@ module Tx_rollup : sig level:int -> roots:string list -> predecessor:string option -> - inbox_hash:string -> + inbox_merkle_root:string -> rollup:string -> src:string -> t -> @@ -969,6 +970,7 @@ module Tx_rollup : sig level:int -> message:string -> position:int -> + path:string -> proof:bool -> context_hash:string -> withdraw_list_hash:string -> diff --git a/tezt/lib_tezos/operation.ml b/tezt/lib_tezos/operation.ml index 64f6f64d98..bda00c8fcd 100644 --- a/tezt/lib_tezos/operation.ml +++ b/tezt/lib_tezos/operation.ml @@ -50,6 +50,7 @@ type manager_op_kind = level : int; message : [`Batch of string]; message_position : int; + message_path : string list; previous_message_result : string * string; } @@ -131,7 +132,7 @@ let mk_reveal ~source ?counter ?(fee = 1_000) ?(gas_limit = 1040) let mk_rejection ~source ?counter ?(fee = 1_000_000) ?(gas_limit = 1_000_000) ?(storage_limit = 0) ~tx_rollup ~proof ~level ~message ~message_position - ~previous_message_result client = + ~message_path ~previous_message_result client = mk_manager_op ~source ?counter ~fee ~gas_limit ~storage_limit client @@ Rejection { @@ -140,6 +141,7 @@ let mk_rejection ~source ?counter ?(fee = 1_000_000) ?(gas_limit = 1_000_000) level; message; message_position; + message_path; previous_message_result; } @@ -155,7 +157,7 @@ let manager_op_content_to_json_string let mk_jsonm ?(amount = `Null) ?(destination = `Null) ?(parameter = `Null) ?(public_key = `Null) ?(balance = `Null) ?(script = `Null) ?(proof = `Null) ?(rollup = `Null) ?(message = `Null) - ?(message_position = `Null) ?(level = `Null) + ?(message_position = `Null) ?(message_path = `Null) ?(level = `Null) ?(previous_message_result = `Null) kind = let filter = List.filter (fun (_k, v) -> v <> `Null) in return @@ -182,6 +184,7 @@ let manager_op_content_to_json_string ("rollup", rollup); ("message", message); ("message_position", message_position); + ("message_path", message_path); ("previous_message_result", previous_message_result); ("level", level); ]) @@ -215,6 +218,7 @@ let manager_op_content_to_json_string level; message; message_position; + message_path; previous_message_result; } -> let rollup = `String tx_rollup in @@ -224,6 +228,7 @@ let manager_op_content_to_json_string match message with `Batch str -> `O [("batch", `String str)] in let message_position = `String (string_of_int message_position) in + let message_path = `A (List.map (fun x -> `String x) message_path) in let previous_message_result = `O [ @@ -237,6 +242,7 @@ let manager_op_content_to_json_string ~level ~message ~message_position + ~message_path ~previous_message_result "tx_rollup_rejection" @@ -373,7 +379,8 @@ let inject_transfer ?protocol ?async ?force ?wait_for_injection ?branch ~source let inject_rejection ?protocol ?async ?force ?wait_for_injection ?branch ~source ?(signer = source) ?counter ?fee ?gas_limit ?storage_limit ~tx_rollup ~proof - ~level ~message ~message_position ~previous_message_result client = + ~level ~message ~message_position ~message_path ~previous_message_result + client = let* op = mk_rejection ~source @@ -386,6 +393,7 @@ let inject_rejection ?protocol ?async ?force ?wait_for_injection ?branch ~source ~level ~message ~message_position + ~message_path ~previous_message_result client in diff --git a/tezt/lib_tezos/operation.mli b/tezt/lib_tezos/operation.mli index 2ca1c9dcb1..6373ddb7d7 100644 --- a/tezt/lib_tezos/operation.mli +++ b/tezt/lib_tezos/operation.mli @@ -108,6 +108,7 @@ val mk_rejection : level:int -> message:[`Batch of string] -> message_position:int -> + message_path:string list -> previous_message_result:string * string -> Client.t -> manager_operation_content Lwt.t @@ -378,6 +379,7 @@ val inject_rejection : level:int -> message:[`Batch of string] -> message_position:int -> + message_path:string list -> previous_message_result:string * string -> Client.t -> [> `OpHash of string] Lwt.t diff --git a/tezt/lib_tezos/rollup.ml b/tezt/lib_tezos/rollup.ml index 2190499bcf..d9f253accb 100644 --- a/tezt/lib_tezos/rollup.ml +++ b/tezt/lib_tezos/rollup.ml @@ -32,7 +32,7 @@ module Tx_rollup = struct inbox_ema : int; } - type inbox = {cumulated_size : int; contents : string list; hash : string} + type inbox = {inbox_length : int; cumulated_size : int; merkle_root : string} let get_state ?hooks ~rollup client = let parse json = @@ -68,12 +68,10 @@ module Tx_rollup = struct let get_inbox ?hooks ~rollup ~level client = let parse json = + let inbox_length = JSON.(json |-> "inbox_length" |> as_int) in let cumulated_size = JSON.(json |-> "cumulated_size" |> as_int) in - let contents = - JSON.(json |-> "contents" |> as_list |> List.map as_string) - in - let hash = JSON.(json |-> "hash" |> as_string) in - {cumulated_size; contents; hash} + let merkle_root = JSON.(json |-> "merkle_root" |> as_string) in + {inbox_length; cumulated_size; merkle_root} in let runnable = RPC.Tx_rollup.get_inbox ?hooks ~rollup ~level client in Process.runnable_map parse runnable @@ -89,6 +87,58 @@ module Tx_rollup = struct ~pkh client + let message_hash ?hooks ~message:(`Batch message) client = + let parse json = `Hash JSON.(json |-> "hash" |> as_string) in + let data : JSON.u = `O [("message", `O [("batch", `String message)])] in + let runnable = RPC.Tx_rollup.Forge.Inbox.message_hash ?hooks ~data client in + Process.runnable_map parse runnable + + let inbox_merkle_tree_hash ?hooks ~message_hashes client = + let parse json = `Hash JSON.(json |-> "hash" |> as_string) in + let make_message (`Hash message) : JSON.u = `String message in + let data = + `O [("message_hashes", `A (List.map make_message message_hashes))] + in + let runnable = + RPC.Tx_rollup.Forge.Inbox.merkle_tree_hash ?hooks ~data client + in + Process.runnable_map parse runnable + + let inbox_merkle_tree_path ?hooks ~message_hashes ~position client = + let parse json = JSON.(json |-> "path") in + let make_message (`Hash message) : JSON.u = `String message in + let data = + `O + [ + ("message_hashes", `A (List.map make_message message_hashes)); + ("position", `Float (float_of_int position)); + ] + in + let runnable = + RPC.Tx_rollup.Forge.Inbox.merkle_tree_path ?hooks ~data client + in + Process.runnable_map parse runnable + + let compute_inbox_from_messages ?hooks messages client = + let* message_hashes = + Lwt_list.map_p + (fun message -> + let*! message_hash = message_hash ?hooks ~message client in + return message_hash) + messages + in + let*! (`Hash merkle_root) = + inbox_merkle_tree_hash ?hooks ~message_hashes client + in + return + { + inbox_length = List.length messages; + cumulated_size = + List.map (fun (`Batch message) -> String.length message) messages + |> List.fold_left ( + ) 0; + merkle_root; + } + module Check = struct let state : state Check.typ = let open Check in @@ -115,9 +165,9 @@ module Tx_rollup = struct let inbox : inbox Check.typ = let open Check in convert - (fun {cumulated_size; contents; hash} -> - (cumulated_size, contents, hash)) - (tuple3 int (list string) string) + (fun {inbox_length; cumulated_size; merkle_root} -> + (inbox_length, cumulated_size, merkle_root)) + (tuple3 int int string) end module Parameters = struct diff --git a/tezt/lib_tezos/rollup.mli b/tezt/lib_tezos/rollup.mli index 97e8bc5595..1bf4e72003 100644 --- a/tezt/lib_tezos/rollup.mli +++ b/tezt/lib_tezos/rollup.mli @@ -32,7 +32,7 @@ module Tx_rollup : sig inbox_ema : int; } - type inbox = {cumulated_size : int; contents : string list; hash : string} + type inbox = {inbox_length : int; cumulated_size : int; merkle_root : string} val get_state : ?hooks:Process.hooks -> rollup:string -> Client.t -> state Process.runnable @@ -60,6 +60,28 @@ module Tx_rollup : sig Client.t -> JSON.t Process.runnable + val message_hash : + ?hooks:Process.hooks -> + message:[`Batch of string] -> + Client.t -> + [> `Hash of string] Process.runnable + + val inbox_merkle_tree_hash : + ?hooks:Process.hooks -> + message_hashes:[`Hash of string] list -> + Client.t -> + [> `Hash of string] Process.runnable + + val inbox_merkle_tree_path : + ?hooks:Process.hooks -> + message_hashes:[`Hash of string] list -> + position:int -> + Client.t -> + JSON.t Process.runnable + + val compute_inbox_from_messages : + ?hooks:Process.hooks -> [`Batch of string] list -> Client.t -> inbox Lwt.t + module Check : sig val state : state Check.typ diff --git a/tezt/tests/tx_rollup.ml b/tezt/tests/tx_rollup.ml index 6150009120..192a1cdea5 100644 --- a/tezt/tests/tx_rollup.ml +++ b/tezt/tests/tx_rollup.ml @@ -55,7 +55,10 @@ let init_with_tx_rollup ?additional_bootstrap_account_count (* We originate a dumb rollup to be able to generate a paths for tx_rollups related RPCs. *) let*! rollup = - Client.Tx_rollup.originate ~src:Constant.bootstrap1.public_key_hash client + Client.Tx_rollup.originate + ~hooks + ~src:Constant.bootstrap1.public_key_hash + client in let* () = Client.bake_for client in let* _ = Node.wait_for_level node 2 in @@ -75,14 +78,21 @@ let submit_batch ~batch {rollup; client; node} = let* _ = Node.wait_for_level node (current_level + 1) in return () -let submit_commitment ~level ~roots ~inbox_hash ~predecessor +let submit_commitment ~level ~roots ~inbox_content ~predecessor {rollup; client; node} = + let* inbox_merkle_root = + match inbox_content with + | `Root inbox_merkle_root -> inbox_merkle_root + | `Content messages -> + let* inbox = Rollup.compute_inbox_from_messages messages client in + return inbox.merkle_root + in let*! () = Client.Tx_rollup.submit_commitment ~hooks ~level ~roots - ~inbox_hash + ~inbox_merkle_root ~predecessor ~rollup ~src:Constant.bootstrap1.public_key_hash @@ -148,6 +158,73 @@ module Regressions = struct let*! _inbox = Rollup.get_inbox ~hooks ~rollup ~level:0 client in unit + let rpc_inbox_message_hash = + Protocol.register_regression_test + ~__FILE__ + ~output_file:(fun _ -> "tx_rollup_rpc_inbox_message_hash") + ~title:"RPC (tx_rollups, regression) - inbox message hash" + ~tags:["tx_rollup"; "rpc"; "inbox"; "message"] + @@ fun protocol -> + let* (_node, client) = Client.init_with_protocol `Client ~protocol () in + let message = `Batch "blob" in + let*! _hash = Rollup.message_hash ~hooks ~message client in + unit + + let rpc_inbox_merkle_tree_hash = + Protocol.register_regression_test + ~__FILE__ + ~output_file:(fun _ -> "tx_rollup_rpc_inbox_merkle_tree_hash") + ~title:"RPC (tx_rollups, regression) - inbox merkle tree hash" + ~tags:["tx_rollup"; "rpc"; "inbox"; "merkle_tree_hash"] + @@ fun protocol -> + let* (_node, client) = Client.init_with_protocol `Client ~protocol () in + let messages = [`Batch "blob"; `Batch "gloubiboulga"] in + let* message_hashes = + Lwt_list.map_p + (fun message -> + let*! message_hash = Rollup.message_hash ~hooks ~message client in + return message_hash) + messages + in + let*! _hash = + Rollup.inbox_merkle_tree_hash ~hooks ~message_hashes client + in + unit + + let rpc_inbox_merkle_tree_path = + Protocol.register_regression_test + ~__FILE__ + ~output_file:(fun _ -> "tx_rollup_rpc_inbox_merkle_tree_path") + ~title:"RPC (tx_rollups, regression) - inbox merkle tree path" + ~tags:["tx_rollup"; "rpc"; "inbox"; "merkle_tree_path"] + @@ fun protocol -> + let* (_node, client) = Client.init_with_protocol `Client ~protocol () in + let messages = + [ + `Batch "Kouroukoukou"; + `Batch "roukoukou"; + `Batch "stach"; + `Batch "stach"; + ] + in + let* message_hashes = + Lwt_list.map_p + (fun message -> + let*! message_hash = Rollup.message_hash ~hooks ~message client in + return message_hash) + messages + in + let*! _ = + Rollup.inbox_merkle_tree_path ~hooks ~message_hashes ~position:3 client + in + let*! _ = + Rollup.inbox_merkle_tree_path ~hooks ~message_hashes ~position:0 client + in + let*? process = + Rollup.inbox_merkle_tree_path ~hooks ~message_hashes ~position:4 client + in + Process.check_error ~msg:(rex "Merkle_list_invalid_positio") process + let rpc_commitment = Protocol.register_regression_test ~__FILE__ @@ -161,13 +238,13 @@ module Regressions = struct (* The content of the batch does not matter for the regression test. *) let batch = "blob" in let* () = submit_batch ~batch state in - let*! inbox = Rollup.get_inbox ~rollup ~level:0 client in let* () = Client.bake_for client in + let inbox_content = `Content [`Batch batch] in let* () = submit_commitment ~level:0 ~roots:[Constant.tx_rollup_initial_message_result] - ~inbox_hash:inbox.hash + ~inbox_content ~predecessor:None state in @@ -189,13 +266,13 @@ module Regressions = struct (* The content of the batch does not matter for the regression test. *) let batch = "blob" in let* () = submit_batch ~batch state in - let*! inbox = Rollup.get_inbox ~rollup ~level:0 client in let* () = Client.bake_for client in + let inbox_content = `Content [`Batch batch] in let* () = submit_commitment ~level:0 ~roots:[Constant.tx_rollup_initial_message_result] - ~inbox_hash:inbox.hash + ~inbox_content ~predecessor:None state in @@ -321,7 +398,7 @@ module Regressions = struct let current_level = Node.get_level node in let* () = Client.bake_for client in let* _ = Node.wait_for_level node (current_level + 1) in - let*! {cumulated_size; contents = _; hash = _} = + let*! {inbox_length = _; cumulated_size; merkle_root = _} = Rollup.get_inbox ~hooks ~rollup ~level:0 client in Check.(cumulated_size = inbox_limit) @@ -431,19 +508,19 @@ module Regressions = struct ~title:"Try to finalize a too recent commitment" ~tags:["tx_rollup"; "client"; "fail"; "finalize"] @@ fun protocol -> - let* ({rollup; client; node = _} as state) = + let* ({rollup = _; client; node = _} as state) = init_with_tx_rollup ~protocol () in (* The content of the batch does not matter for the regression test. *) let batch = "blob" in let* () = submit_batch ~batch state in let* () = Client.bake_for client in - let*! inbox = Rollup.get_inbox ~hooks ~rollup ~level:0 client in + let inbox_content = `Content [`Batch batch] in let* () = submit_commitment ~level:0 ~roots:[Constant.tx_rollup_initial_message_result] - ~inbox_hash:inbox.hash + ~inbox_content ~predecessor:None state in @@ -458,6 +535,9 @@ module Regressions = struct let register protocols = RPC.rpc_state protocols ; RPC.rpc_inbox protocols ; + RPC.rpc_inbox_message_hash protocols ; + RPC.rpc_inbox_merkle_tree_hash protocols ; + RPC.rpc_inbox_merkle_tree_path protocols ; RPC.rpc_commitment protocols ; RPC.rpc_pending_bonded_commitment protocols ; RPC.batch_encoding protocols ; @@ -478,7 +558,7 @@ let hooks = Tezos_regression.hooks let submit_three_batches_and_check_size ~rollup ~tezos_level ~tx_level node client batches = let* () = - Lwt_list.iter_p + Lwt_list.iter_s (fun (content, src, _) -> let*! () = Client.Tx_rollup.submit_batch ~hooks ~content ~rollup ~src client @@ -489,17 +569,9 @@ let submit_three_batches_and_check_size ~rollup ~tezos_level ~tx_level node let* () = Client.bake_for client in let* _ = Node.wait_for_level node tezos_level in (* Check the inbox has been created, with the expected cumulated size. *) - let expected_inbox = - Rollup. - { - cumulated_size = - List.fold_left - (fun acc (batch, _, _) -> acc + String.length batch) - 0 - batches; - contents = List.map (fun (_, _, batch) -> batch) batches; - hash = "txi2hmtibM1ez7ZPbPy8CqSnc9PC3t6E8yqy3YkMB5HgGdoUFWVJ6"; - } + let messages = List.map (fun (contents, _, _) -> `Batch contents) batches in + let* expected_inbox = + Rollup.compute_inbox_from_messages ~hooks messages client in let*! inbox = Rollup.get_inbox ~hooks ~rollup ~level:tx_level client in Check.( @@ -519,7 +591,10 @@ let test_submit_batches_in_several_blocks = Client.init_with_protocol ~parameter_file `Client ~protocol () in let*! rollup = - Client.Tx_rollup.originate ~src:Constant.bootstrap1.public_key_hash client + Client.Tx_rollup.originate + ~hooks + ~src:Constant.bootstrap1.public_key_hash + client in let* () = Client.bake_for client in let* _ = Node.wait_for_level node 2 in @@ -552,19 +627,20 @@ let test_submit_batches_in_several_blocks = let batch1 = "tezos" in let batch2 = "tx_rollup" in let batch3 = "layer-2" in - - (* Hashes are hardcoded, but could be computed programmatically. *) + let*! (`Hash batch1_hash) = + Rollup.message_hash ~message:(`Batch batch1) client + in + let*! (`Hash batch2_hash) = + Rollup.message_hash ~message:(`Batch batch2) client + in + let*! (`Hash batch3_hash) = + Rollup.message_hash ~message:(`Batch batch3) client + in let submission = [ - ( batch1, - Constant.bootstrap1.public_key_hash, - "txm37A8bG21TrYeVYD8XEQXzHq97SsPqWYY4B95TSRYCre1bUhLx2" ); - ( batch2, - Constant.bootstrap2.public_key_hash, - "txm2yd71FfMZN8AEL8BXNhuWi4sDRxpDFjPBAH1rR6YrKe7Bfffm6" ); - ( batch3, - Constant.bootstrap3.public_key_hash, - "txm2z2WP4WDYiwjgE4U1qTL3mTHsVTJAtvLZo8nJq3c9EQqSHJBS7" ); + (batch2, Constant.bootstrap2.public_key_hash, batch2_hash); + (batch3, Constant.bootstrap3.public_key_hash, batch3_hash); + (batch1, Constant.bootstrap1.public_key_hash, batch1_hash); ] in (* Let’s try once and see if everything goes as expected *) @@ -658,12 +734,12 @@ let test_rollup_with_two_commitments = let batch = "blob" in let* () = submit_batch ~batch state in let* () = Client.bake_for client in - let*! inbox = Rollup.get_inbox ~hooks ~rollup ~level:0 client in + let inbox_content = `Content [`Batch batch] in let* () = submit_commitment ~level:0 ~roots:[Constant.tx_rollup_initial_message_result] - ~inbox_hash:inbox.hash + ~inbox_content ~predecessor:None state in @@ -701,7 +777,6 @@ let test_rollup_with_two_commitments = Check.(second_op_status = "failed") Check.string ~error_msg:"The second operation status expected is %R. Got %L" ; - (* let*! _ = Rollup.get_inbox ~rollup ~level:0 client in *) (* We try to finalize a new commitment but it fails. *) let*? process = submit_finalize_commitment state in let* () = @@ -713,7 +788,6 @@ let test_rollup_with_two_commitments = let batch = "blob" in let* () = submit_batch ~batch state in let* () = Client.bake_for client in - let*! inbox = Rollup.get_inbox ~hooks ~rollup ~level:1 client in let*! commitment = Rollup.get_commitment ~hooks ~rollup ~level:0 client in let* () = Client.bake_for client in let*! () = @@ -721,11 +795,12 @@ let test_rollup_with_two_commitments = in let* () = Client.bake_for client in let predecessor = Some JSON.(commitment |-> "commitment_hash" |> as_string) in + let inbox_content = `Content [`Batch batch] in let* () = submit_commitment ~level:1 ~roots:[Constant.tx_rollup_initial_message_result] - ~inbox_hash:inbox.hash + ~inbox_content ~predecessor state in @@ -764,12 +839,12 @@ let test_rollup_last_commitment_is_rejected = let batch = "blob" in let* () = submit_batch ~batch state in let* () = Client.bake_for client in - let*! inbox = Rollup.get_inbox ~hooks ~rollup ~level:0 client in + let inbox_content = `Content [`Batch batch] in let* () = submit_commitment ~level:0 ~roots:[Constant.tx_rollup_initial_message_result] - ~inbox_hash:inbox.hash + ~inbox_content ~predecessor:None state in @@ -777,6 +852,13 @@ let test_rollup_last_commitment_is_rejected = repeat parameters.finality_period (fun () -> Client.bake_for client) in let*! _ = RPC.Tx_rollup.get_state ~rollup client in + let*! message_hash = Rollup.message_hash ~message:(`Batch "blob") client in + let*! path = + Rollup.inbox_merkle_tree_path + ~message_hashes:[message_hash] + ~position:0 + client + in (* This is the encoding of [batch]. *) let message = "{ \"batch\": \"blob\"}" in let*! () = @@ -784,6 +866,7 @@ let test_rollup_last_commitment_is_rejected = ~level:0 ~message ~position:0 + ~path:(path |> JSON.encode) ~proof:true ~context_hash:Constant.tx_rollup_empty_l2_context ~withdraw_list_hash:Constant.tx_rollup_empty_withdraw_list @@ -807,12 +890,12 @@ let test_rollup_wrong_rejection = let batch = "blob" in let* () = submit_batch ~batch state in let* () = Client.bake_for client in - let*! inbox = Rollup.get_inbox ~hooks ~rollup ~level:0 client in + let inbox_content = `Content [`Batch batch] in let* () = submit_commitment ~level:0 ~roots:[Constant.tx_rollup_initial_message_result] - ~inbox_hash:inbox.hash + ~inbox_content ~predecessor:None state in @@ -821,6 +904,15 @@ let test_rollup_wrong_rejection = in (* This is the encoding of [batch]. *) let message = `Batch batch in + let*! _ = RPC.Tx_rollup.get_state ~rollup client in + let*! message_hash = Rollup.message_hash ~message:(`Batch "blob") client in + let*! path = + Rollup.inbox_merkle_tree_path + ~message_hashes:[message_hash] + ~position:0 + client + in + let message_path = List.map (fun x -> JSON.as_string x) (JSON.as_list path) in let* (`OpHash _op) = Operation.inject_rejection ~source:Constant.bootstrap1 @@ -829,6 +921,7 @@ let test_rollup_wrong_rejection = ~level:0 ~message ~message_position:0 + ~message_path ~previous_message_result: ( Constant.tx_rollup_empty_l2_context, Constant.tx_rollup_empty_withdraw_list ) diff --git a/tezt/tests/tx_rollup_node.ml b/tezt/tests/tx_rollup_node.ml index 5e656dc1ab..d837aaf557 100644 --- a/tezt/tests/tx_rollup_node.ml +++ b/tezt/tests/tx_rollup_node.ml @@ -45,17 +45,26 @@ let node_rpc node service = let* result = get ~url in return (Some (result |> JSON.parse ~origin:service)) -let get_node_inbox ?(block = "head") node = - let* json = node_rpc node @@ "block/" ^ block ^ "/proto_inbox" in +(* This function computes an inbox from the messages stored by the + rollup node. The way the inbox is computed is to use helpers + exposed by the protocol. *) +let get_node_inbox ?(block = "head") node client = + let* json = node_rpc node @@ "block/" ^ block ^ "/inbox" in match json with - | None -> return Rollup.{cumulated_size = 0; contents = []; hash = ""} + | None -> + return Rollup.{inbox_length = 0; cumulated_size = 0; merkle_root = ""} | Some json -> - let cumulated_size = JSON.(json |-> "cumulated_size" |> as_int) in - let contents = - JSON.(json |-> "contents" |> as_list |> List.map as_string) + let parse_message json = + if JSON.(is_null (json |-> "batch")) then + Test.fail "This case is not handled yet" + else JSON.(json |-> "batch" |> as_string |> fun x -> `Batch x) in - let hash = JSON.(json |-> "hash" |> as_string) in - return Rollup.{cumulated_size; contents; hash} + let messages = + JSON.( + json |-> "contents" |> as_list + |> List.map (fun x -> x |-> "message" |> parse_message)) + in + Rollup.compute_inbox_from_messages messages client let get_rollup_parameter_file ~protocol = let enable_tx_rollup = [(["tx_rollup_enable"], Some "true")] in @@ -144,24 +153,6 @@ let test_tx_node_origination = let* _tx_node = init_and_run_rollup_node ~operator node client in unit) -let check_inbox_equality (i1 : Rollup.inbox) (i2 : Rollup.inbox) = - Check.( - (( = ) - i1.cumulated_size - i2.cumulated_size - ~error_msg: - "Cumulated size of inboxes computed by the rollup node should be \ - equal to the cumulated size given by the RPC") - int) ; - Check.( - ( = ) - i1.contents - i2.contents - ~error_msg: - "Content of inboxes computed by the rollup node should be equal to the \ - cumulated size given by the RPC" - (list string)) - (* Checks that an inbox received by the tx_rollup node is well stored and available in a percistent way. *) let test_tx_node_store_inbox = @@ -202,11 +193,15 @@ let test_tx_node_store_inbox = let* () = Client.bake_for client in let* _ = Node.wait_for_level node 3 in let* _ = Rollup_node.wait_for_tezos_level tx_node 3 in - let* node_inbox_1 = get_node_inbox ~block:"0" tx_node in - let*! inbox_1 = Rollup.get_inbox ~rollup ~level:0 client in + let* node_inbox_1 = get_node_inbox ~block:"0" tx_node client in + let*! expected_inbox_1 = Rollup.get_inbox ~rollup ~level:0 client in (* Ensure that stored inboxes on daemon's side are equivalent of inboxes returned by the rpc call. *) - check_inbox_equality node_inbox_1 inbox_1 ; + Check.(node_inbox_1 = expected_inbox_1) + Rollup.Check.inbox + ~error_msg: + "Unexpected inbox computed from the rollup node. Expected %R. \ + Computed %L" ; let snd_batch = "tezos_l2_batch_2" in let*! () = Client.Tx_rollup.submit_batch @@ -218,17 +213,25 @@ let test_tx_node_store_inbox = let* () = Client.bake_for client in let* _ = Node.wait_for_level node 4 in let* _ = Rollup_node.wait_for_tezos_level tx_node 4 in - let* node_inbox_2 = get_node_inbox ~block:"1" tx_node in - let*! inbox_2 = Rollup.get_inbox ~rollup ~level:1 client in + let* node_inbox_2 = get_node_inbox ~block:"1" tx_node client in + let*! expected_inbox_2 = Rollup.get_inbox ~rollup ~level:1 client in (* Ensure that stored inboxes on daemon side are equivalent of inboxes returned by the rpc call. *) - check_inbox_equality node_inbox_2 inbox_2 ; + Check.(node_inbox_2 = expected_inbox_2) + Rollup.Check.inbox + ~error_msg: + "Unexpected inbox computed from the rollup node. Expected %R. \ + Computed %L" ; (* Stop the node and try to get the inbox once again*) let* () = Rollup_node.terminate tx_node in let* () = Rollup_node.run tx_node in let* () = Rollup_node.wait_for_ready tx_node in let*! inbox_after_restart = Rollup.get_inbox ~rollup ~level:1 client in - check_inbox_equality node_inbox_2 inbox_after_restart ; + Check.(node_inbox_2 = inbox_after_restart) + Rollup.Check.inbox + ~error_msg: + "Unexpected inbox computed from the rollup node. Expected %R. \ + Computed %L" ; unit) (* FIXME/TORU: This is a temporary way of querying the node without @@ -590,8 +593,10 @@ let test_l2_to_l2_transaction = let* () = Client.bake_for client in let* _ = Node.wait_for_level node 6 in let* _ = Rollup_node.wait_for_tezos_level tx_node 6 in - let* _node_inbox = get_node_inbox tx_node in - Format.printf "ticket 1 %s@." ticket_id ; + (* The decoding fails because of the buggy JSON encoding. This + line can be uncommented once it is fixed. + + let* _node_inbox = get_node_inbox tx_node client in *) let* () = check_tz4_balance ~tx_node From 382bd829541e8f8482b42086b7f0fd66cd3716f7 Mon Sep 17 00:00:00 2001 From: Thomas Letan <lthms@nomadic-labs.com> Date: Sat, 19 Mar 2022 10:47:22 +0100 Subject: [PATCH 072/100] Tezt: Update regressions for failing tests --- tezt/self_tests/test-retry.t | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tezt/self_tests/test-retry.t b/tezt/self_tests/test-retry.t index f1aa0d7bc8..4c77ee0387 100644 --- a/tezt/self_tests/test-retry.t +++ b/tezt/self_tests/test-retry.t @@ -5,7 +5,7 @@ Without --retry, we fail as usual. Starting test: Fail every other run test [error] Failing test on first try [FAILURE] (2/3, 1 failed) Fail every other run test - Try again with: ./main.exe --verbose --test 'Fail every other run test' + Try again with: ./main.exe --verbose --title 'Fail every other run test' [1] With --keep-going but without --retry, we run all tests and fail as usual. @@ -15,11 +15,11 @@ With --keep-going but without --retry, we run all tests and fail as usual. Starting test: Fail every other run test [error] Failing test on first try [FAILURE] (2/3, 1 failed) Fail every other run test - Try again with: ./main.exe --verbose --test 'Fail every other run test' + Try again with: ./main.exe --verbose --title 'Fail every other run test' Starting test: Failing test [error] Always failing test [FAILURE] (3/3, 2 failed) Failing test - Try again with: ./main.exe --verbose --test 'Failing test' + Try again with: ./main.exe --verbose --title 'Failing test' [1] If we set --retry, then the "fail once" test will eventually @@ -37,7 +37,7 @@ succeed. However, the "fail always" test will fail the test suite. Starting test: Failing test [error] Always failing test [FAILURE] (3/3, 1 failed) Failing test - Try again with: ./main.exe --verbose --test 'Failing test' + Try again with: ./main.exe --verbose --title 'Failing test' [1] @@ -64,7 +64,7 @@ With --keep-going, we still fail: Starting test: Failing test [error] Always failing test [FAILURE] (3/3, 1 failed) Failing test - Try again with: ./main.exe --verbose --test 'Failing test' + Try again with: ./main.exe --verbose --title 'Failing test' [1] Looping is handled: @@ -81,7 +81,7 @@ Looping is handled: Starting test: Failing test [error] Always failing test [FAILURE] (3/3, 1 failed) (loop 1) Failing test - Try again with: ./main.exe --verbose --test 'Failing test' + Try again with: ./main.exe --verbose --title 'Failing test' [SUCCESS] (1/3, 1 failed) (loop 2) Success Starting test: Fail every other run test [error] Failing test on first try @@ -93,7 +93,7 @@ Looping is handled: Starting test: Failing test [error] Always failing test [FAILURE] (3/3, 2 failed) (loop 2) Failing test - Try again with: ./main.exe --verbose --test 'Failing test' + Try again with: ./main.exe --verbose --title 'Failing test' [1] Retries work with `-j`, but we don't know the order of the output. So From 13f705134b00b1571c78ec18a470fc55ec9371f2 Mon Sep 17 00:00:00 2001 From: Arvid Jakobsson <arvid.jakobsson@nomadic-labs.com> Date: Wed, 16 Mar 2022 10:25:58 +0100 Subject: [PATCH 073/100] Tezt: print file in failing test error message --- tezt/lib/test.ml | 3 ++- tezt/self_tests/test-basic.t | 8 ++++++++ tezt/self_tests/test-retry.t | 14 +++++++------- 3 files changed, 17 insertions(+), 8 deletions(-) create mode 100644 tezt/self_tests/test-basic.t diff --git a/tezt/lib/test.ml b/tezt/lib/test.ml index 74ca705d32..23f7a36835 100644 --- a/tezt/lib/test.ml +++ b/tezt/lib/test.ml @@ -1139,8 +1139,9 @@ let run () = test.session_successful_runs + single_seconds time) | Failed _ -> Log.report - "Try again with: %s --verbose --title %s" + "Try again with: %s --verbose --file %s --title %s" Sys.argv.(0) + (Log.quote_shell test.file) (Log.quote_shell test.title) ; test.session_failed_runs <- Summed_durations.( diff --git a/tezt/self_tests/test-basic.t b/tezt/self_tests/test-basic.t new file mode 100644 index 0000000000..a2e6593d82 --- /dev/null +++ b/tezt/self_tests/test-basic.t @@ -0,0 +1,8 @@ +Run a test that should fail: + + $ ./tezt.sh --file test_retry.ml --test 'Failing test' + Starting test: Failing test + [error] Always failing test + [FAILURE] (1/1, 1 failed) Failing test + Try again with: ./main.exe --verbose --file test_retry.ml --test 'Failing test' + [1] diff --git a/tezt/self_tests/test-retry.t b/tezt/self_tests/test-retry.t index 4c77ee0387..fb089cbbee 100644 --- a/tezt/self_tests/test-retry.t +++ b/tezt/self_tests/test-retry.t @@ -5,7 +5,7 @@ Without --retry, we fail as usual. Starting test: Fail every other run test [error] Failing test on first try [FAILURE] (2/3, 1 failed) Fail every other run test - Try again with: ./main.exe --verbose --title 'Fail every other run test' + Try again with: ./main.exe --verbose --file test_retry.ml --title 'Fail every other run test' [1] With --keep-going but without --retry, we run all tests and fail as usual. @@ -15,11 +15,11 @@ With --keep-going but without --retry, we run all tests and fail as usual. Starting test: Fail every other run test [error] Failing test on first try [FAILURE] (2/3, 1 failed) Fail every other run test - Try again with: ./main.exe --verbose --title 'Fail every other run test' + Try again with: ./main.exe --verbose --file test_retry.ml --title 'Fail every other run test' Starting test: Failing test [error] Always failing test [FAILURE] (3/3, 2 failed) Failing test - Try again with: ./main.exe --verbose --title 'Failing test' + Try again with: ./main.exe --verbose --file test_retry.ml --title 'Failing test' [1] If we set --retry, then the "fail once" test will eventually @@ -37,7 +37,7 @@ succeed. However, the "fail always" test will fail the test suite. Starting test: Failing test [error] Always failing test [FAILURE] (3/3, 1 failed) Failing test - Try again with: ./main.exe --verbose --title 'Failing test' + Try again with: ./main.exe --verbose --file test_retry.ml --title 'Failing test' [1] @@ -64,7 +64,7 @@ With --keep-going, we still fail: Starting test: Failing test [error] Always failing test [FAILURE] (3/3, 1 failed) Failing test - Try again with: ./main.exe --verbose --title 'Failing test' + Try again with: ./main.exe --verbose --file test_retry.ml --title 'Failing test' [1] Looping is handled: @@ -81,7 +81,7 @@ Looping is handled: Starting test: Failing test [error] Always failing test [FAILURE] (3/3, 1 failed) (loop 1) Failing test - Try again with: ./main.exe --verbose --title 'Failing test' + Try again with: ./main.exe --verbose --file test_retry.ml --title 'Failing test' [SUCCESS] (1/3, 1 failed) (loop 2) Success Starting test: Fail every other run test [error] Failing test on first try @@ -93,7 +93,7 @@ Looping is handled: Starting test: Failing test [error] Always failing test [FAILURE] (3/3, 2 failed) (loop 2) Failing test - Try again with: ./main.exe --verbose --title 'Failing test' + Try again with: ./main.exe --verbose --file test_retry.ml --title 'Failing test' [1] Retries work with `-j`, but we don't know the order of the output. So From 461bc6dfbec83709d96875d7d06d43263580218e Mon Sep 17 00:00:00 2001 From: Sylvain Ribstein <sylvain.ribstein@nomadic-labs.com> Date: Mon, 14 Mar 2022 16:40:25 +0100 Subject: [PATCH 074/100] Proto/ticket table: use table of ticket for deposit and withdraw --- src/proto_alpha/bin_tx_rollup_node/daemon.ml | 23 +- .../lib_client/operation_result.ml | 12 +- src/proto_alpha/lib_protocol/TEZOS_PROTOCOL | 2 + src/proto_alpha/lib_protocol/alpha_context.ml | 19 +- .../lib_protocol/alpha_context.mli | 35 +- src/proto_alpha/lib_protocol/apply.ml | 219 ++++--- src/proto_alpha/lib_protocol/apply_results.ml | 31 +- .../lib_protocol/apply_results.mli | 2 + src/proto_alpha/lib_protocol/dune.inc | 5 + .../lib_protocol/script_ir_translator.ml | 38 -- .../lib_protocol/script_ir_translator.mli | 6 - .../michelson/test_ticket_accounting.ml | 49 +- .../michelson/test_ticket_balance.ml | 6 +- .../michelson/test_ticket_balance_key.ml | 6 +- .../michelson/test_ticket_manager.ml | 4 +- .../michelson/test_ticket_operations_diff.ml | 218 +++++-- .../integration/operations/test_tx_rollup.ml | 588 +++++++++++++----- .../lib_protocol/ticket_accounting.ml | 4 +- .../lib_protocol/ticket_balance_key.ml | 32 +- .../lib_protocol/ticket_balance_key.mli | 12 +- .../ticket_balance_migration_for_j.ml | 7 +- .../lib_protocol/ticket_operations_diff.ml | 71 ++- .../lib_protocol/ticket_operations_diff.mli | 2 +- .../lib_protocol/ticket_token_map.ml | 5 +- .../lib_protocol/tx_rollup_errors_repr.ml | 22 +- .../lib_protocol/tx_rollup_l2_qty.ml | 2 + .../lib_protocol/tx_rollup_l2_qty.mli | 3 + .../lib_protocol/tx_rollup_parameters.ml | 42 ++ .../lib_protocol/tx_rollup_parameters.mli | 49 ++ .../lib_protocol/tx_rollup_repr.ml | 8 - .../lib_protocol/tx_rollup_repr.mli | 26 - tezt/_regressions/tx_node_configuration.out | 2 - tezt/self_tests/test-basic.t | 2 +- 33 files changed, 1051 insertions(+), 501 deletions(-) create mode 100644 src/proto_alpha/lib_protocol/tx_rollup_parameters.ml create mode 100644 src/proto_alpha/lib_protocol/tx_rollup_parameters.mli delete mode 100644 tezt/_regressions/tx_node_configuration.out diff --git a/src/proto_alpha/bin_tx_rollup_node/daemon.ml b/src/proto_alpha/bin_tx_rollup_node/daemon.ml index 29b342c8e3..e5600cfe81 100644 --- a/src/proto_alpha/bin_tx_rollup_node/daemon.ml +++ b/src/proto_alpha/bin_tx_rollup_node/daemon.ml @@ -85,14 +85,17 @@ let parse_tx_rollup_l2_address : | Int (loc, _) | Prim (loc, _, _, _) | Seq (loc, _) -> error (Error.Tx_rollup_invalid_l2_address loc) -(* TODO/TORU: expose uncarbonated parse_tx_rollup_deposit_parameters in protocol *) -let parse_tx_rollup_deposit_parameters : - Script.expr -> Tx_rollup.deposit_parameters tzresult = +let parse_tx_rollup_amount_l2_destination_parameters : + Script.expr -> + (Protocol.Tx_rollup_l2_qty.t + * Protocol.Script_typed_ir.tx_rollup_l2_address) + tzresult = fun parameters -> let open Micheline in let open Protocol in - (* /!\ This pattern matching needs to remain in sync with the - Script_ir_translator.parse_tx_rollup_deposit_parameters. *) + (* /!\ This pattern matching needs to remain in sync with the deposit + parameters. See the transaction to Tx_rollup case in + Protocol.Apply.Apply.apply_internal_manager_operations *) match root parameters with | Seq ( _, @@ -104,12 +107,12 @@ let parse_tx_rollup_deposit_parameters : Prim ( _, D_Pair, - [ticketer; Prim (_, D_Pair, [contents; amount], _)], + [_ticketer; Prim (_, D_Pair, [_contents; amount], _)], _ ); bls; ], _ ); - ty; + _ty; ] ) -> parse_tx_rollup_l2_address bls >>? fun destination -> (match amount with @@ -119,7 +122,7 @@ let parse_tx_rollup_deposit_parameters : | Int (_, invalid_amount) -> error (Error.Tx_rollup_invalid_ticket_amount invalid_amount) | _expr -> error Error.Tx_rollup_invalid_deposit) - >|? fun amount -> Tx_rollup.{ticketer; contents; ty; amount; destination} + >|? fun amount -> (amount, destination) | _expr -> error Error.Tx_rollup_invalid_deposit let extract_messages_from_block block_info rollup_id = @@ -154,9 +157,9 @@ let extract_messages_from_block block_info rollup_id = (* Deposit message *) Option.bind (Data_encoding.force_decode parameters) @@ fun parameters -> - parse_tx_rollup_deposit_parameters parameters + parse_tx_rollup_amount_l2_destination_parameters parameters |> Result.to_option - |> Option.map @@ fun Tx_rollup.{amount; destination; _} -> + |> Option.map @@ fun (amount, destination) -> Tx_rollup_message.make_deposit source destination diff --git a/src/proto_alpha/lib_client/operation_result.ml b/src/proto_alpha/lib_client/operation_result.ml index da1f96a610..61d8654bbe 100644 --- a/src/proto_alpha/lib_client/operation_result.ml +++ b/src/proto_alpha/lib_client/operation_result.ml @@ -585,8 +585,16 @@ let pp_manager_operation_contents_and_result ppf balance_updates ; Format.fprintf ppf "@,Consumed gas: %a" Gas.Arith.pp consumed_gas in - let pp_tx_rollup_withdraw_result (Tx_rollup_withdraw_result {consumed_gas}) = - Format.fprintf ppf "@,Consumed gas: %a" Gas.Arith.pp consumed_gas + let pp_tx_rollup_withdraw_result + (Tx_rollup_withdraw_result + {balance_updates; consumed_gas; paid_storage_size_diff}) = + if paid_storage_size_diff <> Z.zero then + Format.fprintf + ppf + "@,Paid storage size diff: %s bytes" + (Z.to_string paid_storage_size_diff) ; + Format.fprintf ppf "@,Consumed gas: %a" Gas.Arith.pp consumed_gas ; + pp_balance_updates_opt ppf balance_updates in let pp_sc_rollup_originate_result (Sc_rollup_originate_result diff --git a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL index 21c4ccf2ff..fdcd046209 100644 --- a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL +++ b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL @@ -161,6 +161,8 @@ "Ticket_lazy_storage_diff", "Ticket_balance_migration_for_j", + "Tx_rollup_parameters", + "Ticket_token_map", "Ticket_operations_diff", "Ticket_accounting", diff --git a/src/proto_alpha/lib_protocol/alpha_context.ml b/src/proto_alpha/lib_protocol/alpha_context.ml index 165d5d20bf..cad9021444 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.ml +++ b/src/proto_alpha/lib_protocol/alpha_context.ml @@ -245,24 +245,7 @@ module Tx_rollup_message_result_hash = module Tx_rollup = struct include Tx_rollup_repr include Tx_rollup_storage - - let hash_ticket ctxt tx_rollup ~contents ~ticketer ~ty = - let open Micheline in - let owner = String (dummy_location, to_b58check tx_rollup) in - Ticket_hash_builder.make ctxt ~ticketer ~ty ~contents ~owner - - module Internal_for_tests = struct - include Tx_rollup_repr - - let hash_ticket_uncarbonated tx_rollup ~contents ~ticketer ~ty = - let open Micheline in - let owner = String (dummy_location, to_b58check tx_rollup) in - Ticket_hash_builder.Internal_for_tests.make_uncarbonated - ~ticketer - ~ty - ~contents - ~owner - end + module Internal_for_tests = Tx_rollup_repr end module Tx_rollup_state = struct diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index bc7d9cffe9..96cf61a346 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -1530,31 +1530,6 @@ module Tx_rollup : sig val deposit_entrypoint : Entrypoint.t - type deposit_parameters = { - contents : Script.node; - ty : Script.node; - ticketer : Script.node; - amount : Tx_rollup_l2_qty.t; - destination : Tx_rollup_l2_address.Indexable.value; - } - - (** [hash_ticket ctxt tx_rollup ~contents ~ticketer ~ty] computes the - hash of the ticket of type [ty ticket], of content [contents] and - of ticketer [ticketer]. - - The goal of the computed hash is twofold: - - {ul {li Identifying the ticket in the layer-2, and} - {li Registering in the table of tickets that [tx_rollup] - owns this ticket.}} *) - val hash_ticket : - context -> - t -> - contents:Script.node -> - ticketer:Script.node -> - ty:Script.node -> - (Ticket_hash.t * context) tzresult - val originate : context -> (context * tx_rollup) tzresult Lwt.t module Set : Set.S with type elt = tx_rollup @@ -1563,14 +1538,6 @@ module Tx_rollup : sig (** see [tx_rollup_repr.originated_tx_rollup] for documentation *) val originated_tx_rollup : Origination_nonce.Internal_for_tests.t -> tx_rollup - - (** same as [hash_ticket] but uncarbonated *) - val hash_ticket_uncarbonated : - t -> - contents:Script.node -> - ticketer:Script.node -> - ty:Script.node -> - Ticket_hash.t tzresult end end @@ -1959,6 +1926,8 @@ module Tx_rollup_errors : sig computed : Tx_rollup_message_result_hash.t; expected : Tx_rollup_message_result_hash.t; } + | Deposit_wrong_ticketer of Tx_rollup.t + | Wrong_deposit_parameters end module Bond_id : sig diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index ab2b6ae961..5cd883a31a 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -1049,39 +1049,33 @@ let apply_transaction ~ctxt ~parameter ~source ~contract ~amount ~entrypoint ~balance_updates ~allocated_destination_contract -let apply_transaction_to_rollup ~consume_deserialization_gas ~ctxt ~parameters - ~amount ~entrypoint ~payer ~dst_rollup ~since = +let ex_ticket_size : + Alpha_context.t -> + Ticket_scanner.ex_ticket -> + (Alpha_context.t * int) tzresult Lwt.t = + fun ctxt (Ex_ticket (ty, ticket)) -> + (* type *) + Script_typed_ir.ticket_t Micheline.dummy_location ty >>?= fun ty -> + Script_ir_translator.unparse_ty ~loc:Micheline.dummy_location ctxt ty + >>?= fun (ty', ctxt) -> + let (ty_nodes, ty_size) = Script_typed_ir_size.node_size ty' in + let ty_size = Saturation_repr.to_int ty_size in + let ty_size_cost = Script_typed_ir_size_costs.nodes_cost ~nodes:ty_nodes in + Gas.consume ctxt ty_size_cost >>?= fun ctxt -> + (* contents *) + let (val_nodes, val_size) = Script_typed_ir_size.value_size ty ticket in + let val_size = Saturation_repr.to_int val_size in + let val_size_cost = Script_typed_ir_size_costs.nodes_cost ~nodes:val_nodes in + Gas.consume ctxt val_size_cost >>?= fun ctxt -> + (* gas *) + return (ctxt, ty_size + val_size) + +let apply_transaction_to_tx_rollup ~ctxt ~parameters_ty ~parameters ~amount + ~entrypoint ~payer ~dst_rollup ~since = assert_tx_rollup_feature_enabled ctxt >>=? fun () -> fail_unless Tez.(amount = zero) Tx_rollup_invalid_transaction_amount >>=? fun () -> if Entrypoint.(entrypoint = Tx_rollup.deposit_entrypoint) then - Script.force_decode_in_context ~consume_deserialization_gas ctxt parameters - >>?= fun (parameters, ctxt) -> - Script_ir_translator.parse_tx_rollup_deposit_parameters ctxt parameters - >>?= fun (Tx_rollup.{ticketer; contents; ty; amount; destination}, ctxt) -> - let (ty_nodes, ty_size) = Script_typed_ir_size.node_size ty in - let (content_nodes, content_size) = - Script_typed_ir_size.node_size contents - in - let content_size = Saturation_repr.to_int content_size in - let ty_size = Saturation_repr.to_int ty_size in - let limit = - Alpha_context.Constants.tx_rollup_max_ticket_payload_size ctxt - in - let content_size_cost = - Script_typed_ir_size_costs.nodes_cost ~nodes:content_nodes - in - let ty_size_cost = Script_typed_ir_size_costs.nodes_cost ~nodes:ty_nodes in - Gas.consume ctxt content_size_cost >>?= fun ctxt -> - Gas.consume ctxt ty_size_cost >>?= fun ctxt -> - let payload_size = ty_size + content_size in - fail_when - Compare.Int.(payload_size > limit) - (Tx_rollup_errors_repr.Ticket_payload_size_limit_exceeded - {payload_size; limit}) - >>=? fun () -> - Tx_rollup.hash_ticket ctxt dst_rollup ~contents ~ticketer ~ty - >>?= fun (ticket_hash, ctxt) -> (* If the ticket deposit fails on L2 for some reason (e.g. [Balance_overflow] in the recipient), then it is returned to [payer]. As [payer] is implicit, it cannot own @@ -1089,8 +1083,34 @@ let apply_transaction_to_rollup ~consume_deserialization_gas ~ctxt ~parameters returned using the L2 withdrawal mechanism: a failing deposit emits a withdrawal that can be executed by [payer]. *) + Tx_rollup_parameters.get_deposit_parameters parameters_ty parameters + >>?= fun {ex_ticket; l2_destination} -> + ex_ticket_size ctxt ex_ticket >>=? fun (ctxt, ticket_size) -> + let limit = + Alpha_context.Constants.tx_rollup_max_ticket_payload_size ctxt + in + fail_when + Compare.Int.(ticket_size > limit) + (Tx_rollup_errors_repr.Ticket_payload_size_limit_exceeded + {payload_size = ticket_size; limit}) + >>=? fun () -> + let (ex_token, ticket_amount) = + Ticket_token.token_and_amount_of_ex_ticket ex_ticket + in + Ticket_balance_key.of_ex_token ctxt ~owner:(Tx_rollup dst_rollup) ex_token + >>=? fun (ticket_hash, ctxt) -> + Option.value_e + ~error:(Error_monad.trace_of_error Tx_rollup_invalid_transaction_amount) + (Option.bind + (Script_int.to_int64 ticket_amount) + Tx_rollup_l2_qty.of_int64) + >>?= fun ticket_amount -> let (deposit, message_size) = - Tx_rollup_message.make_deposit payer destination ticket_hash amount + Tx_rollup_message.make_deposit + payer + l2_destination + ticket_hash + ticket_amount in Tx_rollup_state.get ctxt dst_rollup >>=? fun (ctxt, state) -> Tx_rollup_state.burn_cost ~limit:None state message_size >>?= fun cost -> @@ -1301,14 +1321,14 @@ let apply_internal_manager_operation_content : | Transaction { transaction = - {amount; parameters; destination = Tx_rollup dst; entrypoint}; + {amount; destination = Tx_rollup dst; entrypoint; parameters = _}; location = _; - parameters_ty = _; - parameters = _; + parameters_ty; + parameters; } -> - apply_transaction_to_rollup - ~consume_deserialization_gas + apply_transaction_to_tx_rollup ~ctxt + ~parameters_ty ~parameters ~amount ~entrypoint @@ -1385,18 +1405,9 @@ let apply_external_manager_operation_content : ~chain_id ~mode ~internal - | Transaction {amount; parameters; destination = Tx_rollup dst; entrypoint} -> - apply_transaction_to_rollup - ~consume_deserialization_gas - ~ctxt - ~parameters - ~amount - ~entrypoint - ~payer - ~dst_rollup:dst - ~since:before_operation + | Transaction {destination = Tx_rollup _; _} -> + fail Tx_rollup_non_internal_transaction | Tx_rollup_withdraw - (* FIXME/TORU: #2488 The ticket accounting for the withdraw is not done here *) { tx_rollup; level; @@ -1415,19 +1426,21 @@ let apply_external_manager_operation_content : >>?= fun (ty, ctxt) -> Script.force_decode_in_context ~consume_deserialization_gas ctxt contents >>?= fun (contents, ctxt) -> - Script_ir_translator.unparse_data + Script_ir_translator.parse_comparable_ty ctxt (Micheline.root ty) + >>?= fun (Ex_comparable_ty contents_type, ctxt) -> + Script_ir_translator.parse_comparable_data ctxt - Optimized - Script_typed_ir.address_t - {destination = Contract ticketer; entrypoint = Entrypoint.default} - >>=? fun (ticketer_node, ctxt) -> - Tx_rollup.hash_ticket + contents_type + (Micheline.root contents) + >>=? fun (contents, ctxt) -> + let ticket_token = + Ticket_token.Ex_token {ticketer; contents_type; contents} + in + Ticket_balance_key.of_ex_token ctxt - tx_rollup - ~contents:(Micheline.root contents) - ~ticketer:(Micheline.root @@ Micheline.strip_locations ticketer_node) - ~ty:(Micheline.root ty) - >>?= fun (ticket_hash, ctxt) -> + ~owner:(Tx_rollup tx_rollup) + ticket_token + >>=? fun (tx_rollup_ticket_hash, ctxt) -> (* Checking the operation is non-internal *) Option.value_e ~error: @@ -1437,8 +1450,14 @@ let apply_external_manager_operation_content : >>?= fun source_pkh -> (* Computing the withdrawal hash *) let withdrawal = - Tx_rollup_withdraw.{claimer = source_pkh; ticket_hash; amount} + Tx_rollup_withdraw. + {claimer = source_pkh; ticket_hash = tx_rollup_ticket_hash; amount} in + (* TODO/TORU: #2340 + + We should perform gas accounting when checking the path, but + we'll rehaul this part when merkelizing withdrawal list. + *) let (withdrawals_merkle_root, withdraw_index) = Tx_rollup_withdraw.check_path withdraw_path withdrawal in @@ -1457,38 +1476,28 @@ let apply_external_manager_operation_content : >>=? fun () -> Tx_rollup_withdraw.add ctxt tx_rollup level ~message_index ~withdraw_index >>=? fun ctxt -> - (* FIXME/TORU: #2488 The ticket accounting for the withdraw should be done here. - Before calling the next function we needs to make sure that - this ticket is owns by the tx_rollup *) (* Now reconstruct the ticket sent as the parameter destination. *) - Script_ir_translator.parse_comparable_ty ctxt (Micheline.root ty) - >>?= fun (Ex_comparable_ty ty, ctxt) -> - Script_ir_translator.parse_comparable_data - ctxt - ty - (Micheline.root contents) - >>=? fun (contents, ctxt) -> - let amount = - Option.value - ~default:Script_int.zero_n - Script_int.(is_nat @@ of_int64 @@ Tx_rollup_l2_qty.to_int64 amount) - in - let ticket = Script_typed_ir.{ticketer; contents; amount} in - Script_typed_ir.ticket_t Micheline.dummy_location ty >>?= fun ty -> - return (ticket, ty, ctxt) >>=? fun (ticket, ticket_ty, ctxt) -> + Option.value_e + ~error: + (Error_monad.trace_of_error + @@ Tx_rollup_errors.Internal_error + "withdraw amount is negative, this can't happens because it \ + comes from a qty.") + Script_int.(is_nat @@ of_int64 @@ Tx_rollup_l2_qty.to_int64 amount) + >>?= fun amount_node -> + Script_typed_ir.ticket_t Micheline.dummy_location contents_type + >>?= fun ticket_ty -> + let ticket = Script_typed_ir.{ticketer; contents; amount = amount_node} in Script_ir_translator.unparse_data ctxt Optimized ticket_ty ticket - >>=? fun (parameters, ctxt) -> + >>=? fun (parameters_expr, ctxt) -> let parameters = - Script.lazy_expr (Micheline.strip_locations parameters) + Script.lazy_expr (Micheline.strip_locations parameters_expr) in - (* FIXME/TORU: #2488 the returned op will fail when ticket hardening is - merged, it must be commented or fixed *) let op = Script_typed_ir.Internal_operation { source; - (* TODO is 0 correct ? *) nonce = 0; operation = Transaction @@ -1500,15 +1509,45 @@ let apply_external_manager_operation_content : destination = Contract destination; entrypoint; }; - location = Micheline.location ticketer_node; + location = Micheline.location parameters_expr; parameters_ty = ticket_ty; parameters = ticket; }; } in + (* remove tickets from the tx_rollup and add them to the destination + contract *) + Ticket_balance_key.of_ex_token + ctxt + ~owner:(Contract destination) + ticket_token + >>=? fun (destination_ticket_hash, ctxt) -> + Ticket_balance.adjust_balance + ctxt + tx_rollup_ticket_hash + ~delta:(Z.neg @@ Tx_rollup_l2_qty.to_z amount) + >>=? fun (_tx_ticket_hash_storage_diff, ctxt) -> + Ticket_balance.adjust_balance + ctxt + destination_ticket_hash + ~delta:(Tx_rollup_l2_qty.to_z amount) + >>=? fun (_dest_ticket_hash_storage_diff, ctxt) -> let result = Tx_rollup_withdraw_result - {consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt} + { + balance_updates = []; + consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt; + paid_storage_size_diff = + (* TODO/TORU: #2339 + + We set [paid_storage_size_diff] to zero for now, it should be something like + + Z.add _tx_ticket_hash_storage_diff _dest_ticket_hash_storage_diff + + with the fix of #2339. + *) + Z.zero; + } in return (ctxt, result, [op]) | Origination {delegate; script; preorigination; credit} -> @@ -1966,7 +2005,7 @@ let precheck_manager_contents (type kind) ctxt (op : kind Kind.manager contents) (ctxt, {balance_updates; consumed_gas}) (** [burn_storage_fees ctxt smopr storage_limit payer] burns the storage fees - associated to the transaction or origination result [smopr]. + associated to an operation result [smopr]. Returns an updated context, an updated storage limit with the space consumed by the operation subtracted, and [smopr] with the relevant balance updates included. *) @@ -2063,9 +2102,17 @@ let burn_storage_fees : Michelson’s big map). *) | Tx_rollup_submit_batch_result _ | Tx_rollup_commit_result _ | Tx_rollup_return_bond_result _ | Tx_rollup_finalize_commitment_result _ - | Tx_rollup_remove_commitment_result _ | Tx_rollup_rejection_result _ - | Tx_rollup_withdraw_result _ -> + | Tx_rollup_remove_commitment_result _ | Tx_rollup_rejection_result _ -> return (ctxt, storage_limit, smopr) + | Tx_rollup_withdraw_result payload -> + let consumed = payload.paid_storage_size_diff in + Fees.burn_storage_fees ctxt ~storage_limit ~payer consumed + >>=? fun (ctxt, storage_limit, storage_bus) -> + let balance_updates = payload.balance_updates @ storage_bus in + return + ( ctxt, + storage_limit, + Tx_rollup_withdraw_result {payload with balance_updates} ) | Sc_rollup_originate_result payload -> Fees.burn_sc_rollup_origination_fees ctxt diff --git a/src/proto_alpha/lib_protocol/apply_results.ml b/src/proto_alpha/lib_protocol/apply_results.ml index 68b4aafcda..92c1f4a586 100644 --- a/src/proto_alpha/lib_protocol/apply_results.ml +++ b/src/proto_alpha/lib_protocol/apply_results.ml @@ -181,7 +181,9 @@ type _ successful_manager_operation_result = } -> Kind.tx_rollup_rejection successful_manager_operation_result | Tx_rollup_withdraw_result : { + balance_updates : Receipt.balance_updates; consumed_gas : Gas.Arith.fp; + paid_storage_size_diff : Z.t; } -> Kind.tx_rollup_withdraw successful_manager_operation_result | Sc_rollup_originate_result : { @@ -740,20 +742,35 @@ module Manager_result = struct ~op_case:Operation.Encoding.Manager_operations.tx_rollup_withdraw_case ~encoding: Data_encoding.( - obj2 + obj4 + (req "balance_updates" Receipt.balance_updates_encoding) (dft "consumed_gas" Gas.Arith.n_integral_encoding Gas.Arith.zero) - (dft "consumed_milligas" Gas.Arith.n_fp_encoding Gas.Arith.zero)) - ~kind:Kind.Tx_rollup_withdraw_manager_kind + (dft "consumed_milligas" Gas.Arith.n_fp_encoding Gas.Arith.zero) + (dft "paid_storage_size_diff" z Z.zero)) ~select:(function | Successful_manager_result (Tx_rollup_withdraw_result _ as op) -> Some op | _ -> None) + ~kind:Kind.Tx_rollup_withdraw_manager_kind ~proj:(function - | Tx_rollup_withdraw_result {consumed_gas} -> - (Gas.Arith.ceil consumed_gas, consumed_gas)) - ~inj:(fun (consumed_gas, consumed_milligas) -> + | Tx_rollup_withdraw_result + {balance_updates; consumed_gas; paid_storage_size_diff} -> + ( balance_updates, + Gas.Arith.ceil consumed_gas, + consumed_gas, + paid_storage_size_diff )) + ~inj: + (fun ( balance_updates, + consumed_gas, + consumed_milligas, + paid_storage_size_diff ) -> assert (Gas.Arith.(equal (ceil consumed_milligas) consumed_gas)) ; - Tx_rollup_withdraw_result {consumed_gas = consumed_milligas}) + Tx_rollup_withdraw_result + { + balance_updates; + consumed_gas = consumed_milligas; + paid_storage_size_diff; + }) let[@coq_axiom_with_reason "gadt"] sc_rollup_originate_case = make diff --git a/src/proto_alpha/lib_protocol/apply_results.mli b/src/proto_alpha/lib_protocol/apply_results.mli index 4b5b1da096..bd1dff6b3b 100644 --- a/src/proto_alpha/lib_protocol/apply_results.mli +++ b/src/proto_alpha/lib_protocol/apply_results.mli @@ -241,7 +241,9 @@ and _ successful_manager_operation_result = } -> Kind.tx_rollup_rejection successful_manager_operation_result | Tx_rollup_withdraw_result : { + balance_updates : Receipt.balance_updates; consumed_gas : Gas.Arith.fp; + paid_storage_size_diff : Z.t; } -> Kind.tx_rollup_withdraw successful_manager_operation_result | Sc_rollup_originate_result : { diff --git a/src/proto_alpha/lib_protocol/dune.inc b/src/proto_alpha/lib_protocol/dune.inc index 9460ba726d..dd9bba3416 100644 --- a/src/proto_alpha/lib_protocol/dune.inc +++ b/src/proto_alpha/lib_protocol/dune.inc @@ -176,6 +176,7 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end ticket_balance_key.mli ticket_balance_key.ml ticket_lazy_storage_diff.mli ticket_lazy_storage_diff.ml ticket_balance_migration_for_j.mli ticket_balance_migration_for_j.ml + tx_rollup_parameters.mli tx_rollup_parameters.ml ticket_token_map.mli ticket_token_map.ml ticket_operations_diff.mli ticket_operations_diff.ml ticket_accounting.mli ticket_accounting.ml @@ -353,6 +354,7 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end ticket_balance_key.mli ticket_balance_key.ml ticket_lazy_storage_diff.mli ticket_lazy_storage_diff.ml ticket_balance_migration_for_j.mli ticket_balance_migration_for_j.ml + tx_rollup_parameters.mli tx_rollup_parameters.ml ticket_token_map.mli ticket_token_map.ml ticket_operations_diff.mli ticket_operations_diff.ml ticket_accounting.mli ticket_accounting.ml @@ -530,6 +532,7 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end ticket_balance_key.mli ticket_balance_key.ml ticket_lazy_storage_diff.mli ticket_lazy_storage_diff.ml ticket_balance_migration_for_j.mli ticket_balance_migration_for_j.ml + tx_rollup_parameters.mli tx_rollup_parameters.ml ticket_token_map.mli ticket_token_map.ml ticket_operations_diff.mli ticket_operations_diff.ml ticket_accounting.mli ticket_accounting.ml @@ -729,6 +732,7 @@ include Tezos_raw_protocol_alpha.Main Ticket_balance_key Ticket_lazy_storage_diff Ticket_balance_migration_for_j + Tx_rollup_parameters Ticket_token_map Ticket_operations_diff Ticket_accounting @@ -947,6 +951,7 @@ include Tezos_raw_protocol_alpha.Main ticket_balance_key.mli ticket_balance_key.ml ticket_lazy_storage_diff.mli ticket_lazy_storage_diff.ml ticket_balance_migration_for_j.mli ticket_balance_migration_for_j.ml + tx_rollup_parameters.mli tx_rollup_parameters.ml ticket_token_map.mli ticket_token_map.ml ticket_operations_diff.mli ticket_operations_diff.ml ticket_accounting.mli ticket_accounting.ml diff --git a/src/proto_alpha/lib_protocol/script_ir_translator.ml b/src/proto_alpha/lib_protocol/script_ir_translator.ml index ee490f8b4a..5e1d452a1b 100644 --- a/src/proto_alpha/lib_protocol/script_ir_translator.ml +++ b/src/proto_alpha/lib_protocol/script_ir_translator.ml @@ -2336,44 +2336,6 @@ let parse_tx_rollup_l2_address ctxt : | expr -> error @@ Invalid_kind (location expr, [String_kind; Bytes_kind], kind expr) -(* TODO: https://gitlab.com/tezos/tezos/-/issues/2035 - Investigate if separating internal operations from manager - operations could make this shenanigan useless. *) -let parse_tx_rollup_deposit_parameters : - context -> Script.expr -> (Tx_rollup.deposit_parameters * context) tzresult - = - fun ctxt parameters -> - (* /!\ This pattern matching needs to remain in sync with the - [Tx_rollup] case of [parse_contract] and [parse_contract_for_script]. *) - match root parameters with - | Seq - ( _, - [ - Prim - ( _, - D_Pair, - [ - Prim - ( _, - D_Pair, - [ticketer; Prim (_, D_Pair, [contents; amount], _)], - _ ); - bls; - ], - _ ); - ty; - ] ) -> - parse_tx_rollup_l2_address ctxt bls >>? fun (destination, ctxt) -> - (match amount with - | Int (_, v) when Compare.Z.(Z.zero < v && v <= Z.of_int64 Int64.max_int) - -> - ok @@ Tx_rollup_l2_qty.of_int64_exn (Z.to_int64 v) - | Int (_, v) -> error @@ Tx_rollup_invalid_ticket_amount v - | expr -> error @@ Invalid_kind (location expr, [Int_kind], kind expr)) - >|? fun amount -> - (Tx_rollup.{ticketer; contents; ty; amount; destination}, ctxt) - | expr -> error @@ Invalid_kind (location expr, [Seq_kind], kind expr) - let parse_never expr : (never * context) tzresult = error @@ Invalid_never_expr (location expr) diff --git a/src/proto_alpha/lib_protocol/script_ir_translator.mli b/src/proto_alpha/lib_protocol/script_ir_translator.mli index 3b2285ef5a..975e66406b 100644 --- a/src/proto_alpha/lib_protocol/script_ir_translator.mli +++ b/src/proto_alpha/lib_protocol/script_ir_translator.mli @@ -428,12 +428,6 @@ val parse_contract_for_script : entrypoint:Entrypoint.t -> (context * 'a Script_typed_ir.typed_contract option) tzresult Lwt.t -(** [parse_tx_rollup_deposit_parameters ctxt expr] extracts from - [expr] the parameters of the [deposit] entrypoint of transaction - rollups. *) -val parse_tx_rollup_deposit_parameters : - context -> Script.expr -> (Tx_rollup.deposit_parameters * context) tzresult - (** ['a ex_ty_cstr] is like [ex_ty], but also adds to the existential a function used to reconstruct a value of type ['a] from the internal type of the existential. Typically, it will be used to go from the type of an diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_accounting.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_accounting.ml index 9a70b37d20..507558a491 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_accounting.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_accounting.ml @@ -930,7 +930,11 @@ let test_update_ticket_self_diff () = in (* After update, we should have 10 added red tokens. *) let* (red_self_token_hash, ctxt) = - wrap @@ Ticket_balance_key.ticket_balance_key ctxt ~owner:self red_token + wrap + @@ Ticket_balance_key.of_ex_token + ctxt + ~owner:(Destination.Contract self) + red_token in assert_balance ~loc:__LOC__ ctxt red_self_token_hash (Some 10) @@ -984,9 +988,9 @@ let test_update_self_ticket_transfer () = let* () = let* (red_receiver_token_hash, ctxt) = wrap - @@ Ticket_balance_key.ticket_balance_key + @@ Ticket_balance_key.of_ex_token ctxt - ~owner:ticket_receiver + ~owner:(Destination.Contract ticket_receiver) red_token in assert_balance ~loc:__LOC__ ctxt red_receiver_token_hash (Some 10) @@ -1011,11 +1015,18 @@ let test_update_valid_transfer () = let ctxt = Incremental.alpha_ctxt incr in let* red_token = string_ticket_token ticketer "red" in let* (red_self_token_hash, ctxt) = - wrap @@ Ticket_balance_key.ticket_balance_key ctxt ~owner:self red_token + wrap + @@ Ticket_balance_key.of_ex_token + ctxt + ~owner:(Destination.Contract self) + red_token in let* (red_receiver_token_hash, ctxt) = wrap - @@ Ticket_balance_key.ticket_balance_key ctxt ~owner:destination red_token + @@ Ticket_balance_key.of_ex_token + ctxt + ~owner:(Destination.Contract destination) + red_token in (* Set up the balance so that the self contract owns one ticket. *) let* (_, ctxt) = @@ -1066,7 +1077,11 @@ let test_update_transfer_tickets_to_self () = let ctxt = Incremental.alpha_ctxt incr in let* red_token = string_ticket_token ticketer "red" in let* (red_self_token_hash, ctxt) = - wrap @@ Ticket_balance_key.ticket_balance_key ctxt ~owner:self red_token + wrap + @@ Ticket_balance_key.of_ex_token + ctxt + ~owner:(Destination.Contract self) + red_token in (* Set up the balance so that the self contract owns ten tickets. *) let* (_, ctxt) = @@ -1159,7 +1174,11 @@ let test_update_valid_origination () = let ctxt = Incremental.alpha_ctxt incr in let* red_token = string_ticket_token ticketer "red" in let* (red_self_token_hash, ctxt) = - wrap @@ Ticket_balance_key.ticket_balance_key ctxt ~owner:self red_token + wrap + @@ Ticket_balance_key.of_ex_token + ctxt + ~owner:(Destination.Contract self) + red_token in (* Set up the balance so that the self contract owns one ticket. *) let* (_, ctxt) = @@ -1187,7 +1206,10 @@ let test_update_valid_origination () = from [self] to [destination]. *) let* (red_originated_token_hash, ctxt) = wrap - @@ Ticket_balance_key.ticket_balance_key ctxt ~owner:originated red_token + @@ Ticket_balance_key.of_ex_token + ctxt + ~owner:(Destination.Contract originated) + red_token in assert_balance ~loc:__LOC__ ctxt red_originated_token_hash (Some 1) @@ -1209,7 +1231,10 @@ let test_update_self_origination () = let* red_token = string_ticket_token ticketer "red" in let* (red_originated_token_hash, ctxt) = wrap - @@ Ticket_balance_key.ticket_balance_key ctxt ~owner:originated red_token + @@ Ticket_balance_key.of_ex_token + ctxt + ~owner:(Destination.Contract originated) + red_token in let operation = origination_operation ~src:self ~orig_contract:originated ~script @@ -1254,7 +1279,11 @@ let test_ticket_token_map_of_list_with_duplicates () = in (* After update, we should have 10 + 5 added red tokens. *) let* (red_self_token_hash, ctxt) = - wrap @@ Ticket_balance_key.ticket_balance_key ctxt ~owner:self red_token + wrap + @@ Ticket_balance_key.of_ex_token + ctxt + ~owner:(Destination.Contract self) + red_token in assert_balance ~loc:__LOC__ ctxt red_self_token_hash (Some 15) diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_balance.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_balance.ml index 92677278b3..31a9cc3f96 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_balance.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_balance.ml @@ -70,14 +70,16 @@ let originate = Contract_helpers.originate_contract_from_string let get_balance ctxt ~token ~owner = let* (key_hash, ctxt) = - wrap @@ Ticket_balance_key.ticket_balance_key ctxt ~owner token + wrap @@ Ticket_balance_key.of_ex_token ctxt ~owner token in wrap (Ticket_balance.get_balance ctxt key_hash) let assert_token_balance ~loc block token owner expected = let* incr = Incremental.begin_construction block in let ctxt = Incremental.alpha_ctxt incr in - let* (balance, _) = get_balance ctxt ~token ~owner in + let* (balance, _) = + get_balance ctxt ~token ~owner:(Destination.Contract owner) + in match (balance, expected) with | (Some b, Some e) -> Assert.equal_int ~loc (Z.to_int b) e | (Some b, None) -> diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_balance_key.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_balance_key.ml index 297d76db86..d0a972d392 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_balance_key.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_balance_key.ml @@ -62,7 +62,11 @@ let make_key ctxt ~ticketer ~ty ~content ~owner = let* (ex_token, ctxt) = make_ex_token ctxt ~ticketer ~ty ~content in let* owner = make_contract owner in let* (key, ctxt) = - wrap @@ Ticket_balance_key.ticket_balance_key ctxt ~owner ex_token + wrap + @@ Ticket_balance_key.of_ex_token + ctxt + ~owner:(Destination.Contract owner) + ex_token in return (key, ctxt) diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_manager.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_manager.ml index a2e8b496c8..5a79954135 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_manager.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_manager.ml @@ -100,9 +100,9 @@ let ticket_balance_of_storage ctxt contract = @@ List.fold_left_es (fun (acc, ctxt) (ex_token, amount) -> let* (key, ctxt) = - Ticket_balance_key.ticket_balance_key + Ticket_balance_key.of_ex_token ctxt - ~owner:contract + ~owner:(Contract contract) ex_token in let acc = (key, amount) :: acc in diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_operations_diff.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_operations_diff.ml index 04e7b5ca8f..36db4c333d 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_operations_diff.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_operations_diff.ml @@ -41,7 +41,7 @@ open Script_typed_ir type ticket_token_diff = { ticket_token : Ticket_token.ex_token; total_amount : Script_int.n Script_int.num; - destinations : (Contract.t * Script_int.n Script_int.num) list; + destinations : (Destination.t * Script_int.n Script_int.num) list; } let to_local_ticket_token_diff @@ -116,7 +116,7 @@ let string_of_ticket_token ctxt Michelson_v1_printer.print_expr (Micheline.strip_locations x) -let string_of_contract_and_amounts cas = +let string_of_destination_and_amounts cas = Format.asprintf "[%a]" (Format.pp_print_list @@ -125,7 +125,7 @@ let string_of_contract_and_amounts cas = Format.fprintf fmt {|("%a", %s)|} - Contract.pp + Destination.pp contract (Script_int.to_string amount))) cas @@ -133,7 +133,7 @@ let string_of_contract_and_amounts cas = let string_of_ticket_operations_diff ctxt {ticket_token; total_amount; destinations} = let* ticket_token = string_of_ticket_token ctxt ticket_token in - let destinations = string_of_contract_and_amounts destinations in + let destinations = string_of_destination_and_amounts destinations in return (Printf.sprintf "(%s, %s, %s)" @@ -153,7 +153,7 @@ let assert_equal_ticket_token_diffs ctxt ~loc ticket_diffs total_amount; destinations = List.sort - (fun (c1, _) (c2, _) -> Contract.compare c1 c2) + (fun (c1, _) (c2, _) -> Destination.compare c1 c2) destinations; }) ticket_diffs @@ -179,8 +179,9 @@ let string_token ~ticketer content = {ticketer; contents_type = Script_typed_ir.string_key; contents} (** Initializes one address for operations and one baker. *) -let init () = - Context.init ~consensus_threshold:0 2 >|=? fun (block, contracts) -> +let init ?tx_rollup_enable () = + Context.init ?tx_rollup_enable ~consensus_threshold:0 2 + >|=? fun (block, contracts) -> let (src0, src1) = match contracts with src0 :: src1 :: _ -> (src0, src1) | _ -> assert false in @@ -295,6 +296,42 @@ let transfer_operation ~incr ~src ~destination ~parameters_ty ~parameters = }, incr ) +let transfer_operation_to_tx_rollup ~incr ~src ~parameters_ty ~parameters + ~tx_rollup = + let open Lwt_tzresult_syntax in + let ctxt = Incremental.alpha_ctxt incr in + let* (params_node, ctxt) = + wrap + (Script_ir_translator.unparse_data + ctxt + Script_ir_translator.Optimized_legacy + parameters_ty + parameters) + in + let incr = Incremental.set_alpha_ctxt incr ctxt in + return + ( Script_typed_ir.Internal_operation + { + source = src; + operation = + Transaction + { + transaction = + { + amount = Tez.zero; + parameters = + Script.lazy_expr @@ Micheline.strip_locations params_node; + entrypoint = Tx_rollup.deposit_entrypoint; + destination = Destination.Tx_rollup tx_rollup; + }; + location = Micheline.dummy_location; + parameters_ty; + parameters; + }; + nonce = 1; + }, + incr ) + let ticket_diffs_of_operations incr operations = wrap @@ Ticket_operations_diff.ticket_diffs_of_operations @@ -420,7 +457,7 @@ let test_transfer_one_ticket () = { ticket_token = string_token ~ticketer "white"; total_amount = nat 1; - destinations = [(orig_contract, nat 1)]; + destinations = [(Destination.Contract orig_contract, nat 1)]; }; ] @@ -459,17 +496,17 @@ let test_transfer_multiple_tickets () = { ticket_token = string_token ~ticketer "red"; total_amount = nat 5; - destinations = [(orig_contract, nat 5)]; + destinations = [(Destination.Contract orig_contract, nat 5)]; }; { ticket_token = string_token ~ticketer "blue"; total_amount = nat 2; - destinations = [(orig_contract, nat 2)]; + destinations = [(Destination.Contract orig_contract, nat 2)]; }; { ticket_token = string_token ~ticketer "green"; total_amount = nat 3; - destinations = [(orig_contract, nat 3)]; + destinations = [(Destination.Contract orig_contract, nat 3)]; }; ] @@ -513,32 +550,32 @@ let test_transfer_different_tickets () = { ticket_token = string_token ~ticketer:ticketer1 "red"; total_amount = nat 2; - destinations = [(destination, nat 2)]; + destinations = [(Destination.Contract destination, nat 2)]; }; { ticket_token = string_token ~ticketer:ticketer1 "green"; total_amount = nat 2; - destinations = [(destination, nat 2)]; + destinations = [(Destination.Contract destination, nat 2)]; }; { ticket_token = string_token ~ticketer:ticketer1 "blue"; total_amount = nat 2; - destinations = [(destination, nat 2)]; + destinations = [(Destination.Contract destination, nat 2)]; }; { ticket_token = string_token ~ticketer:ticketer2 "red"; total_amount = nat 1; - destinations = [(destination, nat 1)]; + destinations = [(Destination.Contract destination, nat 1)]; }; { ticket_token = string_token ~ticketer:ticketer2 "green"; total_amount = nat 1; - destinations = [(destination, nat 1)]; + destinations = [(Destination.Contract destination, nat 1)]; }; { ticket_token = string_token ~ticketer:ticketer2 "blue"; total_amount = nat 1; - destinations = [(destination, nat 1)]; + destinations = [(Destination.Contract destination, nat 1)]; }; ] @@ -586,17 +623,29 @@ let test_transfer_to_two_contracts_with_different_tickets () = { ticket_token = string_token ~ticketer "red"; total_amount = nat 2; - destinations = [(destination2, nat 1); (destination1, nat 1)]; + destinations = + [ + (Destination.Contract destination2, nat 1); + (Destination.Contract destination1, nat 1); + ]; }; { ticket_token = string_token ~ticketer "green"; total_amount = nat 2; - destinations = [(destination2, nat 1); (destination1, nat 1)]; + destinations = + [ + (Destination.Contract destination2, nat 1); + (Destination.Contract destination1, nat 1); + ]; }; { ticket_token = string_token ~ticketer "blue"; total_amount = nat 2; - destinations = [(destination2, nat 1); (destination1, nat 1)]; + destinations = + [ + (Destination.Contract destination2, nat 1); + (Destination.Contract destination1, nat 1); + ]; }; ] @@ -657,7 +706,7 @@ let test_originate_with_one_ticket () = { ticket_token = string_token ~ticketer "white"; total_amount = nat 1; - destinations = [(orig_contract, nat 1)]; + destinations = [(Destination.Contract orig_contract, nat 1)]; }; ] @@ -698,17 +747,17 @@ let test_originate_with_multiple_tickets () = { ticket_token = string_token ~ticketer "red"; total_amount = nat 5; - destinations = [(orig_contract, nat 5)]; + destinations = [(Destination.Contract orig_contract, nat 5)]; }; { ticket_token = string_token ~ticketer "blue"; total_amount = nat 2; - destinations = [(orig_contract, nat 2)]; + destinations = [(Destination.Contract orig_contract, nat 2)]; }; { ticket_token = string_token ~ticketer "green"; total_amount = nat 3; - destinations = [(orig_contract, nat 3)]; + destinations = [(Destination.Contract orig_contract, nat 3)]; }; ] @@ -760,32 +809,32 @@ let test_originate_with_different_tickets () = { ticket_token = string_token ~ticketer:ticketer1 "red"; total_amount = nat 2; - destinations = [(orig_contract, nat 2)]; + destinations = [(Destination.Contract orig_contract, nat 2)]; }; { ticket_token = string_token ~ticketer:ticketer1 "green"; total_amount = nat 2; - destinations = [(orig_contract, nat 2)]; + destinations = [(Destination.Contract orig_contract, nat 2)]; }; { ticket_token = string_token ~ticketer:ticketer1 "blue"; total_amount = nat 2; - destinations = [(orig_contract, nat 2)]; + destinations = [(Destination.Contract orig_contract, nat 2)]; }; { ticket_token = string_token ~ticketer:ticketer2 "red"; total_amount = nat 1; - destinations = [(orig_contract, nat 1)]; + destinations = [(Destination.Contract orig_contract, nat 1)]; }; { ticket_token = string_token ~ticketer:ticketer2 "green"; total_amount = nat 1; - destinations = [(orig_contract, nat 1)]; + destinations = [(Destination.Contract orig_contract, nat 1)]; }; { ticket_token = string_token ~ticketer:ticketer2 "blue"; total_amount = nat 1; - destinations = [(orig_contract, nat 1)]; + destinations = [(Destination.Contract orig_contract, nat 1)]; }; ] @@ -832,17 +881,29 @@ let test_originate_two_contracts_with_different_tickets () = { ticket_token = string_token ~ticketer "red"; total_amount = nat 2; - destinations = [(orig_contract2, nat 1); (orig_contract1, nat 1)]; + destinations = + [ + (Destination.Contract orig_contract2, nat 1); + (Destination.Contract orig_contract1, nat 1); + ]; }; { ticket_token = string_token ~ticketer "green"; total_amount = nat 2; - destinations = [(orig_contract2, nat 1); (orig_contract1, nat 1)]; + destinations = + [ + (Destination.Contract orig_contract2, nat 1); + (Destination.Contract orig_contract1, nat 1); + ]; }; { ticket_token = string_token ~ticketer "blue"; total_amount = nat 2; - destinations = [(orig_contract2, nat 1); (orig_contract1, nat 1)]; + destinations = + [ + (Destination.Contract orig_contract2, nat 1); + (Destination.Contract orig_contract1, nat 1); + ]; }; ] @@ -896,17 +957,29 @@ let test_originate_and_transfer () = { ticket_token = string_token ~ticketer "red"; total_amount = nat 2; - destinations = [(destination2, nat 1); (orig_contract1, nat 1)]; + destinations = + [ + (Destination.Contract destination2, nat 1); + (Destination.Contract orig_contract1, nat 1); + ]; }; { ticket_token = string_token ~ticketer "green"; total_amount = nat 2; - destinations = [(destination2, nat 1); (orig_contract1, nat 1)]; + destinations = + [ + (Destination.Contract destination2, nat 1); + (Destination.Contract orig_contract1, nat 1); + ]; }; { ticket_token = string_token ~ticketer "blue"; total_amount = nat 2; - destinations = [(destination2, nat 1); (orig_contract1, nat 1)]; + destinations = + [ + (Destination.Contract destination2, nat 1); + (Destination.Contract orig_contract1, nat 1); + ]; }; ] @@ -954,17 +1027,17 @@ let test_originate_big_map_with_tickets () = { ticket_token = string_token ~ticketer "red"; total_amount = nat 1; - destinations = [(orig_contract, nat 1)]; + destinations = [(Destination.Contract orig_contract, nat 1)]; }; { ticket_token = string_token ~ticketer "green"; total_amount = nat 1; - destinations = [(orig_contract, nat 1)]; + destinations = [(Destination.Contract orig_contract, nat 1)]; }; { ticket_token = string_token ~ticketer "blue"; total_amount = nat 1; - destinations = [(orig_contract, nat 1)]; + destinations = [(Destination.Contract orig_contract, nat 1)]; }; ] @@ -1034,17 +1107,74 @@ let test_transfer_big_map_with_tickets () = { ticket_token = string_token ~ticketer:ticketer_contract "red"; total_amount = nat 1; - destinations = [(orig_contract, nat 1)]; + destinations = [(Destination.Contract orig_contract, nat 1)]; }; { ticket_token = string_token ~ticketer:ticketer_contract "green"; total_amount = nat 1; - destinations = [(orig_contract, nat 1)]; + destinations = [(Destination.Contract orig_contract, nat 1)]; }; { ticket_token = string_token ~ticketer:ticketer_contract "blue"; total_amount = nat 1; - destinations = [(orig_contract, nat 1)]; + destinations = [(Destination.Contract orig_contract, nat 1)]; + }; + ] + +(** Test transfer a ticket to a tx_rollup. *) +let test_tx_rollup_deposit_one_ticket () = + let open Lwt_tzresult_syntax in + let* (_baker, src, block) = init ~tx_rollup_enable:true () in + let* ticketer = one_ticketer block in + let* incr = Incremental.begin_construction block in + let* (operation, tx_rollup) = + Op.tx_rollup_origination (I incr) src ~fee:(Test_tez.of_int 10) + in + let* incr = Incremental.add_operation incr operation in + + let*? ticket_ty = + Script_typed_ir.(ticket_t Micheline.dummy_location string_key) + |> Environment.wrap_tzresult + in + let*? (Ty_ex_c parameters_ty) = + Script_typed_ir.( + pair_t Micheline.dummy_location ticket_ty tx_rollup_l2_address_t) + |> Environment.wrap_tzresult + in + let amount = + Script_int.(is_nat @@ of_int 1) |> WithExceptions.Option.get ~loc:__LOC__ + in + let*? contents = + Script_string.of_string "white" |> Environment.wrap_tzresult + in + let l2_destination = + Indexable.value + @@ Tx_rollup_l2_address.of_b58check_exn + "tz4MSfZsn6kMDczShy8PMeB628TNukn9hi2K" + in + let parameters = + (Script_typed_ir.{ticketer; contents; amount}, l2_destination) + in + + let* (operation, incr) = + transfer_operation_to_tx_rollup + ~incr + ~src + ~tx_rollup + ~parameters_ty + ~parameters + in + let* (ticket_diffs, ctxt) = ticket_diffs_of_operations incr [operation] in + assert_equal_ticket_token_diffs + ctxt + ~loc:__LOC__ + ticket_diffs + ~expected: + [ + { + ticket_token = string_token ~ticketer "white"; + total_amount = nat 1; + destinations = [(Destination.Tx_rollup tx_rollup, nat 1)]; }; ] @@ -1111,4 +1241,8 @@ let tests = "Test transfer big-map with tickets" `Quick test_transfer_big_map_with_tickets; + Tztest.tztest + "Testt tx rollup deposit one ticket" + `Quick + test_tx_rollup_deposit_one_ticket; ] diff --git a/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml b/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml index 67e963c2e8..6d81f87524 100644 --- a/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml +++ b/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml @@ -27,7 +27,7 @@ (** Testing ------- - Component: Rollup layer 1 logic + Component: Tx rollup layer 1 logic Invocation: cd src/proto_alpha/lib_protocol/test/integration/operations \ && dune exec ./main.exe -- test "^tx rollup$" Subject: Test rollup @@ -239,29 +239,32 @@ let gen_l2_account () = (** [make_ticket_key ty contents ticketer tx_rollup] computes the ticket hash of the ticket containing [contents] of type [ty], crafted by [ticketer] and owned by [tx_rollup]. *) -let make_ticket_key ~ty ~contents ~ticketer tx_rollup = - let open Tezos_micheline.Micheline in - let ticketer = - Bytes (0, Data_encoding.Binary.to_bytes_exn Contract.encoding ticketer) - in - match - Alpha_context.Tx_rollup.Internal_for_tests.hash_ticket_uncarbonated - ~ticketer - ~ty - ~contents - tx_rollup - with - | Ok x -> x - | Error _ -> raise (Invalid_argument "make_ticket_key") +let make_ticket_key ctxt ~ty ~contents ~ticketer tx_rollup = + (match ctxt with + | Context.B block -> + Incremental.begin_construction block >>=? fun incr -> return incr + | Context.I incr -> return incr) + >>=? fun incr -> + let ctxt = Incremental.alpha_ctxt incr in + Environment.wrap_tzresult @@ Script_ir_translator.parse_comparable_ty ctxt ty + >>?= fun (Ex_comparable_ty contents_type, ctxt) -> + wrap @@ Script_ir_translator.parse_comparable_data ctxt contents_type contents + >>=? fun (contents, ctxt) -> + wrap + @@ Ticket_balance_key.of_ex_token + ctxt + ~owner:(Tx_rollup tx_rollup) + (Ticket_token.Ex_token {ticketer; contents_type; contents}) + >|=? fst (** [make_unit_ticket_key ticketer tx_rollup] computes the ticket hash of the unit ticket crafted by [ticketer] and owned by [tx_rollup]. *) -let make_unit_ticket_key ~ticketer tx_rollup = +let make_unit_ticket_key ctxt ~ticketer tx_rollup = let open Tezos_micheline.Micheline in let open Michelson_v1_primitives in let ty = Prim (0, T_unit, [], []) in let contents = Prim (0, D_Unit, [], []) in - make_ticket_key ~ty ~contents ~ticketer tx_rollup + make_ticket_key ctxt ~ty ~contents ~ticketer tx_rollup let rng_state = Random.State.make_self_init () @@ -343,6 +346,19 @@ let assert_retired retired = | `Retired -> return_unit | _ -> failwith "Expected retired" +let assert_ticket_balance ~loc block token owner expected = + Incremental.begin_construction block >>=? fun incr -> + let ctxt = Incremental.alpha_ctxt incr in + wrap @@ Ticket_balance_key.of_ex_token ctxt ~owner token + >>=? fun (key_hash, ctxt) -> + wrap (Ticket_balance.get_balance ctxt key_hash) >>=? fun (balance, _) -> + match (balance, expected) with + | (Some b, Some e) -> Assert.equal_int ~loc (Z.to_int b) e + | (Some b, None) -> + failwith "%s: Expected no balance but got some %d" loc (Z.to_int b) + | (None, Some b) -> failwith "%s: Expected balance %d but got none" loc b + | (None, None) -> return () + (** ---- TESTS -------------------------------------------------------------- *) (** [test_origination] originates a transaction rollup and checks that @@ -754,7 +770,8 @@ let test_valid_deposit () = Block.bake ~operation b >>=? fun b -> Incremental.begin_construction b >|=? Incremental.alpha_ctxt >>=? fun _ctxt -> Context.Tx_rollup.inbox (B b) tx_rollup Tx_rollup_level.root >>=? fun inbox -> - let ticket_hash = make_unit_ticket_key ~ticketer:contract tx_rollup in + make_unit_ticket_key (B b) ~ticketer:contract tx_rollup + >>=? fun ticket_hash -> let (message, cumulated_size) = Tx_rollup_message.make_deposit (is_implicit_exn account) @@ -977,6 +994,13 @@ let test_invalid_deposit_too_big_ticket_type () = [tx_rollup_max_ticket_payload_size] succeeds.*) let test_valid_deposit_big_ticket () = let (_, _, pkh) = gen_l2_account () in + (* [overhead] is the number of bytes introduced by the wrapping of a + string in a ticket. This encompasses the ticketer, amount and ty + fields. + + This value has been fetched from the failing test, and acts as a + regression value. *) + let overhead = 112 in context_init1 () >>=? fun (b, account) -> Context.get_constants (B b) >>=? fun constant -> let tx_rollup_max_ticket_payload_size = @@ -992,7 +1016,7 @@ let test_valid_deposit_big_ticket () = >>=? fun (contract, b) -> Incremental.begin_construction b >>=? fun i -> let ticket_contents = - string_ticket_of_size tx_rollup_max_ticket_payload_size + string_ticket_of_size (tx_rollup_max_ticket_payload_size - overhead) in let parameters = Expr_common.( @@ -1857,49 +1881,153 @@ module Rejection = struct end module Withdraw = struct + module Nat_ticket = struct + let ty_str = "nat" + + let ty = Expr.from_string ty_str + + let contents_nat = 1 + + let ex_token ~ticketer = + let contents = + WithExceptions.Option.get ~loc:__LOC__ + @@ Script_int.(of_int contents_nat |> is_nat) + in + Ticket_token.Ex_token + {ticketer; contents_type = Script_typed_ir.nat_key; contents} + + let contents = Expr.from_string (string_of_int contents_nat) + + let int64_amount = 10L + + let amount = Tx_rollup_l2_qty.of_int64_exn int64_amount + + let ticket_hash ctxt ~ticketer ~tx_rollup = + make_ticket_key + ctxt + ~ty:(Tezos_micheline.Micheline.root ty) + ~contents:(Tezos_micheline.Micheline.root contents) + ~ticketer + tx_rollup + + let withdrawal ctxt ~ticketer ?(claimer = ticketer) ?(amount = amount) + tx_rollup : Tx_rollup_withdraw.t tzresult Lwt.t = + ticket_hash ctxt ~ticketer ~tx_rollup >|=? fun ticket_hash -> + Tx_rollup_withdraw. + {claimer = is_implicit_exn claimer; ticket_hash; amount} + end + (** [context_init_withdraw n] initializes a context with [n + 1] accounts, one rollup and a withdrawal recipient contract. *) let context_init_withdraw n = - context_init (n + 1) >>=? fun (b, accounts) -> + context_init (n + 1) >>=? fun (block, accounts) -> let account1 = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth accounts 0 in - originate b account1 >>=? fun (b, tx_rollup) -> - Contract_helpers.originate_contract - "contracts/tx_rollup_withdraw.tz" - "None" + originate block account1 >>=? fun (block, tx_rollup) -> + let script = + Format.sprintf + {| parameter (pair address tx_rollup_l2_address); + storage unit; + code { + # cast the address to contract type + CAR; + UNPAIR; + CONTRACT %%deposit (pair (ticket nat) tx_rollup_l2_address); + ASSERT_SOME; + SWAP; + PUSH mutez 0; + SWAP; + # create a ticket + PUSH nat %Ld; + PUSH %s %d; + TICKET; + PAIR ; + TRANSFER_TOKENS; + PUSH unit Unit; + NIL operation; + DIG 2 ; + CONS; + PAIR } |} + (Tx_rollup_l2_qty.to_int64 Nat_ticket.amount) + Nat_ticket.ty_str + Nat_ticket.contents_nat + in + Contract_helpers.originate_contract_from_string + ~baker:(is_implicit_exn account1) + ~source_contract:account1 + ~script + ~storage:"Unit" + block + >>=? fun (deposit_contract, _script, block) -> + Op.transaction + (B block) + ~entrypoint:Entrypoint.default + ~parameters: + (Script.lazy_expr @@ Expr.from_string + @@ Printf.sprintf + {| Pair %S %S |} + (Tx_rollup.to_b58check tx_rollup) + "tz4MSfZsn6kMDczShy8PMeB628TNukn9hi2K") + ~fee:Tez.one account1 - b - (is_implicit_exn account1) - >>=? fun (withdraw_contract, b) -> - return (account1, accounts, tx_rollup, withdraw_contract, b) + deposit_contract + (Tez.of_mutez_exn 0L) + >>=? fun operation -> + Block.bake ~operation block >>=? fun block -> + Contract_helpers.originate_contract_from_string + ~script: + (Format.sprintf + {| parameter (ticket %s); + storage (option (ticket %s)); + code { CAR ; SOME ; NIL operation ; PAIR } ;|} + Nat_ticket.ty_str + Nat_ticket.ty_str) + ~storage:"None" + ~source_contract:account1 + ~baker:(is_implicit_exn account1) + block + >>=? fun (withdraw_contract, _script, block) -> + return + (account1, accounts, tx_rollup, deposit_contract, withdraw_contract, block) (** [context_init1_withdraw] initializes a context with one account, one rollup and a withdrawal recipient contract. *) let context_init1_withdraw () = context_init_withdraw 0 - >>=? fun (account1, _accounts, tx_rollup, withdraw_contract, b) -> - return (account1, tx_rollup, withdraw_contract, b) + >>=? fun ( account1, + _accounts, + tx_rollup, + deposit_contract, + withdraw_contract, + b ) -> + return (account1, tx_rollup, deposit_contract, withdraw_contract, b) (** [context_init2_withdraw] initializes a context with two accounts, one rollup and a withdrawal recipient contract. *) let context_init2_withdraw () = context_init_withdraw 1 - >>=? fun (account1, accounts, tx_rollup, withdraw_contract, b) -> + >>=? fun ( account1, + accounts, + tx_rollup, + deposit_contract, + withdraw_contract, + b ) -> let account2 = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth accounts 1 in - return (account1, account2, tx_rollup, withdraw_contract, b) + return + (account1, account2, tx_rollup, deposit_contract, withdraw_contract, b) (** [context_finalize_batch_with_withdrawals account tx_rollup batch withdrawals b] - submits a batch containing the message [batch] to [tx_rollup] in the block [b]. - In the following block, it adds a commitment for that block containing - [withdrawals] (same format as in [make_commitment_for_batch]). - In the third and final block, it finalizes the commitment. - - It returns the commitment and a list of dummy context hashes - that was mocked as the result of the applying the batch. - *) + submits a batch containing the message [batch] to [tx_rollup] in the block [b]. + In the following block, it adds a commitment for that block containing + [withdrawals] (same format as in [make_commitment_for_batch]). + In the third and final block, it finalizes the commitment. + + It returns the commitment and a list of dummy context hashes + that was mocked as the result of the applying the batch. + *) let context_finalize_batch_with_withdrawals ~account ~tx_rollup ?(batch = "batch") ~withdrawals b = Op.tx_rollup_submit_batch (B b) account tx_rollup batch @@ -1919,36 +2047,48 @@ module Withdraw = struct Block.bake ~operation b >>=? fun b -> return (commitment, context_hash_list, b) - module Nat_ticket = struct - let ty = Expr.from_string "nat" - - let contents_nat = 1 - - let contents = Expr.from_string (string_of_int contents_nat) - - let amount = Tx_rollup_l2_qty.of_int64_exn 10L - - let ticket_hash ~ticketer ~tx_rollup = - make_ticket_key - ~ty:(Tezos_micheline.Micheline.root ty) - ~contents:(Tezos_micheline.Micheline.root contents) - ~ticketer - tx_rollup - - let withdrawal ~ticketer ?(recipient = ticketer) tx_rollup : - Tx_rollup_withdraw.t = - { - claimer = is_implicit_exn recipient; - ticket_hash = ticket_hash ~ticketer ~tx_rollup; - amount; - } - end - (** [test_valid_withdraw] checks that a smart contract can deposit tickets to a transaction rollup. *) let test_valid_withdraw () = context_init1_withdraw () - >>=? fun (account1, tx_rollup, withdraw_contract, b) -> + >>=? fun (account1, tx_rollup, deposit_contract, withdraw_contract, block) + -> + Contract_helpers.originate_contract_from_string + ~script: + (Format.sprintf + {| parameter (ticket %s); + storage unit; + code { CDR; NIL operation ; PAIR } ;|} + Nat_ticket.ty_str) + ~storage:"Unit" + ~source_contract:account1 + ~baker:(is_implicit_exn account1) + block + >>=? fun (withdraw_dropping_contract, _script, block) -> + let token_one = Nat_ticket.ex_token ~ticketer:deposit_contract in + (* The Tx_rollup should own some tickets and the two contract none before + calling withdraw.*) + assert_ticket_balance + ~loc:__LOC__ + block + token_one + (Contract deposit_contract) + None + >>=? fun () -> + assert_ticket_balance + ~loc:__LOC__ + block + token_one + (Contract withdraw_contract) + None + >>=? fun () -> + assert_ticket_balance + ~loc:__LOC__ + block + token_one + (Tx_rollup tx_rollup) + (Some (Int64.to_int Nat_ticket.int64_amount)) + >>=? fun () -> (* The withdrawal execution operation must include proof that the level it specifies allows the withdrawal it executes. @@ -1970,47 +2110,63 @@ module Withdraw = struct This will result in a withdrawal that can be executed. *) - (* 1. Create a ticket and it's withdrawal *) - let withdraw = Nat_ticket.withdrawal ~ticketer:account1 tx_rollup in - + (* 1. Create a ticket and two withdrawal to empty it *) + let int64_half_amount = Int64.div Nat_ticket.int64_amount 2L in + let half_amount = Tx_rollup_l2_qty.of_int64_exn int64_half_amount in + Nat_ticket.withdrawal + (B block) + ~ticketer:deposit_contract + ~claimer:account1 + ~amount:half_amount + tx_rollup + >>=? fun withdraw1 -> + Nat_ticket.withdrawal + (B block) + ~ticketer:deposit_contract + ~claimer:account1 + ~amount:half_amount + tx_rollup + >>=? fun withdraw2 -> (* 2 Add a batch message to [b], a commitment for that inbox containing the withdrawal at index 0, and finalize that commitment *) context_finalize_batch_with_withdrawals ~account:account1 ~tx_rollup - ~withdrawals:[(0, [withdraw])] - b - >>=? fun (_commitment, context_hash_list, b) -> + ~withdrawals:[(0, [withdraw1; withdraw2])] + block + >>=? fun (_commitment, context_hash_list, block) -> (* -- At this point, everything is in place for the user to execute the withdrawal -- *) (* 3. Now execute the withdrawal. The ticket should be received by withdraw_contract at the default entrypoint. *) - (let entrypoint = Entrypoint.default in - let context_hash = - WithExceptions.Option.get ~loc:__LOC__ @@ List.nth context_hash_list 0 - in - let withdraw_proof = Tx_rollup_withdraw.compute_path [withdraw] 0 in - Op.tx_rollup_withdraw - (B b) - ~source:account1 - tx_rollup - Tx_rollup_level.root - ~context_hash - ~contents:(Script.lazy_expr Nat_ticket.contents) - ~ty:(Script.lazy_expr Nat_ticket.ty) - ~ticketer:account1 - Nat_ticket.amount - ~destination:withdraw_contract - withdraw_proof - ~message_index:0 - entrypoint) + let entrypoint = Entrypoint.default in + let context_hash = + WithExceptions.Option.get ~loc:__LOC__ @@ List.nth context_hash_list 0 + in + let withdraw_proof1 = + Tx_rollup_withdraw.compute_path [withdraw1; withdraw2] 0 + in + Op.tx_rollup_withdraw + (B block) + ~source:account1 + tx_rollup + Tx_rollup_level.root + ~context_hash + ~contents:(Script.lazy_expr Nat_ticket.contents) + ~ty:(Script.lazy_expr Nat_ticket.ty) + ~ticketer:deposit_contract + half_amount + ~destination:withdraw_contract + withdraw_proof1 + ~message_index:0 + entrypoint >>=? fun operation -> - Block.bake ~operation b >>=? fun b -> - (* 4. Finally, we assert that [withdraw_contract] has received the - ticket as expected *) - Incremental.begin_construction b >>=? fun i -> + Block.bake ~operation block >>=? fun block -> + (* 4.1 We assert that [withdraw_contract] has received the ticket as + expected *) + Incremental.begin_construction block >>=? fun i -> let ctxt = Incremental.alpha_ctxt i in wrap @@ Contract.get_storage ctxt withdraw_contract >>=? fun (_ctxt, found_storage) -> @@ -2024,19 +2180,95 @@ module Withdraw = struct "(Some (Pair 0x%s (Pair %d %s)))" (Hex.show (Hex.of_string - (Data_encoding.Binary.to_string_exn Contract.encoding account1))) + (Data_encoding.Binary.to_string_exn + Contract.encoding + deposit_contract))) Nat_ticket.contents_nat - (Tx_rollup_l2_qty.to_string Nat_ticket.amount) + (Tx_rollup_l2_qty.to_string half_amount) |> Expr.from_string |> Option.some in - if expected_storage = found_storage then return_unit - else Alcotest.fail "Storage didn't match" + (if expected_storage = found_storage then return_unit + else Alcotest.fail "Storage didn't match") + >>=? fun () -> + (* 4.2 The Tx_rollup should owns some tickets and the withdraw_contract half + of it.*) + assert_ticket_balance + ~loc:__LOC__ + block + token_one + (Contract deposit_contract) + None + >>=? fun () -> + assert_ticket_balance + ~loc:__LOC__ + block + token_one + (Contract withdraw_contract) + (Some (Int64.to_int int64_half_amount)) + >>=? fun () -> + assert_ticket_balance + ~loc:__LOC__ + block + token_one + (Tx_rollup tx_rollup) + (Some (Int64.to_int int64_half_amount)) + >>=? fun () -> + (* 5.1 And finally we try to drop the other half amount of ticket. *) + let withdraw_path2 = + Tx_rollup_withdraw.compute_path [withdraw1; withdraw2] 1 + in + Op.tx_rollup_withdraw + (B block) + ~source:account1 + tx_rollup + Tx_rollup_level.root + ~context_hash + ~contents:(Script.lazy_expr Nat_ticket.contents) + ~ty:(Script.lazy_expr Nat_ticket.ty) + ~ticketer:deposit_contract + half_amount + ~destination:withdraw_dropping_contract + withdraw_path2 + ~message_index:0 + entrypoint + >>=? fun operation -> + Block.bake ~operation block >>=? fun block -> + (* 4. Finally, we assert that [withdraw_contract] has received the ticket as + expected *) + Incremental.begin_construction block >>=? fun i -> + let ctxt = Incremental.alpha_ctxt i in + wrap @@ Contract.get_storage ctxt withdraw_dropping_contract + >>=? fun (_ctxt, found_storage) -> + let expected_storage = "Unit" |> Expr.from_string |> Option.some in + (if expected_storage = found_storage then return_unit + else Alcotest.fail "Storage didn't match") + >>=? fun () -> + assert_ticket_balance + ~loc:__LOC__ + block + token_one + (Contract deposit_contract) + None + >>=? fun () -> + assert_ticket_balance + ~loc:__LOC__ + block + token_one + (Contract withdraw_dropping_contract) + None + >>=? fun () -> + assert_ticket_balance + ~loc:__LOC__ + block + token_one + (Tx_rollup tx_rollup) + None (** [test_invalid_withdraw_no_commitment] checks that attempting to withdraw from a level with no commited inbox raises an error. *) let test_invalid_withdraw_no_commitment () = context_init1_withdraw () - >>=? fun (account1, tx_rollup, withdraw_contract, b) -> + >>=? fun (account1, tx_rollup, deposit_contract, withdraw_contract, b) -> Incremental.begin_construction b >>=? fun i -> let entrypoint = Entrypoint.default in let context_hash = Context_hash.hash_bytes [Bytes.make 20 'c'] in @@ -2061,7 +2293,7 @@ module Withdraw = struct ~message_index:0 ~contents:(Script.lazy_expr Nat_ticket.contents) ~ty:(Script.lazy_expr Nat_ticket.ty) - ~ticketer:account1 + ~ticketer:deposit_contract Nat_ticket.amount ~destination:withdraw_contract dummy_withdraw_proof @@ -2083,12 +2315,17 @@ module Withdraw = struct associated. *) let test_invalid_withdraw_missing_withdraw_in_commitment () = context_init1_withdraw () - >>=? fun (account1, tx_rollup, withdraw_contract, b) -> + >>=? fun (account1, tx_rollup, deposit_contract, withdraw_contract, b) -> let batch = "batch" in Op.tx_rollup_submit_batch (B b) account1 tx_rollup batch >>=? fun operation -> Block.bake ~operation b >>=? fun b -> - let withdraw = Nat_ticket.withdrawal ~ticketer:account1 tx_rollup in + Nat_ticket.withdrawal + (B b) + ~ticketer:deposit_contract + ~claimer:account1 + tx_rollup + >>=? fun withdraw -> context_finalize_batch_with_withdrawals ~account:account1 ~tx_rollup @@ -2110,7 +2347,7 @@ module Withdraw = struct ~message_index:0 ~contents:(Script.lazy_expr Nat_ticket.contents) ~ty:(Script.lazy_expr Nat_ticket.ty) - ~ticketer:account1 + ~ticketer:deposit_contract Nat_ticket.amount ~destination:withdraw_contract withdraw_path @@ -2127,13 +2364,17 @@ module Withdraw = struct are raised. *) let test_invalid_withdraw_tickets () = context_init1_withdraw () - >>=? fun (account1, tx_rollup, withdraw_contract, b) -> + >>=? fun (account1, tx_rollup, deposit_contract, withdraw_contract, b) -> let batch = "batch" in Op.tx_rollup_submit_batch (B b) account1 tx_rollup batch >>=? fun operation -> Block.bake ~operation b >>=? fun b -> - let withdraw = Nat_ticket.withdrawal ~ticketer:account1 tx_rollup in - + Nat_ticket.withdrawal + (B b) + ~ticketer:deposit_contract + ~claimer:account1 + tx_rollup + >>=? fun withdraw -> context_finalize_batch_with_withdrawals ~account:account1 ~tx_rollup @@ -2160,7 +2401,7 @@ module Withdraw = struct ~message_index:0 ~contents:(Script.lazy_expr Nat_ticket.contents) ~ty:(Script.lazy_expr Nat_ticket.ty) - ~ticketer:account1 + ~ticketer:deposit_contract amount ~destination:withdraw_contract withdraw_path @@ -2185,14 +2426,19 @@ module Withdraw = struct ~message_index:0 ~contents:(Script.lazy_expr Nat_ticket.contents) ~ty:(Script.lazy_expr @@ Expr.from_string "unit") - ~ticketer:account1 + ~ticketer:deposit_contract Nat_ticket.amount ~destination:withdraw_contract withdraw_path entrypoint) >>=? fun operation -> Incremental.add_operation - ~expect_failure:(check_proto_error Tx_rollup_errors.Withdraw_invalid_path) + ~expect_failure:(function + | Environment.Ecoproto_error + (Script_tc_errors.Invalid_constant (_, _, _)) + :: _ -> + return_unit + | _ -> Alcotest.fail "expected to fail with wrong type") i operation >>=? fun _i -> @@ -2207,7 +2453,7 @@ module Withdraw = struct ~message_index:0 ~contents:(Script.lazy_expr @@ Expr.from_string "2") ~ty:(Script.lazy_expr Nat_ticket.ty) - ~ticketer:account1 + ~ticketer:deposit_contract Nat_ticket.amount ~destination:withdraw_contract withdraw_path @@ -2229,7 +2475,7 @@ module Withdraw = struct ~message_index:0 ~contents:(Script.lazy_expr Nat_ticket.contents) ~ty:(Script.lazy_expr Nat_ticket.ty) - ~ticketer:withdraw_contract + ~ticketer:account1 Nat_ticket.amount ~destination:withdraw_contract withdraw_path @@ -2245,14 +2491,17 @@ module Withdraw = struct an invalid proof. *) let test_invalid_withdraw_invalid_proof () = context_init1_withdraw () - >>=? fun (account1, tx_rollup, withdraw_contract, b) -> + >>=? fun (account1, tx_rollup, deposit_contract, withdraw_contract, b) -> let batch = "batch" in Op.tx_rollup_submit_batch (B b) account1 tx_rollup batch >>=? fun operation -> Block.bake ~operation b >>=? fun b -> - let withdrawal1 : Tx_rollup_withdraw.t = - Nat_ticket.withdrawal ~ticketer:account1 tx_rollup - in + Nat_ticket.withdrawal + (B b) + ~ticketer:deposit_contract + ~claimer:account1 + tx_rollup + >>=? fun withdrawal1 -> let withdrawal2 : Tx_rollup_withdraw.t = {withdrawal1 with amount = Tx_rollup_l2_qty.of_int64_exn 5L} in @@ -2282,7 +2531,7 @@ module Withdraw = struct ~message_index:0 ~contents:(Script.lazy_expr Nat_ticket.contents) ~ty:(Script.lazy_expr Nat_ticket.ty) - ~ticketer:account1 + ~ticketer:deposit_contract Nat_ticket.amount ~destination:withdraw_contract invalid_withdraw_path @@ -2307,7 +2556,7 @@ module Withdraw = struct ~message_index:0 ~contents:(Script.lazy_expr Nat_ticket.contents) ~ty:(Script.lazy_expr Nat_ticket.ty) - ~ticketer:account1 + ~ticketer:deposit_contract Nat_ticket.amount ~destination:withdraw_contract invalid_withdraw_path @@ -2323,8 +2572,13 @@ module Withdraw = struct withdrawal twice raises [Withdraw_already_consumed]. *) let test_invalid_withdraw_already_consumed () = context_init1_withdraw () - >>=? fun (account1, tx_rollup, withdraw_contract, b) -> - let withdraw = Nat_ticket.withdrawal ~ticketer:account1 tx_rollup in + >>=? fun (account1, tx_rollup, deposit_contract, withdraw_contract, b) -> + Nat_ticket.withdrawal + (B b) + ~ticketer:deposit_contract + ~claimer:account1 + tx_rollup + >>=? fun withdraw -> context_finalize_batch_with_withdrawals ~account:account1 ~tx_rollup @@ -2345,7 +2599,7 @@ module Withdraw = struct ~context_hash ~contents:(Script.lazy_expr Nat_ticket.contents) ~ty:(Script.lazy_expr Nat_ticket.ty) - ~ticketer:account1 + ~ticketer:deposit_contract Nat_ticket.amount ~destination:withdraw_contract withdraw_proof @@ -2363,7 +2617,7 @@ module Withdraw = struct ~context_hash ~contents:(Script.lazy_expr Nat_ticket.contents) ~ty:(Script.lazy_expr Nat_ticket.ty) - ~ticketer:account1 + ~ticketer:deposit_contract Nat_ticket.amount ~destination:withdraw_contract withdraw_proof @@ -2382,13 +2636,18 @@ module Withdraw = struct incorrect proof. *) let test_invalid_withdraw_someone_elses () = context_init2_withdraw () - >>=? fun (account1, account2, tx_rollup, withdraw_contract, b) -> - let withdraw = - Nat_ticket.withdrawal - ~ticketer:account1 (* Explicit for clarity *) - ~recipient:account1 - tx_rollup - in + >>=? fun ( account1, + account2, + tx_rollup, + deposit_contract, + withdraw_contract, + b ) -> + Nat_ticket.withdrawal + (B b) + ~ticketer:deposit_contract + ~claimer:account1 + tx_rollup + >>=? fun withdraw -> context_finalize_batch_with_withdrawals ~account:account1 ~tx_rollup @@ -2411,7 +2670,7 @@ module Withdraw = struct ~context_hash ~contents:(Script.lazy_expr Nat_ticket.contents) ~ty:(Script.lazy_expr Nat_ticket.ty) - ~ticketer:account1 + ~ticketer:deposit_contract Nat_ticket.amount ~destination:withdraw_contract withdraw_proof @@ -2428,8 +2687,12 @@ module Withdraw = struct attempting to withdraw nat tickets to a contract taking unit tickets raises [Bad_contract_parameter]. *) let test_invalid_withdraw_illtyped_entrypoint () = - context_init1 () >>=? fun (b, account1) -> - originate b account1 >>=? fun (b, tx_rollup) -> + context_init1_withdraw () + >>=? fun ( account1, + tx_rollup, + deposit_contract, + _unused_withdraw_contract, + b ) -> Contract_helpers.originate_contract "contracts/tx_rollup_withdraw_unit_tickets.tz" "None" @@ -2437,7 +2700,12 @@ module Withdraw = struct b (is_implicit_exn account1) >>=? fun (withdraw_contract_unit_tickets, b) -> - let withdraw = Nat_ticket.withdrawal ~ticketer:account1 tx_rollup in + Nat_ticket.withdrawal + (B b) + ~ticketer:deposit_contract + ~claimer:account1 + tx_rollup + >>=? fun withdraw -> context_finalize_batch_with_withdrawals ~account:account1 ~tx_rollup @@ -2458,7 +2726,7 @@ module Withdraw = struct ~context_hash ~contents:(Script.lazy_expr Nat_ticket.contents) ~ty:(Script.lazy_expr Nat_ticket.ty) - ~ticketer:account1 + ~ticketer:deposit_contract Nat_ticket.amount ~destination:withdraw_contract_unit_tickets withdraw_proof @@ -2479,8 +2747,13 @@ module Withdraw = struct tickets raises [Bad_contract_parameter]. *) let test_invalid_withdraw_bad_entrypoint () = context_init1_withdraw () - >>=? fun (account1, tx_rollup, withdraw_contract, b) -> - let withdraw = Nat_ticket.withdrawal ~ticketer:account1 tx_rollup in + >>=? fun (account1, tx_rollup, deposit_contract, withdraw_contract, b) -> + Nat_ticket.withdrawal + (B b) + ~ticketer:deposit_contract + ~claimer:account1 + tx_rollup + >>=? fun withdraw -> context_finalize_batch_with_withdrawals ~account:account1 ~tx_rollup @@ -2501,7 +2774,7 @@ module Withdraw = struct ~context_hash ~contents:(Script.lazy_expr Nat_ticket.contents) ~ty:(Script.lazy_expr Nat_ticket.ty) - ~ticketer:account1 + ~ticketer:deposit_contract Nat_ticket.amount ~destination:withdraw_contract withdraw_proof @@ -2520,7 +2793,7 @@ module Withdraw = struct level with a wrong message index raises an error. *) let test_invalid_message_index () = context_init1_withdraw () - >>=? fun (account1, tx_rollup, withdraw_contract, b) -> + >>=? fun (account1, tx_rollup, deposit_contract, withdraw_contract, b) -> (* 1. Create and submit two dummy batch *) let batch1 = "batch" in Op.tx_rollup_submit_batch (B b) account1 tx_rollup batch1 @@ -2531,14 +2804,13 @@ module Withdraw = struct let contents_nat = 1 in let contents = Expr.from_string (string_of_int contents_nat) in let amount = Tx_rollup_l2_qty.of_int64_exn 10L in - let ticket_hash = - make_ticket_key - ~ty:(Tezos_micheline.Micheline.root ty) - ~contents:(Tezos_micheline.Micheline.root contents) - ~ticketer:account1 - tx_rollup - in - + make_ticket_key + (B b) + ~ty:(Tezos_micheline.Micheline.root ty) + ~contents:(Tezos_micheline.Micheline.root contents) + ~ticketer:withdraw_contract + tx_rollup + >>=? fun ticket_hash -> (* 2.2 Create a withdrawal for the ticket *) let withdraw : Tx_rollup_withdraw.t = {claimer = is_implicit_exn account1; ticket_hash; amount} @@ -2576,7 +2848,7 @@ module Withdraw = struct ~context_hash ~contents:(Script.lazy_expr contents) ~ty:(Script.lazy_expr ty) - ~ticketer:account1 + ~ticketer:deposit_contract amount ~destination:withdraw_contract withdraw_proof @@ -2595,8 +2867,13 @@ module Withdraw = struct level of a commitment already removed fails. *) let test_too_late_withdrawal () = context_init1_withdraw () - >>=? fun (account1, tx_rollup, withdraw_contract, b) -> - let withdraw = Nat_ticket.withdrawal ~ticketer:account1 tx_rollup in + >>=? fun (account1, tx_rollup, deposit_contract, withdraw_contract, b) -> + Nat_ticket.withdrawal + (B b) + ~ticketer:deposit_contract + ~claimer:account1 + tx_rollup + >>=? fun withdraw -> context_finalize_batch_with_withdrawals ~account:account1 ~tx_rollup @@ -2621,7 +2898,7 @@ module Withdraw = struct ~context_hash ~contents:(Script.lazy_expr Nat_ticket.contents) ~ty:(Script.lazy_expr Nat_ticket.ty) - ~ticketer:account1 + ~ticketer:deposit_contract Nat_ticket.amount ~destination:withdraw_contract withdraw_proof @@ -2648,7 +2925,7 @@ module Withdraw = struct let test_withdrawal_accounting_is_cleaned_up_after_removal () = let open Error_monad_operators in context_init1_withdraw () - >>=? fun (account1, tx_rollup, withdraw_contract, b) -> + >>=? fun (account1, tx_rollup, deposit_contract, withdraw_contract, b) -> let assert_consumed b ~msg consumed_expected = Incremental.begin_construction b >>=? fun i -> let ctxt = Incremental.alpha_ctxt i in @@ -2663,7 +2940,12 @@ module Withdraw = struct return_unit in - let withdraw = Nat_ticket.withdrawal ~ticketer:account1 tx_rollup in + Nat_ticket.withdrawal + (B b) + ~ticketer:deposit_contract + ~claimer:account1 + tx_rollup + >>=? fun withdraw -> context_finalize_batch_with_withdrawals ~account:account1 ~tx_rollup @@ -2686,7 +2968,7 @@ module Withdraw = struct ~context_hash ~contents:(Script.lazy_expr Nat_ticket.contents) ~ty:(Script.lazy_expr Nat_ticket.ty) - ~ticketer:account1 + ~ticketer:deposit_contract Nat_ticket.amount ~destination:withdraw_contract withdraw_proof diff --git a/src/proto_alpha/lib_protocol/ticket_accounting.ml b/src/proto_alpha/lib_protocol/ticket_accounting.ml index d4609a8c28..e04e6c5c19 100644 --- a/src/proto_alpha/lib_protocol/ticket_accounting.ml +++ b/src/proto_alpha/lib_protocol/ticket_accounting.ml @@ -88,7 +88,7 @@ let ticket_balances_of_value ctxt ~include_lazy ty value = let update_ticket_balances ctxt ~total_storage_diff token destinations = List.fold_left_es (fun (tot_storage_diff, ctxt) (owner, delta) -> - Ticket_balance_key.ticket_balance_key ctxt ~owner token + Ticket_balance_key.of_ex_token ctxt ~owner token >>=? fun (key_hash, ctxt) -> Ticket_balance.adjust_balance ctxt key_hash ~delta >>=? fun (storage_diff, ctxt) -> @@ -121,7 +121,7 @@ let update_ticket_balances_for_self_contract ctxt ~self ticket_diffs = ctxt ~total_storage_diff ticket_token - [(self, amount)]) + [(Destination.Contract self, amount)]) (Z.zero, ctxt) ticket_diffs diff --git a/src/proto_alpha/lib_protocol/ticket_balance_key.ml b/src/proto_alpha/lib_protocol/ticket_balance_key.ml index a7a74b4a19..442478070a 100644 --- a/src/proto_alpha/lib_protocol/ticket_balance_key.ml +++ b/src/proto_alpha/lib_protocol/ticket_balance_key.ml @@ -27,13 +27,12 @@ open Alpha_context (* This function extracts nodes of: - - Ticketer - - Type of content - - Content - - Owner - to generate at ticket-balance key-hash. -*) -let ticket_balance_key ctxt ~owner + - Ticketer + - Type of content + - Content + - Owner + to generate at ticket-balance key-hash.*) +let of_ex_token ctxt ~owner (Ticket_token.Ex_token {ticketer; contents_type; contents}) = let loc = Micheline.dummy_location in Script_ir_translator.unparse_comparable_ty ~loc ctxt contents_type @@ -44,11 +43,17 @@ let ticket_balance_key ctxt ~owner Gas.consume ctxt (Script.strip_annotations_cost cont_ty_unstripped) >>?= fun ctxt -> let ty = Script.strip_annotations cont_ty_unstripped in - let ticketer = Destination.Contract ticketer in + Script_ir_translator.unparse_comparable_data + ~loc + ctxt + Script_ir_translator.Optimized_legacy + contents_type + contents + >>=? fun (contents, ctxt) -> let ticketer_address = - Script_typed_ir.{destination = ticketer; entrypoint = Entrypoint.default} + Script_typed_ir. + {destination = Contract ticketer; entrypoint = Entrypoint.default} in - let owner = Destination.Contract owner in let owner_address = Script_typed_ir.{destination = owner; entrypoint = Entrypoint.default} in @@ -58,13 +63,6 @@ let ticket_balance_key ctxt ~owner Script_typed_ir.address_t ticketer_address >>=? fun (ticketer, ctxt) -> - Script_ir_translator.unparse_comparable_data - ~loc - ctxt - Script_ir_translator.Optimized_legacy - contents_type - contents - >>=? fun (contents, ctxt) -> Script_ir_translator.unparse_data ctxt Script_ir_translator.Optimized_legacy diff --git a/src/proto_alpha/lib_protocol/ticket_balance_key.mli b/src/proto_alpha/lib_protocol/ticket_balance_key.mli index 1b0900673f..f3160da53d 100644 --- a/src/proto_alpha/lib_protocol/ticket_balance_key.mli +++ b/src/proto_alpha/lib_protocol/ticket_balance_key.mli @@ -23,15 +23,17 @@ (* *) (*****************************************************************************) +open Alpha_context + (** This module exposes a function for generating a ticket-balance key-hash given an owner and a ticket-token. The key-hash is used for populating the global ticket-balance table that tracks ownership of tickets for different tokens. *) -(** [ticket_balance_key ctxt ~owner ex_token] returns the [key_hash] of the +(** [of_ex_token ctxt ~owner ex_token] returns the [key_hash] of the given [owner] and [ex_token]. *) -val ticket_balance_key : - Alpha_context.context -> - owner:Alpha_context.Contract.t -> +val of_ex_token : + context -> + owner:Destination.t -> Ticket_token.ex_token -> - (Alpha_context.Ticket_hash.t * Alpha_context.context) tzresult Lwt.t + (Ticket_hash.t * context) tzresult Lwt.t diff --git a/src/proto_alpha/lib_protocol/ticket_balance_migration_for_j.ml b/src/proto_alpha/lib_protocol/ticket_balance_migration_for_j.ml index 5f11b58051..096d4efe96 100644 --- a/src/proto_alpha/lib_protocol/ticket_balance_migration_for_j.ml +++ b/src/proto_alpha/lib_protocol/ticket_balance_migration_for_j.ml @@ -28,7 +28,7 @@ open Alpha_context (* In the ticket balance table, credit the ticket [ticket] to the owner [contract]. *) let add_ticket_balance contract ctxt ticket = let (token, amount) = Ticket_token.token_and_amount_of_ex_ticket ticket in - Ticket_balance_key.ticket_balance_key ctxt ~owner:contract token + Ticket_balance_key.of_ex_token ctxt ~owner:contract token >>=? fun (hash, ctxt) -> Ticket_balance.adjust_balance ctxt hash ~delta:(Script_int.to_zint amount) >|=? fun ((_added_size : Z.t), ctxt) -> ctxt @@ -57,7 +57,10 @@ let update_contract_tickets ctxt contract = has_tickets storage >>=? fun (tickets, ctxt) -> - List.fold_left_es (add_ticket_balance contract) ctxt tickets + List.fold_left_es + (add_ticket_balance (Destination.Contract contract)) + ctxt + tickets let is_originated contract = match Contract.is_originated contract with Some _ -> true | _ -> false diff --git a/src/proto_alpha/lib_protocol/ticket_operations_diff.ml b/src/proto_alpha/lib_protocol/ticket_operations_diff.ml index 0fcc683b02..ef51b6aec2 100644 --- a/src/proto_alpha/lib_protocol/ticket_operations_diff.ml +++ b/src/proto_alpha/lib_protocol/ticket_operations_diff.ml @@ -26,14 +26,14 @@ open Alpha_context type ticket_transfer = { - destination : Contract.t; + destination : Destination.t; tickets : Ticket_scanner.ex_ticket list; } type ticket_token_diff = { ticket_token : Ticket_token.ex_token; total_amount : Script_int.n Script_int.num; - destinations : (Contract.t * Script_int.n Script_int.num) list; + destinations : (Destination.t * Script_int.n Script_int.num) list; } type error += Failed_to_get_script of Contract.t | Contract_not_originated @@ -65,12 +65,17 @@ let () = (function Contract_not_originated -> Some () | _ -> None) (fun () -> Contract_not_originated) -(** A carbonated map where the keys are contracts. *) -module Contract_map = Carbonated_map.Make (struct - type t = Contract.t +(** A carbonated map where the keys are destination (contract or tx_rollup). *) +module Destination_map = Carbonated_map.Make (struct + type t = Destination.t - let compare = Contract.compare + let compare = Destination.compare + (* TODO: #2667 + Change cost-function to one for comparing destinations. + Not expected to have any performance impact but we should update for + completeness. + *) let compare_cost _ = Ticket_costs.Constants.cost_compare_key_contract end) @@ -94,7 +99,7 @@ module Ticket_token_map = struct (** Adds a ticket-token with a destination and an amount to the map. The layout of the map parameter is as described above. Its type is: - (n num Contract_map.t) Ticket_token_map.t + (n num Destination_map.t) Ticket_token_map.t As explained above, the inner map expresses a list of destination contracts and outgoing amount pairs. @@ -111,7 +116,7 @@ module Ticket_token_map = struct match old_val with | None -> (* Create a new map with a single contract-and amount pair. *) - let map = Contract_map.singleton destination amount in + let map = Destination_map.singleton destination amount in ok (Some map, ctxt) | Some destination_map -> (* Update the inner contract map *) @@ -125,7 +130,7 @@ module Ticket_token_map = struct (Some (Script_int.add_n prev_amount amount), ctxt) | None -> ok (Some amount, ctxt) in - Contract_map.update ctxt destination update destination_map + Destination_map.update ctxt destination update destination_map >|? fun (destination_map, ctxt) -> (Some destination_map, ctxt)) map end @@ -210,13 +215,14 @@ let tickets_of_transaction ctxt ~destination ~entrypoint ~location ctxt has_tickets parameters - >>=? fun (tickets, ctxt) -> return (Some {destination; tickets}, ctxt) + >>=? fun (tickets, ctxt) -> + return (Some {destination = Contract destination; tickets}, ctxt) (** Extract tickets of an origination operation by scanning the storage. *) let tickets_of_origination ctxt ~preorigination script = match preorigination with | None -> fail Contract_not_originated - | Some destination -> + | Some contract -> (* TODO: #2351 Avoid having to parse the script here. We're not able to rely on caching due to issues with lazy storage. @@ -248,13 +254,9 @@ let tickets_of_origination ctxt ~preorigination script = ~include_lazy:true has_tickets storage - >|=? fun (tickets, ctxt) -> (Some {tickets; destination}, ctxt) + >|=? fun (tickets, ctxt) -> + (Some {tickets; destination = Destination.Contract contract}, ctxt) -(* TODO: #2352 - Extend operations scanning to support rollup-operations once ready. - Currently the only two operations that may involve ticket transfers are - originations and transactions. We will likely also need to support rollups. - *) let tickets_of_operation ctxt (Script_typed_ir.Internal_operation {source = _; operation; nonce = _}) = match operation with @@ -278,12 +280,30 @@ let tickets_of_operation ctxt ~location ~parameters_ty ~parameters - | Transaction {transaction = {destination = Destination.Tx_rollup _; _}; _} -> - (* TODO: #2488 - The ticket accounting for the recipient of rollup transactions - is currently done in the apply function, but should rather be - done in this module. *) - return (None, ctxt) + | Transaction + { + transaction = + { + destination = Destination.Tx_rollup tx_rollup_dest; + parameters = _; + entrypoint; + amount = _; + }; + location = _; + parameters_ty; + parameters; + } -> + if Entrypoint.(entrypoint = Tx_rollup.deposit_entrypoint) then + Tx_rollup_parameters.get_deposit_parameters parameters_ty parameters + >>?= fun {ex_ticket; l2_destination = _} -> + return + ( Some + { + destination = Destination.Tx_rollup tx_rollup_dest; + tickets = [ex_ticket]; + }, + ctxt ) + else return (None, ctxt) | Origination {delegate = _; script; credit = _; preorigination} -> tickets_of_origination ctxt ~preorigination script | Delegation _ -> return (None, ctxt) @@ -317,7 +337,7 @@ let ticket_diffs_of_operations ctxt operations = (fun ctxt acc ticket_token destination_map -> (* Calculate the total amount of outgoing units for the current ticket-token. *) - Contract_map.fold + Destination_map.fold ctxt (fun ctxt total_amount _destination amount -> Gas.consume ctxt (Ticket_costs.add_int_cost total_amount amount) @@ -325,7 +345,8 @@ let ticket_diffs_of_operations ctxt operations = Script_int.zero_n destination_map >>? fun (total_amount, ctxt) -> - Contract_map.to_list ctxt destination_map >|? fun (destinations, ctxt) -> + Destination_map.to_list ctxt destination_map + >|? fun (destinations, ctxt) -> ({ticket_token; total_amount; destinations} :: acc, ctxt)) [] token_map diff --git a/src/proto_alpha/lib_protocol/ticket_operations_diff.mli b/src/proto_alpha/lib_protocol/ticket_operations_diff.mli index 0c984a7c34..b32b38b434 100644 --- a/src/proto_alpha/lib_protocol/ticket_operations_diff.mli +++ b/src/proto_alpha/lib_protocol/ticket_operations_diff.mli @@ -36,7 +36,7 @@ type ticket_token_diff = private { ticket_token : Ticket_token.ex_token; total_amount : Alpha_context.Script_int.n Alpha_context.Script_int.num; destinations : - (Alpha_context.Contract.t + (Alpha_context.Destination.t * Alpha_context.Script_int.n Alpha_context.Script_int.num) list; } diff --git a/src/proto_alpha/lib_protocol/ticket_token_map.ml b/src/proto_alpha/lib_protocol/ticket_token_map.ml index 79f2198c49..fd66f16938 100644 --- a/src/proto_alpha/lib_protocol/ticket_token_map.ml +++ b/src/proto_alpha/lib_protocol/ticket_token_map.ml @@ -46,7 +46,10 @@ let key_of_ticket_token ctxt (Ticket_token.Ex_token {ticketer; _} as token) = for comparing tokens. Since an owner contract is required we use [ticketer] but any dummy value would work as long as it's consistent. *) - Ticket_balance_key.ticket_balance_key ctxt ~owner:ticketer token + Ticket_balance_key.of_ex_token + ctxt + ~owner:(Destination.Contract ticketer) + token let update ctxt key f m = key_of_ticket_token ctxt key >>=? fun (key_hash, ctxt) -> diff --git a/src/proto_alpha/lib_protocol/tx_rollup_errors_repr.ml b/src/proto_alpha/lib_protocol/tx_rollup_errors_repr.ml index ef89d54d7f..d5b50ab9ea 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_errors_repr.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_errors_repr.ml @@ -78,6 +78,8 @@ type error += expected : Tx_rollup_commitment_repr.Message_result_hash.t; } | Ticket_payload_size_limit_exceeded of {payload_size : int; limit : int} + | Deposit_wrong_ticketer of Tx_rollup_repr.t + | Wrong_deposit_parameters let () = let open Data_encoding in @@ -525,4 +527,22 @@ let () = Some (payload_size, limit) | _ -> None) (fun (payload_size, limit) -> - Ticket_payload_size_limit_exceeded {payload_size; limit}) + Ticket_payload_size_limit_exceeded {payload_size; limit}) ; + register_error_kind + `Permanent + ~id:"tx_rollup_deposit_wrong_ticketer" + ~title: + "The ticketer submitted in the ticket is a tx rollup instead of a \ + contract." + ~description: + "The ticketer provided with the ticket on the deposit transaction is a \ + tx_rollup which is not possible." + ~pp:(fun ppf tx_rollup -> + Format.fprintf + ppf + "A tx_rollup (%a) can't be the ticketer of a ticket" + Tx_rollup_repr.pp + tx_rollup) + (obj1 (req "tx_rollup" Tx_rollup_repr.encoding)) + (function Deposit_wrong_ticketer tx_rollup -> Some tx_rollup | _ -> None) + (fun tx_rollup -> Deposit_wrong_ticketer tx_rollup) diff --git a/src/proto_alpha/lib_protocol/tx_rollup_l2_qty.ml b/src/proto_alpha/lib_protocol/tx_rollup_l2_qty.ml index 449c830700..28e18a5337 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_l2_qty.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_l2_qty.ml @@ -38,6 +38,8 @@ let of_int64_exn q = let to_int64 q = q +let to_z = Z.of_int64 + let to_string q = Int64.to_string q let of_string q = Option.fold ~none:None ~some:of_int64 (Int64.of_string_opt q) diff --git a/src/proto_alpha/lib_protocol/tx_rollup_l2_qty.mli b/src/proto_alpha/lib_protocol/tx_rollup_l2_qty.mli index 636d56b376..24aeb023b1 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_l2_qty.mli +++ b/src/proto_alpha/lib_protocol/tx_rollup_l2_qty.mli @@ -45,6 +45,9 @@ val of_int64_exn : int64 -> t (** Convert a quantity to [int64]. *) val to_int64 : t -> int64 +(** Convert a quantity to [z]. *) +val to_z : t -> Z.t + (** Returns a string representation of a quantity. *) val to_string : t -> string diff --git a/src/proto_alpha/lib_protocol/tx_rollup_parameters.ml b/src/proto_alpha/lib_protocol/tx_rollup_parameters.ml new file mode 100644 index 0000000000..7c93e0a7f7 --- /dev/null +++ b/src/proto_alpha/lib_protocol/tx_rollup_parameters.ml @@ -0,0 +1,42 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 Marigold <contact@marigold.dev> *) +(* Copyright (c) 2022 Nomadic Labs <contact@nomadic-labs.com> *) +(* Copyright (c) 2022 Oxhead Alpha <info@oxheadalpha.com> *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type deposit_parameters = { + ex_ticket : Ticket_scanner.ex_ticket; + l2_destination : Script_typed_ir.tx_rollup_l2_address; +} + +let get_deposit_parameters : + type a comparable. + (a, comparable) Script_typed_ir.ty -> a -> deposit_parameters tzresult = + fun ty contents -> + let open Script_typed_ir in + match (ty, contents) with + | ( Pair_t (Ticket_t (ty, _), Tx_rollup_l2_address_t, _, _), + (ticket, l2_destination) ) -> + ok {ex_ticket = Ticket_scanner.Ex_ticket (ty, ticket); l2_destination} + | _ -> error Alpha_context.Tx_rollup_errors.Wrong_deposit_parameters diff --git a/src/proto_alpha/lib_protocol/tx_rollup_parameters.mli b/src/proto_alpha/lib_protocol/tx_rollup_parameters.mli new file mode 100644 index 0000000000..8d240a4283 --- /dev/null +++ b/src/proto_alpha/lib_protocol/tx_rollup_parameters.mli @@ -0,0 +1,49 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 Marigold <contact@marigold.dev> *) +(* Copyright (c) 2022 Nomadic Labs <contact@nomadic-labs.com> *) +(* Copyright (c) 2022 Oxhead Alpha <info@oxheadalpha.com> *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** A module for representing and extracting typed transactional rollup + parameters. *) + +(** A type representing deposit parameters for transactional rollups. Deposit + parameters consist of a ticket of arbitrary content along with a + layer-2 destination address. *) +type deposit_parameters = { + ex_ticket : Ticket_scanner.ex_ticket; + l2_destination : Script_typed_ir.tx_rollup_l2_address; +} + +(** [get_deposit_parameters ty value] returns [ex_ticket] and a + [tx_rollup_l2_address] from a michelson typed value. if [ty] is not of a + pair of ticket and [tx_rollup_l2_address] then it fails with + [Tx_rollup_errors.Wrong_deposit_parameters]. + + This function is intended to be used to enforce the type of the transaction + to a [tx_rollup%deposit]. It must be used both in [ticket_diffs_of_operations] + to account for the ticket deposited and in [apply] to retrieve the ticket + when applying the transaction to a tx_rollup. *) +val get_deposit_parameters : + ('a, 'comparable) Script_typed_ir.ty -> 'a -> deposit_parameters tzresult diff --git a/src/proto_alpha/lib_protocol/tx_rollup_repr.ml b/src/proto_alpha/lib_protocol/tx_rollup_repr.ml index defb74482f..2623a090fe 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_repr.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_repr.ml @@ -155,14 +155,6 @@ end let deposit_entrypoint = Entrypoint_repr.of_string_strict_exn "deposit" -type deposit_parameters = { - contents : Script_repr.node; - ty : Script_repr.node; - ticketer : Script_repr.node; - amount : Tx_rollup_l2_qty.t; - destination : Tx_rollup_l2_address.Indexable.value; -} - module Set = Set.Make (struct type t = tx_rollup diff --git a/src/proto_alpha/lib_protocol/tx_rollup_repr.mli b/src/proto_alpha/lib_protocol/tx_rollup_repr.mli index fc0934aefd..9fa632d7b5 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_repr.mli +++ b/src/proto_alpha/lib_protocol/tx_rollup_repr.mli @@ -68,32 +68,6 @@ module Index : Storage_description.INDEX with type t = t into a transaction rollup. *) val deposit_entrypoint : Entrypoint_repr.t -(* TODO: https://gitlab.com/tezos/tezos/-/issues/2035 - Refactor this away when proper internal operations are introduced. - Currently, this type is needed because when emitting an internal - operation, the Michelson interpreter serialize the parameters, - loosing their type information in the process. Se we need to inject - said type (the [ty] field) in the Micheline produced by the - interpreter, so that the transaction rollup can use it to hash the - ticket. Without this serialization/deserialization step, type - information are preserved, and there is no more need to instrument - the parameters of the deposit entrypoint. *) - -(** The parameters expected to be supplied to the deposit entrypoint. - - These arguments will not be supplied as-is, but encoded using - Micheline. - - The function {!Script_ir_translator.parse_tx_rollup_deposit_parameters} - should be used to extract a [deposit_parameters] from a Micheline value. *) -type deposit_parameters = { - contents : Script_repr.node; - ty : Script_repr.node; - ticketer : Script_repr.node; - amount : Tx_rollup_l2_qty.t; - destination : Tx_rollup_l2_address.Indexable.value; -} - module Set : Set.S with type elt = tx_rollup module Map : Map.S with type key = tx_rollup diff --git a/tezt/_regressions/tx_node_configuration.out b/tezt/_regressions/tx_node_configuration.out deleted file mode 100644 index 1b902dfb32..0000000000 --- a/tezt/_regressions/tx_node_configuration.out +++ /dev/null @@ -1,2 +0,0 @@ -tezt/_regressions/tx_node_configuration.out -{"data-dir":"<variable>","client-keys":"tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx","rollup-id":"txr1YNMEtkj5Vkqsbdmt7xaxBTMRZjzS96UAi","block-hash":"<variable>","rpc-port":"<variable>"} diff --git a/tezt/self_tests/test-basic.t b/tezt/self_tests/test-basic.t index a2e6593d82..32921079f7 100644 --- a/tezt/self_tests/test-basic.t +++ b/tezt/self_tests/test-basic.t @@ -4,5 +4,5 @@ Run a test that should fail: Starting test: Failing test [error] Always failing test [FAILURE] (1/1, 1 failed) Failing test - Try again with: ./main.exe --verbose --file test_retry.ml --test 'Failing test' + Try again with: ./main.exe --verbose --file test_retry.ml --title 'Failing test' [1] From 7ec877cbb5e44c89a8a278479225caace85d85ae Mon Sep 17 00:00:00 2001 From: Nicolas Ayache <nicolas.ayache@nomadic-labs.com> Date: Wed, 16 Mar 2022 11:56:57 +0100 Subject: [PATCH 075/100] Proto/Michelson-Plugin: move script back from translator to ir. Because we will use them in internal originations. (This reverts and elaborates commit d0b4766c3da681e4dc50d5e143a5a1c2a27ccc5a.) --- src/proto_alpha/lib_plugin/plugin.ml | 19 ++++---- src/proto_alpha/lib_protocol/apply.ml | 2 +- .../lib_protocol/contract_services.ml | 4 +- src/proto_alpha/lib_protocol/main.ml | 2 +- .../lib_protocol/script_interpreter.ml | 26 +++++------ .../lib_protocol/script_ir_translator.ml | 43 +++++++------------ .../lib_protocol/script_ir_translator.mli | 17 +------- .../lib_protocol/script_typed_ir.ml | 20 ++++++++- .../lib_protocol/script_typed_ir.mli | 15 ++++++- .../lib_protocol/test/helpers/block.ml | 2 +- .../integration/michelson/test_sapling.ml | 2 +- .../michelson/test_script_cache.ml | 6 +-- .../michelson/test_ticket_manager.ml | 3 +- .../ticket_balance_migration_for_j.ml | 2 +- .../lib_protocol/ticket_operations_diff.ml | 24 ++++++----- 15 files changed, 98 insertions(+), 89 deletions(-) diff --git a/src/proto_alpha/lib_plugin/plugin.ml b/src/proto_alpha/lib_plugin/plugin.ml index 5d5426addd..7a06931b2e 100644 --- a/src/proto_alpha/lib_plugin/plugin.ml +++ b/src/proto_alpha/lib_plugin/plugin.ml @@ -2537,15 +2537,16 @@ module RPC = struct >>=? fun (storage, _) -> let script = Script_ir_translator.Ex_script - { - code; - arg_type; - storage_type; - views; - entrypoints; - code_size; - storage; - } + (Script + { + code; + arg_type; + storage_type; + views; + entrypoints; + code_size; + storage; + }) in let (size, cost) = Script_ir_translator.script_size script in Gas.consume ctxt cost >>?= fun _ctxt -> return @@ size) ; diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index 5cd883a31a..86de918830 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -1157,7 +1157,7 @@ let apply_origination ~consume_deserialization_gas ~ctxt ~script ~internal ~legacy:false ~allow_forged_in_storage:internal script - >>=? fun (Ex_script parsed_script, ctxt) -> + >>=? fun (Ex_script (Script parsed_script), ctxt) -> let views_result = Script_ir_translator.typecheck_views ctxt diff --git a/src/proto_alpha/lib_protocol/contract_services.ml b/src/proto_alpha/lib_protocol/contract_services.ml index 042fdc86d6..784582bc51 100644 --- a/src/proto_alpha/lib_protocol/contract_services.ml +++ b/src/proto_alpha/lib_protocol/contract_services.ml @@ -243,7 +243,7 @@ module S = struct ~allow_forged_in_storage:true script >|= fun tzresult -> - tzresult >>? fun (Ex_script script, ctxt) -> + tzresult >>? fun (Ex_script (Script script), ctxt) -> Script_ir_translator.get_single_sapling_state ctxt script.storage_type @@ -454,7 +454,7 @@ let[@coq_axiom_with_reason "gadt"] register () = let ctxt = Gas.set_unlimited ctxt in let open Script_ir_translator in parse_script ctxt ~legacy:true ~allow_forged_in_storage:true script - >>=? fun (Ex_script script, ctxt) -> + >>=? fun (Ex_script (Script script), ctxt) -> Script_ir_translator.collect_lazy_storage ctxt script.storage_type diff --git a/src/proto_alpha/lib_protocol/main.ml b/src/proto_alpha/lib_protocol/main.ml index da097a31fc..3301fa3761 100644 --- a/src/proto_alpha/lib_protocol/main.ml +++ b/src/proto_alpha/lib_protocol/main.ml @@ -742,7 +742,7 @@ let init ctxt block_header = ~legacy:true ~allow_forged_in_storage script - >>=? fun (Ex_script parsed_script, ctxt) -> + >>=? fun (Ex_script (Script parsed_script), ctxt) -> Script_ir_translator.extract_lazy_storage_diff ctxt Optimized diff --git a/src/proto_alpha/lib_protocol/script_interpreter.ml b/src/proto_alpha/lib_protocol/script_interpreter.ml index 70fb97fca2..772de7148c 100644 --- a/src/proto_alpha/lib_protocol/script_interpreter.ml +++ b/src/proto_alpha/lib_protocol/script_interpreter.ml @@ -1055,8 +1055,8 @@ and step : type a s b t r f. (a, s, b, t, r, f) step_type = ~allow_forged_in_storage:true ctxt script - >>=? fun (Ex_script {storage; storage_type; views; _}, ctxt) - -> + >>=? fun ( Ex_script (Script {storage; storage_type; views; _}), + ctxt ) -> Gas.consume ctxt (Interp_costs.view_get name views) >>?= fun ctxt -> match Script_map.get name views with @@ -1759,15 +1759,16 @@ let execute_any_arg logger ctxt mode step_constants ~entrypoint ~internal ~allow_forged_in_storage:true | Some ex_script -> return (ex_script, ctxt)) >>=? fun ( Ex_script - { - code_size; - code; - arg_type; - storage = old_storage; - storage_type; - entrypoints; - views; - }, + (Script + { + code_size; + code; + arg_type; + storage = old_storage; + storage_type; + entrypoints; + views; + }), ctxt ) -> Gas_monad.run ctxt @@ -1819,7 +1820,8 @@ let execute_any_arg logger ctxt mode step_constants ~entrypoint ~internal in let script = Ex_script - {code_size; code; arg_type; storage; storage_type; entrypoints; views} + (Script + {code_size; code; arg_type; storage; storage_type; entrypoints; views}) in Ticket_scanner.type_has_tickets ctxt arg_type >>?= fun (arg_type_has_tickets, ctxt) -> diff --git a/src/proto_alpha/lib_protocol/script_ir_translator.ml b/src/proto_alpha/lib_protocol/script_ir_translator.ml index 5e1d452a1b..dcef099c0b 100644 --- a/src/proto_alpha/lib_protocol/script_ir_translator.ml +++ b/src/proto_alpha/lib_protocol/script_ir_translator.ml @@ -1801,23 +1801,7 @@ type ('arg, 'storage) code = } -> ('arg, 'storage) code -type ex_script = - | Ex_script : { - code : - (('arg, 'storage) pair, (operation boxed_list, 'storage) pair) lambda; - arg_type : ('arg, _) ty; - storage : 'storage; - storage_type : ('storage, _) ty; - views : view_map; - entrypoints : 'arg entrypoints; - code_size : Cache_memory_helpers.sint; - (* This is an over-approximation of the value size in memory, in - bytes, of the contract's static part, that is its source - code. This includes the code of the contract as well as the code - of the views. The storage size is not taken into account by this - field as it has a dynamic size. *) - } - -> ex_script +type ex_script = Ex_script : ('a, 'c) Script_typed_ir.script -> ex_script type ex_code = Ex_code : ('a, 'c) code -> ex_code @@ -5490,7 +5474,8 @@ let[@coq_axiom_with_reason "gadt"] parse_script : ~storage >|=? fun (storage, ctxt) -> ( Ex_script - {code_size; code; arg_type; storage; storage_type; views; entrypoints}, + (Script + {code_size; code; arg_type; storage; storage_type; views; entrypoints}), ctxt ) let typecheck_code : @@ -5868,7 +5853,8 @@ and[@coq_axiom_with_reason "gadt"] unparse_code ctxt ~stack_depth mode code = (* TODO: https://gitlab.com/tezos/tezos/-/issues/1688 Refactor the sharing part of unparse_script and create_contract *) let unparse_script ctxt mode - (Ex_script {code; arg_type; storage; storage_type; entrypoints; views; _}) = + (Ex_script + (Script {code; arg_type; storage; storage_type; entrypoints; views; _})) = let (Lam (_, original_code)) = code in Gas.consume ctxt Unparse_costs.unparse_script >>?= fun ctxt -> unparse_code ctxt ~stack_depth:0 mode original_code >>=? fun (code, ctxt) -> @@ -6467,15 +6453,16 @@ let[@coq_axiom_with_reason "gadt"] get_single_sapling_state ctxt ty x = *) let script_size (Ex_script - { - code_size; - code = _; - arg_type = _; - storage; - storage_type; - entrypoints = _; - views = _; - }) = + (Script + { + code_size; + code = _; + arg_type = _; + storage; + storage_type; + entrypoints = _; + views = _; + })) = let (nodes, storage_size) = Script_typed_ir_size.value_size storage_type storage in diff --git a/src/proto_alpha/lib_protocol/script_ir_translator.mli b/src/proto_alpha/lib_protocol/script_ir_translator.mli index 975e66406b..61bc87b46f 100644 --- a/src/proto_alpha/lib_protocol/script_ir_translator.mli +++ b/src/proto_alpha/lib_protocol/script_ir_translator.mli @@ -82,22 +82,7 @@ type ex_parameter_ty_and_entrypoints = type ex_stack_ty = | Ex_stack_ty : ('a, 's) Script_typed_ir.stack_ty -> ex_stack_ty -type ex_script = - | Ex_script : { - code : - ( ('arg, 'storage) Script_typed_ir.pair, - ( Script_typed_ir.operation Script_typed_ir.boxed_list, - 'storage ) - Script_typed_ir.pair ) - Script_typed_ir.lambda; - arg_type : ('arg, _) Script_typed_ir.ty; - storage : 'storage; - storage_type : ('storage, _) Script_typed_ir.ty; - views : Script_typed_ir.view_map; - entrypoints : 'arg Script_typed_ir.entrypoints; - code_size : Cache_memory_helpers.sint; - } - -> ex_script +type ex_script = Ex_script : ('a, 'b) Script_typed_ir.script -> ex_script type toplevel = { code_field : Script.node; diff --git a/src/proto_alpha/lib_protocol/script_typed_ir.ml b/src/proto_alpha/lib_protocol/script_typed_ir.ml index 8734cd25e5..2c984edbd1 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir.ml +++ b/src/proto_alpha/lib_protocol/script_typed_ir.ml @@ -468,8 +468,26 @@ and 'arg nested_entrypoints = let no_entrypoints = {name = None; nested = Entrypoints_None} +type ('arg, 'storage) script = + | Script : { + code : + (('arg, 'storage) pair, (operation boxed_list, 'storage) pair) lambda; + arg_type : ('arg, _) ty; + storage : 'storage; + storage_type : ('storage, _) ty; + views : view_map; + entrypoints : 'arg entrypoints; + code_size : Cache_memory_helpers.sint; + (* This is an over-approximation of the value size in memory, in + bytes, of the contract's static part, that is its source + code. This includes the code of the contract as well as the code + of the views. The storage size is not taken into account by this + field as it has a dynamic size. *) + } + -> ('arg, 'storage) script + (* ---- Instructions --------------------------------------------------------*) -type ('before_top, 'before, 'result_top, 'result) kinstr = +and ('before_top, 'before, 'result_top, 'result) kinstr = (* Stack ----- diff --git a/src/proto_alpha/lib_protocol/script_typed_ir.mli b/src/proto_alpha/lib_protocol/script_typed_ir.mli index 102d0a36b4..3550305444 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir.mli +++ b/src/proto_alpha/lib_protocol/script_typed_ir.mli @@ -335,6 +335,19 @@ and 'arg nested_entrypoints = (** [no_entrypoints] is [{name = None; nested = Entrypoints_None}] *) val no_entrypoints : _ entrypoints +type ('arg, 'storage) script = + | Script : { + code : + (('arg, 'storage) pair, (operation boxed_list, 'storage) pair) lambda; + arg_type : ('arg, _) ty; + storage : 'storage; + storage_type : ('storage, _) ty; + views : view_map; + entrypoints : 'arg entrypoints; + code_size : Cache_memory_helpers.sint; + } + -> ('arg, 'storage) script + (* ---- Instructions --------------------------------------------------------*) (* @@ -436,7 +449,7 @@ val no_entrypoints : _ entrypoints [1]: http://www.complang.tuwien.ac.at/projects/interpreters.html *) -type ('before_top, 'before, 'result_top, 'result) kinstr = +and ('before_top, 'before, 'result_top, 'result) kinstr = (* Stack ----- diff --git a/src/proto_alpha/lib_protocol/test/helpers/block.ml b/src/proto_alpha/lib_protocol/test/helpers/block.ml index d6452b8edf..9cdf37f75e 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/block.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/block.ml @@ -324,7 +324,7 @@ let initial_alpha_context ?(commitments = []) constants ~legacy:true ~allow_forged_in_storage script - >>=? fun (Ex_script parsed_script, ctxt) -> + >>=? fun (Ex_script (Script parsed_script), ctxt) -> Script_ir_translator.extract_lazy_storage_diff ctxt Optimized diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_sapling.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_sapling.ml index 4e9918de5d..53da0dca16 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_sapling.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_sapling.ml @@ -951,7 +951,7 @@ module Interpreter_tests = struct ~allow_forged_in_storage:true script >>= wrap - >>=? fun (Ex_script script, ctxt) -> + >>=? fun (Ex_script (Script script), ctxt) -> Script_ir_translator.get_single_sapling_state ctxt script.storage_type diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_script_cache.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_script_cache.ml index cd0edb8952..9b4125d93b 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_script_cache.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_script_cache.ml @@ -206,17 +206,17 @@ let test_update_modifies_cached_contract () = originate_contract "contracts/int-store.tz" "36" src block baker >>=? fun (addr, block) -> ( make_block block @! fun ctxt -> - find ctxt addr >>=? fun (ctxt, identifier, script, Ex_script ir) -> + find ctxt addr >>=? fun (ctxt, identifier, script, Ex_script (Script ir)) -> match ir.storage_type with | Int_t -> let storage' = Script_int.(add ir.storage (Script_int.of_int 1)) in let cached_contract' = - (script, Ex_script {ir with storage = storage'}) + (script, Ex_script (Script {ir with storage = storage'})) in Script_cache.update ctxt identifier cached_contract' 1 |> Environment.wrap_tzresult >>?= fun ctxt -> - find ctxt addr >>=? fun (_, _, _, Ex_script ir') -> + find ctxt addr >>=? fun (_, _, _, Ex_script (Script ir')) -> let storage = value_as_int ir'.storage_type ir'.storage in fail_unless (Script_int.compare storage storage' = 0) diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_manager.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_manager.ml index 5a79954135..252e84bb0d 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_manager.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_manager.ml @@ -84,7 +84,8 @@ let ticket_balance_of_storage ctxt contract = match script with | None -> return ([], ctxt) | Some script -> - let* (Script_ir_translator.Ex_script {storage; storage_type; _}, ctxt) = + let* ( Script_ir_translator.Ex_script (Script {storage; storage_type; _}), + ctxt ) = wrap (Script_ir_translator.parse_script ctxt diff --git a/src/proto_alpha/lib_protocol/ticket_balance_migration_for_j.ml b/src/proto_alpha/lib_protocol/ticket_balance_migration_for_j.ml index 096d4efe96..e595f431b2 100644 --- a/src/proto_alpha/lib_protocol/ticket_balance_migration_for_j.ml +++ b/src/proto_alpha/lib_protocol/ticket_balance_migration_for_j.ml @@ -48,7 +48,7 @@ let update_contract_tickets ctxt contract = ~allow_forged_in_storage:true script >>=? fun (ex_script, ctxt) -> - let (Ex_script {storage_type; storage; _}) = ex_script in + let (Ex_script (Script {storage_type; storage; _})) = ex_script in Ticket_scanner.type_has_tickets ctxt storage_type >>?= fun (has_tickets, ctxt) -> Ticket_scanner.tickets_of_value diff --git a/src/proto_alpha/lib_protocol/ticket_operations_diff.ml b/src/proto_alpha/lib_protocol/ticket_operations_diff.ml index ef51b6aec2..9c9f69f3cb 100644 --- a/src/proto_alpha/lib_protocol/ticket_operations_diff.ml +++ b/src/proto_alpha/lib_protocol/ticket_operations_diff.ml @@ -187,8 +187,9 @@ let tickets_of_transaction ctxt ~destination ~entrypoint ~location match script_opt with | None -> fail (Failed_to_get_script destination) | Some script -> return (script, ctxt)) - >>=? fun (Script_ir_translator.Ex_script {arg_type; entrypoints; _}, ctxt) - -> + >>=? fun ( Script_ir_translator.Ex_script + (Script {arg_type; entrypoints; _}), + ctxt ) -> (* Find the entrypoint type for the given entrypoint. *) Gas_monad.run ctxt @@ -235,15 +236,16 @@ let tickets_of_origination ctxt ~preorigination script = ~allow_forged_in_storage:true script >>=? fun ( Script_ir_translator.Ex_script - { - storage; - storage_type; - code = _; - arg_type = _; - views = _; - entrypoints = _; - code_size = _; - }, + (Script + { + storage; + storage_type; + code = _; + arg_type = _; + views = _; + entrypoints = _; + code_size = _; + }), ctxt ) -> (* Extract any tickets from the storage. Note that if the type of the contract storage does not contain tickets, storage is not scanned. *) From 3fc29aa1e2bc8679573eed316ab0e48889dbe5d1 Mon Sep 17 00:00:00 2001 From: Nicolas Ayache <nicolas.ayache@nomadic-labs.com> Date: Mon, 7 Mar 2022 11:44:30 +0100 Subject: [PATCH 076/100] Proto/Michelson: enrich the origination application with a parsed script. --- src/proto_alpha/lib_protocol/apply.ml | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index 86de918830..0c2c22c17e 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -1140,8 +1140,8 @@ let apply_transaction_to_tx_rollup ~ctxt ~parameters_ty ~parameters ~amount return (ctxt, result, []) else fail (Script_tc_errors.No_such_entrypoint entrypoint) -let apply_origination ~consume_deserialization_gas ~ctxt ~script ~internal - ~preorigination ~delegate ~source ~credit ~before_operation = +let apply_origination ~consume_deserialization_gas ~ctxt ~parsed_script ~script + ~internal ~preorigination ~delegate ~source ~credit ~before_operation = Script.force_decode_in_context ~consume_deserialization_gas ctxt @@ -1152,11 +1152,14 @@ let apply_origination ~consume_deserialization_gas ~ctxt ~script ~internal ctxt script.Script.code >>?= fun (unparsed_code, ctxt) -> - Script_ir_translator.parse_script - ctxt - ~legacy:false - ~allow_forged_in_storage:internal - script + (match parsed_script with + | None -> + Script_ir_translator.parse_script + ctxt + ~legacy:false + ~allow_forged_in_storage:internal + script + | Some parsed_script -> return (parsed_script, ctxt)) >>=? fun (Ex_script (Script parsed_script), ctxt) -> let views_result = Script_ir_translator.typecheck_views @@ -1339,6 +1342,7 @@ let apply_internal_manager_operation_content : apply_origination ~consume_deserialization_gas ~ctxt + ~parsed_script:None ~script ~internal ~preorigination @@ -1554,6 +1558,7 @@ let apply_external_manager_operation_content : apply_origination ~consume_deserialization_gas ~ctxt + ~parsed_script:None ~script ~internal ~preorigination From 846b5ad2e79f89cb5d17d483ea43a77264e04573 Mon Sep 17 00:00:00 2001 From: Nicolas Ayache <nicolas.ayache@nomadic-labs.com> Date: Wed, 16 Feb 2022 09:47:55 +0100 Subject: [PATCH 077/100] Proto/Michelson: enrich create_contract with a lambda. That will be used to create a typed script. --- src/proto_alpha/lib_protocol/script_interpreter.ml | 12 ++---------- .../lib_protocol/script_interpreter_defs.ml | 3 ++- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/proto_alpha/lib_protocol/script_interpreter.ml b/src/proto_alpha/lib_protocol/script_interpreter.ml index 772de7148c..9fdafa8e94 100644 --- a/src/proto_alpha/lib_protocol/script_interpreter.ml +++ b/src/proto_alpha/lib_protocol/script_interpreter.ml @@ -1138,15 +1138,7 @@ and step : type a s b t r f. (a, s, b, t, r, f) step_type = (EmptyCell, EmptyCell)))))) | Tx_rollup _ -> (return_none [@ocaml.tailcall]) ctxt) | ICreate_contract - { - storage_type; - arg_type; - lambda = Lam (_, code); - views; - entrypoints; - k; - _; - } -> + {storage_type; arg_type; lambda; views; entrypoints; k; _} -> (* Removed the instruction's arguments manager, spendable and delegatable *) let delegate = accu in let (credit, (init, stack)) = stack in @@ -1155,7 +1147,7 @@ and step : type a s b t r f. (a, s, b, t, r, f) step_type = gas storage_type arg_type - code + lambda views entrypoints delegate diff --git a/src/proto_alpha/lib_protocol/script_interpreter_defs.ml b/src/proto_alpha/lib_protocol/script_interpreter_defs.ml index 7dbabb9d1c..4020110058 100644 --- a/src/proto_alpha/lib_protocol/script_interpreter_defs.ml +++ b/src/proto_alpha/lib_protocol/script_interpreter_defs.ml @@ -591,7 +591,7 @@ let transfer (ctxt, sc) gas amount location parameters_ty parameters destination (* TODO: https://gitlab.com/tezos/tezos/-/issues/1688 Refactor the sharing part of unparse_script and create_contract *) -let create_contract (ctxt, sc) gas storage_type param_type code views +let create_contract (ctxt, sc) gas storage_type param_type lambda views entrypoints delegate credit init = let ctxt = update_context gas ctxt in let loc = Micheline.dummy_location in @@ -613,6 +613,7 @@ let create_contract (ctxt, sc) gas storage_type param_type code views :: views in let views = Script_map.fold view views [] |> List.rev in + let (Lam (_, code)) = lambda in let code = strip_locations (Seq From 09da053058bc560ea57464450cdc9745b3ff602a Mon Sep 17 00:00:00 2001 From: Nicolas Ayache <nicolas.ayache@nomadic-labs.com> Date: Mon, 7 Feb 2022 13:51:54 +0100 Subject: [PATCH 078/100] Proto/Michelson: enrich the origination internal operation. The fields are already available when creating a contract, and this allows other modules, like ticket_operations_diff, to use it without parsing it yet again. Does not compile (tests to adapt). --- src/proto_alpha/lib_protocol/apply.ml | 11 +++++-- src/proto_alpha/lib_protocol/apply_results.ml | 2 +- .../lib_protocol/script_interpreter_defs.ml | 31 +++++++++++++------ .../lib_protocol/script_typed_ir.ml | 6 ++-- .../lib_protocol/script_typed_ir.mli | 6 ++-- .../lib_protocol/ticket_operations_diff.ml | 3 +- 6 files changed, 41 insertions(+), 18 deletions(-) diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index 0c2c22c17e..a83521b4a0 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -1159,7 +1159,8 @@ let apply_origination ~consume_deserialization_gas ~ctxt ~parsed_script ~script ~legacy:false ~allow_forged_in_storage:internal script - | Some parsed_script -> return (parsed_script, ctxt)) + | Some parsed_script -> + return (Script_ir_translator.Ex_script parsed_script, ctxt)) >>=? fun (Ex_script (Script parsed_script), ctxt) -> let views_result = Script_ir_translator.typecheck_views @@ -1338,11 +1339,15 @@ let apply_internal_manager_operation_content : ~payer ~dst_rollup:dst ~since:before_operation - | Origination {delegate; script; preorigination; credit} -> + | Origination + { + origination = {delegate; script; preorigination; credit}; + script = parsed_script; + } -> apply_origination ~consume_deserialization_gas ~ctxt - ~parsed_script:None + ~parsed_script:(Some parsed_script) ~script ~internal ~preorigination diff --git a/src/proto_alpha/lib_protocol/apply_results.ml b/src/proto_alpha/lib_protocol/apply_results.ml index 92c1f4a586..5df0091349 100644 --- a/src/proto_alpha/lib_protocol/apply_results.ml +++ b/src/proto_alpha/lib_protocol/apply_results.ml @@ -81,7 +81,7 @@ let contents_of_internal_operation (type kind) let operation : kind internal_manager_operation = match operation with | Transaction {transaction; _} -> Transaction transaction - | Origination origination -> Origination origination + | Origination {origination; _} -> Origination origination | Delegation delegate -> Delegation delegate in {source; operation; nonce} diff --git a/src/proto_alpha/lib_protocol/script_interpreter_defs.ml b/src/proto_alpha/lib_protocol/script_interpreter_defs.ml index 4020110058..9b6c80346e 100644 --- a/src/proto_alpha/lib_protocol/script_interpreter_defs.ml +++ b/src/proto_alpha/lib_protocol/script_interpreter_defs.ml @@ -612,7 +612,7 @@ let create_contract (ctxt, sc) gas storage_type param_type lambda views [] ) :: views in - let views = Script_map.fold view views [] |> List.rev in + let view_list = Script_map.fold view views [] |> List.rev in let (Lam (_, code)) = lambda in let code = strip_locations @@ -623,7 +623,7 @@ let create_contract (ctxt, sc) gas storage_type param_type lambda views Prim (loc, K_storage, [unparsed_storage_type], []); Prim (loc, K_code, [code], []); ] - @ views )) + @ view_list )) in collect_lazy_storage ctxt storage_type init >>?= fun (to_duplicate, ctxt) -> let to_update = no_lazy_storage_id in @@ -640,16 +640,29 @@ let create_contract (ctxt, sc) gas storage_type param_type lambda views Gas.consume ctxt (Script.strip_locations_cost storage) >>?= fun ctxt -> let storage = strip_locations storage in Contract.fresh_contract_from_current_nonce ctxt >>?= fun (ctxt, contract) -> - let operation = - Origination + let origination = + { + credit; + delegate; + preorigination = Some contract; + script = + {code = Script.lazy_expr code; storage = Script.lazy_expr storage}; + } + in + Script_ir_translator.code_size ctxt lambda views >>?= fun (code_size, ctxt) -> + let script = + Script { - credit; - delegate; - preorigination = Some contract; - script = - {code = Script.lazy_expr code; storage = Script.lazy_expr storage}; + code = lambda; + arg_type = param_type; + storage = init; + storage_type; + views; + entrypoints; + code_size; } in + let operation = Origination {origination; script} in fresh_internal_nonce ctxt >>?= fun (ctxt, nonce) -> let piop = Internal_operation {source = sc.self; operation; nonce} in let res = {piop; lazy_storage_diff} in diff --git a/src/proto_alpha/lib_protocol/script_typed_ir.ml b/src/proto_alpha/lib_protocol/script_typed_ir.ml index 2c984edbd1..142fb615d9 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir.ml +++ b/src/proto_alpha/lib_protocol/script_typed_ir.ml @@ -1395,8 +1395,10 @@ and 'kind manager_operation = parameters : 'a; } -> Kind.transaction manager_operation - | Origination : - Alpha_context.origination + | Origination : { + origination : Alpha_context.origination; + script : ('arg, 'storage) script; + } -> Kind.origination manager_operation | Delegation : Signature.Public_key_hash.t option diff --git a/src/proto_alpha/lib_protocol/script_typed_ir.mli b/src/proto_alpha/lib_protocol/script_typed_ir.mli index 3550305444..5ca8b7364c 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir.mli +++ b/src/proto_alpha/lib_protocol/script_typed_ir.mli @@ -1533,8 +1533,10 @@ and 'kind manager_operation = parameters : 'a; } -> Kind.transaction manager_operation - | Origination : - Alpha_context.origination + | Origination : { + origination : Alpha_context.origination; + script : ('arg, 'storage) script; + } -> Kind.origination manager_operation | Delegation : Signature.Public_key_hash.t option diff --git a/src/proto_alpha/lib_protocol/ticket_operations_diff.ml b/src/proto_alpha/lib_protocol/ticket_operations_diff.ml index 9c9f69f3cb..b3a766fbdd 100644 --- a/src/proto_alpha/lib_protocol/ticket_operations_diff.ml +++ b/src/proto_alpha/lib_protocol/ticket_operations_diff.ml @@ -306,7 +306,8 @@ let tickets_of_operation ctxt }, ctxt ) else return (None, ctxt) - | Origination {delegate = _; script; credit = _; preorigination} -> + | Origination + {origination = {delegate = _; script; credit = _; preorigination}; _} -> tickets_of_origination ctxt ~preorigination script | Delegation _ -> return (None, ctxt) From 80ae35f765725cf2dc23ec8ac4fbdab7117f9fe0 Mon Sep 17 00:00:00 2001 From: Nicolas Ayache <nicolas.ayache@nomadic-labs.com> Date: Mon, 7 Mar 2022 14:17:01 +0100 Subject: [PATCH 079/100] Proto/Tests: typed scripts in originations. --- .../michelson/test_ticket_accounting.ml | 56 ++++++++++++------- .../michelson/test_ticket_operations_diff.ml | 22 ++++++-- 2 files changed, 54 insertions(+), 24 deletions(-) diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_accounting.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_accounting.ml index 507558a491..4a62229dc0 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_accounting.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_accounting.ml @@ -330,20 +330,36 @@ let originate_script block ~script ~storage ~src ~baker ~forges_tickets = in Incremental.finalize_block incr >|=? fun block -> (destination, script, block) -let origination_operation ~src ~script ~orig_contract = - Internal_operation - { - source = src; - operation = - Origination - { - delegate = None; - script; - credit = Tez.one; - preorigination = Some orig_contract; - }; - nonce = 1; - } +let origination_operation ctxt ~src ~script ~orig_contract = + let open Lwt_tzresult_syntax in + let* (Script_ir_translator.Ex_script parsed_script, ctxt) = + wrap + @@ Script_ir_translator.parse_script + ctxt + ~legacy:true + ~allow_forged_in_storage:true + script + in + let operation = + Internal_operation + { + source = src; + operation = + Origination + { + origination = + { + delegate = None; + script; + credit = Tez.one; + preorigination = Some orig_contract; + }; + script = parsed_script; + }; + nonce = 1; + } + in + return (operation, ctxt) let originate block ~src ~baker ~script ~storage ~forges_tickets = let open Lwt_tzresult_syntax in @@ -1140,8 +1156,8 @@ let test_update_invalid_origination () = ~forges_tickets:true in let ctxt = Incremental.alpha_ctxt incr in - let operation = - origination_operation ~src ~orig_contract:destination ~script + let* (operation, ctxt) = + origination_operation ctxt ~src ~orig_contract:destination ~script in assert_fail_with ~loc:__LOC__ @@ -1184,8 +1200,8 @@ let test_update_valid_origination () = let* (_, ctxt) = wrap @@ Ticket_balance.adjust_balance ctxt red_self_token_hash ~delta:Z.one in - let operation = - origination_operation ~src:self ~orig_contract:originated ~script + let* (operation, ctxt) = + origination_operation ctxt ~src:self ~orig_contract:originated ~script in let* (_, ctxt) = let* (ticket_diffs, ctxt) = @@ -1236,8 +1252,8 @@ let test_update_self_origination () = ~owner:(Destination.Contract originated) red_token in - let operation = - origination_operation ~src:self ~orig_contract:originated ~script + let* (operation, ctxt) = + origination_operation ctxt ~src:self ~orig_contract:originated ~script in let* (_, ctxt) = wrap diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_operations_diff.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_operations_diff.ml index 36db4c333d..0fbb2dfe89 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_operations_diff.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_operations_diff.ml @@ -231,6 +231,15 @@ let origination_operation block ~src ~baker ~script ~storage ~forges_tickets = let* incr = Incremental.begin_construction ~policy:Block.(By_account baker) block in + let ctxt = Incremental.alpha_ctxt incr in + let* (Script_ir_translator.Ex_script parsed_script, ctxt) = + wrap + @@ Script_ir_translator.parse_script + ctxt + ~legacy:true + ~allow_forged_in_storage:true + script + in let operation = Script_typed_ir.Internal_operation { @@ -238,14 +247,19 @@ let origination_operation block ~src ~baker ~script ~storage ~forges_tickets = operation = Origination { - delegate = None; - script; - credit = Tez.one; - preorigination = Some orig_contract; + origination = + { + delegate = None; + script; + credit = Tez.one; + preorigination = Some orig_contract; + }; + script = parsed_script; }; nonce = 1; } in + let incr = Incremental.set_alpha_ctxt incr ctxt in return (orig_contract, operation, incr) let delegation_operation ~src = From 8ec3785766790652aa747bd38b0efd330d82d244 Mon Sep 17 00:00:00 2001 From: Nicolas Ayache <nicolas.ayache@nomadic-labs.com> Date: Wed, 16 Mar 2022 17:58:40 +0100 Subject: [PATCH 080/100] Proto/Michelson: optimize tickets_of_origination. --- .../lib_protocol/ticket_operations_diff.ml | 40 +++++++------------ 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/src/proto_alpha/lib_protocol/ticket_operations_diff.ml b/src/proto_alpha/lib_protocol/ticket_operations_diff.ml index b3a766fbdd..04a4135579 100644 --- a/src/proto_alpha/lib_protocol/ticket_operations_diff.ml +++ b/src/proto_alpha/lib_protocol/ticket_operations_diff.ml @@ -220,33 +220,20 @@ let tickets_of_transaction ctxt ~destination ~entrypoint ~location return (Some {destination = Contract destination; tickets}, ctxt) (** Extract tickets of an origination operation by scanning the storage. *) -let tickets_of_origination ctxt ~preorigination script = +let tickets_of_origination ctxt ~preorigination + (Script_typed_ir.Script + { + storage_type; + storage; + code = _; + arg_type = _; + views = _; + entrypoints = _; + code_size = _; + }) = match preorigination with | None -> fail Contract_not_originated | Some contract -> - (* TODO: #2351 - Avoid having to parse the script here. - We're not able to rely on caching due to issues with lazy storage. - After internal operations are in place we should be able to use the - typed script directly. - *) - Script_ir_translator.parse_script - ctxt - ~legacy:true - ~allow_forged_in_storage:true - script - >>=? fun ( Script_ir_translator.Ex_script - (Script - { - storage; - storage_type; - code = _; - arg_type = _; - views = _; - entrypoints = _; - code_size = _; - }), - ctxt ) -> (* Extract any tickets from the storage. Note that if the type of the contract storage does not contain tickets, storage is not scanned. *) Ticket_scanner.type_has_tickets ctxt storage_type @@ -307,7 +294,10 @@ let tickets_of_operation ctxt ctxt ) else return (None, ctxt) | Origination - {origination = {delegate = _; script; credit = _; preorigination}; _} -> + { + origination = {delegate = _; script = _; credit = _; preorigination}; + script; + } -> tickets_of_origination ctxt ~preorigination script | Delegation _ -> return (None, ctxt) From 59e94ced4737310da47ce922d4ba15c956cf1b7f Mon Sep 17 00:00:00 2001 From: Nicolas Ayache <nicolas.ayache@nomadic-labs.com> Date: Mon, 7 Mar 2022 14:41:54 +0100 Subject: [PATCH 081/100] Proto/Michelson: remove preoriginations from external originations. Because this is what actually happens: preoriginations are only set for internal operations. --- .../lib_client/client_proto_context.ml | 8 +----- .../lib_client/operation_result.ml | 3 +- src/proto_alpha/lib_plugin/plugin.ml | 8 +----- .../lib_protocol/alpha_context.mli | 1 - src/proto_alpha/lib_protocol/apply.ml | 28 +++++++++---------- src/proto_alpha/lib_protocol/apply_results.ml | 16 ++--------- .../lib_protocol/operation_repr.ml | 15 ++-------- .../lib_protocol/operation_repr.mli | 1 - .../lib_protocol/script_interpreter_defs.ml | 5 ++-- .../lib_protocol/script_typed_ir.ml | 1 + .../lib_protocol/script_typed_ir.mli | 1 + .../lib_protocol/test/helpers/op.ml | 6 ++-- .../lib_protocol/test/helpers/op.mli | 1 - .../michelson/test_ticket_accounting.ml | 9 ++---- .../michelson/test_ticket_operations_diff.ml | 9 ++---- .../lib_protocol/ticket_operations_diff.ml | 24 ++++++---------- 16 files changed, 42 insertions(+), 94 deletions(-) diff --git a/src/proto_alpha/lib_client/client_proto_context.ml b/src/proto_alpha/lib_client/client_proto_context.ml index 6054f27455..c2d7e384b8 100644 --- a/src/proto_alpha/lib_client/client_proto_context.ml +++ b/src/proto_alpha/lib_client/client_proto_context.ml @@ -360,13 +360,7 @@ let build_origination_operation ?fee ?gas_limit ?storage_limit ~initial_storage >>=? fun {Michelson_v1_parser.expanded = storage; _} -> let code = Script.lazy_expr code and storage = Script.lazy_expr storage in let origination = - Origination - { - delegate; - script = {code; storage}; - credit = balance; - preorigination = None; - } + Origination {delegate; script = {code; storage}; credit = balance} in return (Injection.prepare_manager_operation diff --git a/src/proto_alpha/lib_client/operation_result.ml b/src/proto_alpha/lib_client/operation_result.ml index 61d8654bbe..e815e7589e 100644 --- a/src/proto_alpha/lib_client/operation_result.ml +++ b/src/proto_alpha/lib_client/operation_result.ml @@ -58,8 +58,7 @@ let pp_manager_operation_content (type kind) source internal pp_result ppf expr) ; pp_result ppf result ; Format.fprintf ppf "@]" - | Origination {delegate; credit; script = {code; storage}; preorigination = _} - -> + | Origination {delegate; credit; script = {code; storage}} -> Format.fprintf ppf "@[<v 2>%s:@,From: %a@,Credit: %s%a" diff --git a/src/proto_alpha/lib_plugin/plugin.ml b/src/proto_alpha/lib_plugin/plugin.ml index 7a06931b2e..1f24ac2e8b 100644 --- a/src/proto_alpha/lib_plugin/plugin.ml +++ b/src/proto_alpha/lib_plugin/plugin.ml @@ -3202,13 +3202,7 @@ module RPC = struct ~storage_limit [ Manager - (Origination - { - delegate = delegatePubKey; - script; - credit = balance; - preorigination = None; - }); + (Origination {delegate = delegatePubKey; script; credit = balance}); ] let delegation ctxt block ~branch ~source ?sourcePubKey ~counter ~fee diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index 96cf61a346..65c1ca14ba 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -2688,7 +2688,6 @@ type origination = { delegate : Signature.Public_key_hash.t option; script : Script.t; credit : Tez.tez; - preorigination : Contract.t option; } type 'kind operation = { diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index a83521b4a0..eb8b7e23d7 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -1141,7 +1141,7 @@ let apply_transaction_to_tx_rollup ~ctxt ~parameters_ty ~parameters ~amount else fail (Script_tc_errors.No_such_entrypoint entrypoint) let apply_origination ~consume_deserialization_gas ~ctxt ~parsed_script ~script - ~internal ~preorigination ~delegate ~source ~credit ~before_operation = + ~internal ~preoriginate ~delegate ~source ~credit ~before_operation = Script.force_decode_in_context ~consume_deserialization_gas ctxt @@ -1203,15 +1203,7 @@ let apply_origination ~consume_deserialization_gas ~ctxt ~parsed_script ~script Gas.consume ctxt (Script.strip_locations_cost code) >>?= fun ctxt -> let code = Script.lazy_expr (Micheline.strip_locations code) in let script = {Script.code; storage} in - (match preorigination with - | Some contract -> - assert internal ; - (* The preorigination field is only used to early return the address of - an originated contract in Michelson. - It cannot come from the outside. *) - ok (ctxt, contract) - | None -> Contract.fresh_contract_from_current_nonce ctxt) - >>?= fun (ctxt, contract) -> + preoriginate ctxt >>?= fun (contract, ctxt) -> Contract.raw_originate ctxt ~prepaid_bootstrap_storage:false @@ -1341,7 +1333,8 @@ let apply_internal_manager_operation_content : ~since:before_operation | Origination { - origination = {delegate; script; preorigination; credit}; + origination = {delegate; script; credit}; + preorigination; script = parsed_script; } -> apply_origination @@ -1350,7 +1343,7 @@ let apply_internal_manager_operation_content : ~parsed_script:(Some parsed_script) ~script ~internal - ~preorigination + ~preoriginate:(fun ctxt -> ok (preorigination, ctxt)) ~delegate ~source ~credit @@ -1559,14 +1552,21 @@ let apply_external_manager_operation_content : } in return (ctxt, result, [op]) - | Origination {delegate; script; preorigination; credit} -> + | Origination {delegate; script; credit} -> + (* The preorigination field is only used to early return the address of + an originated contract in Michelson. + It cannot come from the outside. *) + let preoriginate ctxt = + Contract.fresh_contract_from_current_nonce ctxt + >|? fun (ctxt, contract) -> (contract, ctxt) + in apply_origination ~consume_deserialization_gas ~ctxt ~parsed_script:None ~script ~internal - ~preorigination + ~preoriginate ~delegate ~source ~credit diff --git a/src/proto_alpha/lib_protocol/apply_results.ml b/src/proto_alpha/lib_protocol/apply_results.ml index 5df0091349..623b28c9ef 100644 --- a/src/proto_alpha/lib_protocol/apply_results.ml +++ b/src/proto_alpha/lib_protocol/apply_results.ml @@ -926,22 +926,10 @@ module Internal_result = struct (function Manager (Origination _ as op) -> Some op | _ -> None); proj = (function - | Origination - { - credit; - delegate; - script; - preorigination = - _ - (* the hash is only used internally - when originating from smart - contracts, don't serialize it *); - _; - } -> - (credit, delegate, script)); + | Origination {credit; delegate; script} -> (credit, delegate, script)); inj = (fun (credit, delegate, script) -> - Origination {credit; delegate; script; preorigination = None}); + Origination {credit; delegate; script}); } let[@coq_axiom_with_reason "gadt"] delegation_case = diff --git a/src/proto_alpha/lib_protocol/operation_repr.ml b/src/proto_alpha/lib_protocol/operation_repr.ml index 24cf9a9377..6fc002bf5a 100644 --- a/src/proto_alpha/lib_protocol/operation_repr.ml +++ b/src/proto_alpha/lib_protocol/operation_repr.ml @@ -207,7 +207,6 @@ type origination = { delegate : Signature.Public_key_hash.t option; script : Script_repr.t; credit : Tez_repr.tez; - preorigination : Contract_repr.t option; } type 'kind operation = { @@ -547,21 +546,11 @@ module Encoding = struct (function Manager (Origination _ as op) -> Some op | _ -> None); proj = (function - | Origination - { - credit; - delegate; - script; - preorigination = - _ - (* the hash is only used internally - when originating from smart - contracts, don't serialize it *); - } -> + | Origination {credit; delegate; script} -> (credit, delegate, script)); inj = (fun (credit, delegate, script) -> - Origination {credit; delegate; script; preorigination = None}); + Origination {credit; delegate; script}); } let delegation_tag = 3 diff --git a/src/proto_alpha/lib_protocol/operation_repr.mli b/src/proto_alpha/lib_protocol/operation_repr.mli index 19d787633d..6eab5947cb 100644 --- a/src/proto_alpha/lib_protocol/operation_repr.mli +++ b/src/proto_alpha/lib_protocol/operation_repr.mli @@ -188,7 +188,6 @@ type origination = { delegate : Signature.Public_key_hash.t option; script : Script_repr.t; credit : Tez_repr.tez; - preorigination : Contract_repr.t option; } (** An [operation] contains the operation header information in [shell] diff --git a/src/proto_alpha/lib_protocol/script_interpreter_defs.ml b/src/proto_alpha/lib_protocol/script_interpreter_defs.ml index 9b6c80346e..6a19b41433 100644 --- a/src/proto_alpha/lib_protocol/script_interpreter_defs.ml +++ b/src/proto_alpha/lib_protocol/script_interpreter_defs.ml @@ -644,7 +644,6 @@ let create_contract (ctxt, sc) gas storage_type param_type lambda views { credit; delegate; - preorigination = Some contract; script = {code = Script.lazy_expr code; storage = Script.lazy_expr storage}; } @@ -662,7 +661,9 @@ let create_contract (ctxt, sc) gas storage_type param_type lambda views code_size; } in - let operation = Origination {origination; script} in + let operation = + Origination {origination; preorigination = contract; script} + in fresh_internal_nonce ctxt >>?= fun (ctxt, nonce) -> let piop = Internal_operation {source = sc.self; operation; nonce} in let res = {piop; lazy_storage_diff} in diff --git a/src/proto_alpha/lib_protocol/script_typed_ir.ml b/src/proto_alpha/lib_protocol/script_typed_ir.ml index 142fb615d9..ce2142c54a 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir.ml +++ b/src/proto_alpha/lib_protocol/script_typed_ir.ml @@ -1397,6 +1397,7 @@ and 'kind manager_operation = -> Kind.transaction manager_operation | Origination : { origination : Alpha_context.origination; + preorigination : Contract.t; script : ('arg, 'storage) script; } -> Kind.origination manager_operation diff --git a/src/proto_alpha/lib_protocol/script_typed_ir.mli b/src/proto_alpha/lib_protocol/script_typed_ir.mli index 5ca8b7364c..2caa8f1894 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir.mli +++ b/src/proto_alpha/lib_protocol/script_typed_ir.mli @@ -1535,6 +1535,7 @@ and 'kind manager_operation = -> Kind.transaction manager_operation | Origination : { origination : Alpha_context.origination; + preorigination : Contract.t; script : ('arg, 'storage) script; } -> Kind.origination manager_operation diff --git a/src/proto_alpha/lib_protocol/test/helpers/op.ml b/src/proto_alpha/lib_protocol/test/helpers/op.ml index 8dcfec4200..b7971edb3c 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/op.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/op.ml @@ -310,15 +310,15 @@ let originated_contract op = exception Impossible -let contract_origination ?counter ?delegate ~script ?(preorigination = None) - ?public_key ?credit ?fee ?gas_limit ?storage_limit ctxt source = +let contract_origination ?counter ?delegate ~script ?public_key ?credit ?fee + ?gas_limit ?storage_limit ctxt source = Context.Contract.manager ctxt source >>=? fun account -> let default_credit = Tez.of_mutez @@ Int64.of_int 1000001 in let default_credit = WithExceptions.Option.to_exn ~none:Impossible default_credit in let credit = Option.value ~default:default_credit credit in - let operation = Origination {delegate; script; credit; preorigination} in + let operation = Origination {delegate; script; credit} in manager_operation ?counter ?public_key diff --git a/src/proto_alpha/lib_protocol/test/helpers/op.mli b/src/proto_alpha/lib_protocol/test/helpers/op.mli index 267f857997..f5ce022582 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/op.mli +++ b/src/proto_alpha/lib_protocol/test/helpers/op.mli @@ -119,7 +119,6 @@ val contract_origination : ?counter:Z.t -> ?delegate:public_key_hash -> script:Script.t -> - ?preorigination:Contract.contract option -> ?public_key:public_key -> ?credit:Tez.tez -> ?fee:Tez.tez -> diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_accounting.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_accounting.ml index 4a62229dc0..dd0c488484 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_accounting.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_accounting.ml @@ -347,13 +347,8 @@ let origination_operation ctxt ~src ~script ~orig_contract = operation = Origination { - origination = - { - delegate = None; - script; - credit = Tez.one; - preorigination = Some orig_contract; - }; + origination = {delegate = None; script; credit = Tez.one}; + preorigination = orig_contract; script = parsed_script; }; nonce = 1; diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_operations_diff.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_operations_diff.ml index 0fbb2dfe89..ccab867615 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_operations_diff.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_operations_diff.ml @@ -247,13 +247,8 @@ let origination_operation block ~src ~baker ~script ~storage ~forges_tickets = operation = Origination { - origination = - { - delegate = None; - script; - credit = Tez.one; - preorigination = Some orig_contract; - }; + origination = {delegate = None; script; credit = Tez.one}; + preorigination = orig_contract; script = parsed_script; }; nonce = 1; diff --git a/src/proto_alpha/lib_protocol/ticket_operations_diff.ml b/src/proto_alpha/lib_protocol/ticket_operations_diff.ml index 04a4135579..8109390b6e 100644 --- a/src/proto_alpha/lib_protocol/ticket_operations_diff.ml +++ b/src/proto_alpha/lib_protocol/ticket_operations_diff.ml @@ -231,20 +231,13 @@ let tickets_of_origination ctxt ~preorigination entrypoints = _; code_size = _; }) = - match preorigination with - | None -> fail Contract_not_originated - | Some contract -> - (* Extract any tickets from the storage. Note that if the type of the - contract storage does not contain tickets, storage is not scanned. *) - Ticket_scanner.type_has_tickets ctxt storage_type - >>?= fun (has_tickets, ctxt) -> - Ticket_scanner.tickets_of_value - ctxt - ~include_lazy:true - has_tickets - storage - >|=? fun (tickets, ctxt) -> - (Some {tickets; destination = Destination.Contract contract}, ctxt) + (* Extract any tickets from the storage. Note that if the type of the contract + storage does not contain tickets, storage is not scanned. *) + Ticket_scanner.type_has_tickets ctxt storage_type + >>?= fun (has_tickets, ctxt) -> + Ticket_scanner.tickets_of_value ctxt ~include_lazy:true has_tickets storage + >|=? fun (tickets, ctxt) -> + (Some {tickets; destination = Destination.Contract preorigination}, ctxt) let tickets_of_operation ctxt (Script_typed_ir.Internal_operation {source = _; operation; nonce = _}) = @@ -295,7 +288,8 @@ let tickets_of_operation ctxt else return (None, ctxt) | Origination { - origination = {delegate = _; script = _; credit = _; preorigination}; + origination = {delegate = _; script = _; credit = _}; + preorigination; script; } -> tickets_of_origination ctxt ~preorigination script From 45bc4609aa0b9e1a39db2b026545fdd0a49c4893 Mon Sep 17 00:00:00 2001 From: Nicolas Ayache <nicolas.ayache@nomadic-labs.com> Date: Tue, 15 Mar 2022 16:29:42 +0100 Subject: [PATCH 082/100] Tests: update regression tests gas. --- ...t_originate_contract_from_contract_transfer.out | 8 ++++---- ...nit-(Some \"KT1Mjjcb6tmSsLm7Cb3.c3984fbc14.out" | 14 +++++++------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/tests_python/tests_alpha/_regtest_outputs/test_contract.TestOriginateContractFromContract::test_originate_contract_from_contract_transfer.out b/tests_python/tests_alpha/_regtest_outputs/test_contract.TestOriginateContractFromContract::test_originate_contract_from_contract_transfer.out index c3db7f879e..42bff6c96f 100644 --- a/tests_python/tests_alpha/_regtest_outputs/test_contract.TestOriginateContractFromContract::test_originate_contract_from_contract_transfer.out +++ b/tests_python/tests_alpha/_regtest_outputs/test_contract.TestOriginateContractFromContract::test_originate_contract_from_contract_transfer.out @@ -1,7 +1,7 @@ tests_alpha/test_contract.py::TestOriginateContractFromContract::test_originate_contract_from_contract_transfer Node is bootstrapped. -Estimated gas: 3477.065 units (will add 100 for safety) +Estimated gas: 3470.319 units (will add 100 for safety) Estimated storage: 295 bytes added (will add 20 for safety) Operation successfully injected in the node. Operation hash is '[BLOCK_HASH]' @@ -14,7 +14,7 @@ This sequence of operations was run: From: [CONTRACT_HASH] Fee to the baker: ꜩ0.000607 Expected counter: [EXPECTED_COUNTER] - Gas limit: 3578 + Gas limit: 3571 Storage limit: 315 bytes Balance updates: [CONTRACT_HASH] ... -ꜩ0.000607 @@ -26,7 +26,7 @@ This sequence of operations was run: This transaction was successfully applied Updated storage: Unit Storage size: 93 bytes - Consumed gas: 2069.085 + Consumed gas: 2066.252 Internal operations: Origination: From: [CONTRACT_HASH] @@ -40,7 +40,7 @@ This sequence of operations was run: [CONTRACT_HASH] Storage size: 38 bytes Paid storage size diff: 38 bytes - Consumed gas: 1407.980 + Consumed gas: 1404.067 Balance updates: [CONTRACT_HASH] ... -ꜩ0.0095 storage fees ........................... +ꜩ0.0095 diff --git "a/tests_python/tests_alpha/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[create_contract.tz-None-Unit-(Some \"KT1Mjjcb6tmSsLm7Cb3.c3984fbc14.out" "b/tests_python/tests_alpha/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[create_contract.tz-None-Unit-(Some \"KT1Mjjcb6tmSsLm7Cb3.c3984fbc14.out" index 4b98d5ac09..edceebcd11 100644 --- "a/tests_python/tests_alpha/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[create_contract.tz-None-Unit-(Some \"KT1Mjjcb6tmSsLm7Cb3.c3984fbc14.out" +++ "b/tests_python/tests_alpha/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[create_contract.tz-None-Unit-(Some \"KT1Mjjcb6tmSsLm7Cb3.c3984fbc14.out" @@ -26,24 +26,24 @@ emitted operations [ None 50000 Unit ] - - location: 13 (remaining gas: 1039983.548 units remaining) + - location: 13 (remaining gas: 1039982.468 units remaining) [ 0x011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600000002d08603000000001c02000000170500036c0501036c050202000000080317053d036d034200000002030b "KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm" ] - - location: 25 (remaining gas: 1039983.533 units remaining) + - location: 25 (remaining gas: 1039982.453 units remaining) [ "KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm" ] - - location: 27 (remaining gas: 1039983.518 units remaining) + - location: 27 (remaining gas: 1039982.438 units remaining) [ (Some "KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm") ] - - location: 28 (remaining gas: 1039983.503 units remaining) + - location: 28 (remaining gas: 1039982.423 units remaining) [ {} (Some "KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm") ] - - location: 25 (remaining gas: 1039983.473 units remaining) + - location: 25 (remaining gas: 1039982.393 units remaining) [ 0x011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600000002d08603000000001c02000000170500036c0501036c050202000000080317053d036d034200000002030b {} (Some "KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm") ] - - location: 30 (remaining gas: 1039983.458 units remaining) + - location: 30 (remaining gas: 1039982.378 units remaining) [ { 0x011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600000002d08603000000001c02000000170500036c0501036c050202000000080317053d036d034200000002030b } (Some "KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm") ] - - location: 31 (remaining gas: 1039983.443 units remaining) + - location: 31 (remaining gas: 1039982.363 units remaining) [ (Pair { 0x011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600000002d08603000000001c02000000170500036c0501036c050202000000080317053d036d034200000002030b } (Some "KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm")) ] From c3865a9609babf49de055c5f5d3a49ffb029923d Mon Sep 17 00:00:00 2001 From: Nicolas Ayache <nicolas.ayache@nomadic-labs.com> Date: Thu, 17 Mar 2022 14:44:03 +0100 Subject: [PATCH 083/100] Proto/Michelson: simplify using the preorigination. --- src/proto_alpha/lib_protocol/apply.ml | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index eb8b7e23d7..77cdfc947d 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -1141,7 +1141,7 @@ let apply_transaction_to_tx_rollup ~ctxt ~parameters_ty ~parameters ~amount else fail (Script_tc_errors.No_such_entrypoint entrypoint) let apply_origination ~consume_deserialization_gas ~ctxt ~parsed_script ~script - ~internal ~preoriginate ~delegate ~source ~credit ~before_operation = + ~internal ~contract ~delegate ~source ~credit ~before_operation = Script.force_decode_in_context ~consume_deserialization_gas ctxt @@ -1203,7 +1203,6 @@ let apply_origination ~consume_deserialization_gas ~ctxt ~parsed_script ~script Gas.consume ctxt (Script.strip_locations_cost code) >>?= fun ctxt -> let code = Script.lazy_expr (Micheline.strip_locations code) in let script = {Script.code; storage} in - preoriginate ctxt >>?= fun (contract, ctxt) -> Contract.raw_originate ctxt ~prepaid_bootstrap_storage:false @@ -1334,7 +1333,7 @@ let apply_internal_manager_operation_content : | Origination { origination = {delegate; script; credit}; - preorigination; + preorigination = contract; script = parsed_script; } -> apply_origination @@ -1343,7 +1342,7 @@ let apply_internal_manager_operation_content : ~parsed_script:(Some parsed_script) ~script ~internal - ~preoriginate:(fun ctxt -> ok (preorigination, ctxt)) + ~contract ~delegate ~source ~credit @@ -1553,20 +1552,18 @@ let apply_external_manager_operation_content : in return (ctxt, result, [op]) | Origination {delegate; script; credit} -> - (* The preorigination field is only used to early return the address of - an originated contract in Michelson. + (* The contract is only used to early return the address of an originated + contract in Michelson. It cannot come from the outside. *) - let preoriginate ctxt = - Contract.fresh_contract_from_current_nonce ctxt - >|? fun (ctxt, contract) -> (contract, ctxt) - in + Contract.fresh_contract_from_current_nonce ctxt + >>?= fun (ctxt, contract) -> apply_origination ~consume_deserialization_gas ~ctxt ~parsed_script:None ~script ~internal - ~preoriginate + ~contract ~delegate ~source ~credit From fa9d3b2085a3f905fed02af4e797e88a57a0c74d Mon Sep 17 00:00:00 2001 From: Nicolas Ayache <nicolas.ayache@nomadic-labs.com> Date: Fri, 18 Mar 2022 09:44:15 +0100 Subject: [PATCH 084/100] Proto/Michelson: fix a comment. --- src/proto_alpha/lib_protocol/apply.ml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index 77cdfc947d..d03767acb8 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -921,8 +921,8 @@ let apply_transaction_to_smart_contract ~ctxt ~source ~contract ~amount ~entrypoint ~before_operation ~payer ~chain_id ~mode ~internal ~script_ir ~script ~parameter ~cache_key ~balance_updates ~allocated_destination_contract = - (* Token.transfer which is being called above already loads this - value into the Irmin cache, so no need to burn gas for it. *) + (* Token.transfer which is being called before already loads this value into + the Irmin cache, so no need to burn gas for it. *) Contract.get_balance ctxt contract >>=? fun balance -> let now = Script_timestamp.now ctxt in let level = From a0141367d397b5d3e9ebd034fd8ce62ea106cfc9 Mon Sep 17 00:00:00 2001 From: Romain Bardou <romain@nomadic-labs.com> Date: Mon, 14 Mar 2022 14:09:53 +0100 Subject: [PATCH 085/100] Tezt: add missing ?hooks arguments --- tezt/lib/process.ml | 22 +++++++++++++--------- tezt/lib/process.mli | 3 +++ 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/tezt/lib/process.ml b/tezt/lib/process.ml index fe55526b96..689c33138c 100644 --- a/tezt/lib/process.ml +++ b/tezt/lib/process.ml @@ -457,9 +457,9 @@ let check ?(expect_failure = false) process = reason = Some reason; }) -let run ?log_status_on_exit ?name ?color ?env ?expect_failure command arguments - = - spawn ?log_status_on_exit ?name ?color ?env command arguments +let run ?log_status_on_exit ?name ?color ?env ?hooks ?expect_failure command + arguments = + spawn ?log_status_on_exit ?name ?color ?env ?hooks command arguments |> check ?expect_failure let clean_up () = @@ -492,14 +492,18 @@ let check_and_read_stdout = check_and_read ~channel_getter:stdout let check_and_read_stderr = check_and_read ~channel_getter:stderr -let run_and_read_stdout ?log_status_on_exit ?name ?color ?env ?expect_failure - command arguments = - let process = spawn ?log_status_on_exit ?name ?color ?env command arguments in +let run_and_read_stdout ?log_status_on_exit ?name ?color ?env ?hooks + ?expect_failure command arguments = + let process = + spawn ?log_status_on_exit ?name ?color ?env ?hooks command arguments + in check_and_read_stdout ?expect_failure process -let run_and_read_stderr ?log_status_on_exit ?name ?color ?env ?expect_failure - command arguments = - let process = spawn ?log_status_on_exit ?name ?color ?env command arguments in +let run_and_read_stderr ?log_status_on_exit ?name ?color ?env ?hooks + ?expect_failure command arguments = + let process = + spawn ?log_status_on_exit ?name ?color ?env ?hooks command arguments + in check_and_read_stdout ?expect_failure process let check_error ?exit_code ?msg process = diff --git a/tezt/lib/process.mli b/tezt/lib/process.mli index c841e99dc2..437a02f6e1 100644 --- a/tezt/lib/process.mli +++ b/tezt/lib/process.mli @@ -149,6 +149,7 @@ val run : ?name:string -> ?color:Log.Color.t -> ?env:string Base.String_map.t -> + ?hooks:hooks -> ?expect_failure:bool -> string -> string list -> @@ -178,6 +179,7 @@ val run_and_read_stdout : ?name:string -> ?color:Log.Color.t -> ?env:string Base.String_map.t -> + ?hooks:hooks -> ?expect_failure:bool -> string -> string list -> @@ -192,6 +194,7 @@ val run_and_read_stderr : ?name:string -> ?color:Log.Color.t -> ?env:string Base.String_map.t -> + ?hooks:hooks -> ?expect_failure:bool -> string -> string list -> From 6cab9d0b96f2900314d7a5344053a4d820c184b1 Mon Sep 17 00:00:00 2001 From: Arvid Jakobsson <arvid.jakobsson@nomadic-labs.com> Date: Sat, 19 Mar 2022 11:55:54 +0100 Subject: [PATCH 086/100] CI/Tezt: run self tests in the CI --- .gitlab/ci/test/tezt.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.gitlab/ci/test/tezt.yml b/.gitlab/ci/test/tezt.yml index 7cb950cef5..57cbbc4889 100644 --- a/.gitlab/ci/test/tezt.yml +++ b/.gitlab/ci/test/tezt.yml @@ -49,6 +49,15 @@ tezt:build-long: script: - dune build @tezt/long_tests/check +# Tests tezt itself +tezt:self_tests: + extends: + - .build_template + - .rules_template__development + stage: test + script: + - dune runtest tezt/self_tests/ + # Note: if you reactivate this test and if you keep it manual, put it in the "manual" stage. # #tezt:manual:migration: From 08eaf0304ccf561fcd3d31aea85dd76b4115e16d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Proust?= <code@bnwr.net> Date: Thu, 17 Mar 2022 09:03:11 +0100 Subject: [PATCH 087/100] Manifest: support opam's description field --- manifest/manifest.ml | 22 +++++++++++++++++++--- manifest/manifest.mli | 3 +++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/manifest/manifest.ml b/manifest/manifest.ml index 9efe0bf617..cca728ef0b 100644 --- a/manifest/manifest.ml +++ b/manifest/manifest.ml @@ -446,6 +446,7 @@ module Opam = struct build : build_instruction list; synopsis : string; url : url option; + description : string option; } let pp fmt @@ -461,6 +462,7 @@ module Opam = struct build; synopsis; url; + description; } = let (depopts, depends) = List.partition (fun dep -> dep.optional) depends in let (depopts, conflicts) = @@ -643,7 +645,8 @@ module Opam = struct conflicts ; pp_line "%a" (pp_list ~prefix:"build: " pp_build_instruction) build ; pp_line "synopsis: %a" pp_string synopsis ; - Option.iter pp_url url + Option.iter pp_url url ; + Option.iter (pp_line "description: %a" pp_string) description end (*****************************************************************************) @@ -723,6 +726,7 @@ module Target = struct static : bool; static_cclibs : string list; synopsis : string option; + description : string option; warnings : string option; wrapped : bool; node_wrapper_flags : string list; @@ -858,6 +862,7 @@ module Target = struct ?static:bool -> ?static_cclibs:string list -> ?synopsis:string -> + ?description:string -> ?time_measurement_ppx:bool -> ?warnings:string -> ?wrapped:bool -> @@ -875,8 +880,8 @@ module Target = struct ?(nopervasives = false) ?(nostdlib = false) ?ocaml ?opam ?(opaque = false) ?(opens = []) ?(preprocess = []) ?(preprocessor_deps = []) ?(private_modules = []) ?(opam_only_deps = []) ?release ?static - ?static_cclibs ?synopsis ?(time_measurement_ppx = false) ?warnings - ?(wrapped = true) ?(cram = false) ?action ~path names = + ?static_cclibs ?synopsis ?description ?(time_measurement_ppx = false) + ?warnings ?(wrapped = true) ?(cram = false) ?action ~path names = let conflicts = List.filter_map Fun.id conflicts in let deps = List.filter_map Fun.id deps in let opam_only_deps = List.filter_map Fun.id opam_only_deps in @@ -1055,6 +1060,7 @@ module Target = struct static; static_cclibs; synopsis; + description; node_wrapper_flags; warnings; wrapped; @@ -1664,6 +1670,15 @@ let generate_opam ?release this_package (internals : Target.internal list) : String.concat " " @@ List.flatten @@ map internals @@ fun internal -> Option.to_list internal.synopsis in + let description = + let descriptions = + List.filter_map Fun.id @@ map internals + @@ fun internal -> internal.description + in + match descriptions with + | [] -> None + | descriptions -> Some (String.concat "\n\n" descriptions) + in let build = let build : Opam.build_instruction = { @@ -1707,6 +1722,7 @@ let generate_opam ?release this_package (internals : Target.internal list) : build; synopsis; url = Option.map (fun {url; _} -> url) release; + description; } let generate_opam_files () = diff --git a/manifest/manifest.mli b/manifest/manifest.mli index 98ee6fe7e6..964bbab136 100644 --- a/manifest/manifest.mli +++ b/manifest/manifest.mli @@ -547,6 +547,8 @@ val pps : ?args:string list -> target -> preprocessor - [synopsis]: short description for the [.opam] file. + - [description]: long description for the [.opam] file. + - [warnings]: the argument passed to the -w flag when building. - [wrapped]: if [false], add the [(wrapped false)] stanza in the [dune] file. @@ -588,6 +590,7 @@ type 'a maker = ?static:bool -> ?static_cclibs:string list -> ?synopsis:string -> + ?description:string -> ?time_measurement_ppx:bool -> ?warnings:string -> ?wrapped:bool -> From 25263121206a82048bf7a433b844e8d7b4c3fc72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Proust?= <code@bnwr.net> Date: Wed, 16 Mar 2022 16:38:18 +0100 Subject: [PATCH 088/100] Proto-env: simplify build, keep only one opam package --- docs/shell/the_big_picture.rst | 2 +- manifest/main.ml | 80 ++++++++----------- src/lib_protocol_compiler/dune | 28 +++---- .../dune_protocol.template.v0 | 4 +- .../dune_protocol.template.v1 | 4 +- .../tezos-protocol-compiler.opam | 3 +- src/lib_protocol_environment/dune | 4 +- src/lib_protocol_environment/s_packer/dune | 8 +- src/lib_protocol_environment/sigs/dune | 4 +- .../sigs/stdlib_compat/dune | 2 +- src/lib_protocol_environment/sigs/v0.dune.inc | 2 +- src/lib_protocol_environment/sigs/v1.dune.inc | 2 +- src/lib_protocol_environment/sigs/v2.dune.inc | 2 +- src/lib_protocol_environment/sigs/v3.dune.inc | 2 +- src/lib_protocol_environment/sigs/v4.dune.inc | 2 +- src/lib_protocol_environment/sigs/v5.dune.inc | 2 +- src/lib_protocol_environment/structs/dune | 2 +- .../structs/v0.dune.inc | 2 +- .../structs/v1.dune.inc | 2 +- .../structs/v2.dune.inc | 2 +- .../structs/v3.dune.inc | 2 +- .../structs/v4.dune.inc | 2 +- .../structs/v5.dune.inc | 2 +- .../tezos-protocol-environment-packer.opam | 18 ----- .../tezos-protocol-environment-sigs.opam | 19 ----- .../tezos-protocol-environment-structs.opam | 23 ------ .../tezos-protocol-environment.opam | 21 ++++- src/proto_000_Ps9mPmXa/lib_protocol/dune.inc | 4 +- src/proto_001_PtCJ7pwo/lib_protocol/dune.inc | 4 +- src/proto_002_PsYLVpVv/lib_protocol/dune.inc | 4 +- src/proto_003_PsddFKi3/lib_protocol/dune.inc | 4 +- src/proto_004_Pt24m4xi/lib_protocol/dune.inc | 4 +- src/proto_005_PsBABY5H/lib_protocol/dune.inc | 4 +- src/proto_005_PsBabyM1/lib_protocol/dune.inc | 4 +- src/proto_006_PsCARTHA/lib_protocol/dune.inc | 4 +- src/proto_007_PsDELPH1/lib_protocol/dune.inc | 4 +- src/proto_008_PtEdo2Zk/lib_protocol/dune.inc | 4 +- src/proto_008_PtEdoTez/lib_protocol/dune.inc | 4 +- src/proto_009_PsFLoren/lib_protocol/dune.inc | 4 +- src/proto_010_PtGRANAD/lib_protocol/dune.inc | 4 +- src/proto_011_PtHangz2/lib_protocol/dune.inc | 4 +- src/proto_012_Psithaca/lib_protocol/dune.inc | 4 +- src/proto_alpha/lib_protocol/dune.inc | 4 +- src/proto_demo_counter/lib_protocol/dune.inc | 4 +- src/proto_demo_noops/lib_protocol/dune.inc | 4 +- src/proto_genesis/lib_protocol/dune.inc | 4 +- .../lib_protocol/dune.inc | 4 +- 47 files changed, 130 insertions(+), 196 deletions(-) delete mode 100644 src/lib_protocol_environment/tezos-protocol-environment-packer.opam delete mode 100644 src/lib_protocol_environment/tezos-protocol-environment-sigs.opam delete mode 100644 src/lib_protocol_environment/tezos-protocol-environment-structs.opam diff --git a/docs/shell/the_big_picture.rst b/docs/shell/the_big_picture.rst index 2d9aa82a0c..11814dc868 100644 --- a/docs/shell/the_big_picture.rst +++ b/docs/shell/the_big_picture.rst @@ -178,7 +178,7 @@ economic protocol, as a form of static sandboxing. It also generates a functorized version of the protocol, to make the execution of the protocol in an alternative environment possible. - - :package:`tezos-protocol-environment-sigs` contains the modules + - :package:`tezos-protocol-environment` contains the modules that are available to the economic protocol. A review of this sandbox is available :doc:`here <../developer/protocol_environment>`. These modules include a stripped-down standard library, and interfaces diff --git a/manifest/main.ml b/manifest/main.ml index 13c520ab47..561a2c0c60 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -1495,37 +1495,20 @@ let _tezos_sapling_ctypes_gen = ~modules: ["rustzcash_ctypes_gen"; "rustzcash_ctypes_bindings"; "gen_runtime_js"] -let tezos_protocol_environment_packer = - public_lib - "tezos-protocol-environment-packer" - ~path:"src/lib_protocol_environment/s_packer" - ~opam:"src/lib_protocol_environment/tezos-protocol-environment-packer" - ~ocaml:V.(at_least "4.03") - ~synopsis:"Tezos: sigs/structs packer for economic protocol environment" - ~modules:[] - let tezos_protocol_environment_sigs_stdlib_compat = public_lib - "tezos-protocol-environment-sigs.stdlib-compat" - ~internal_name:"tezos_protocol_environment_sigs_stdlib_compat" + "tezos-protocol-environment.sigs.stdlib-compat" ~path:"src/lib_protocol_environment/sigs/stdlib_compat" - ~opam:"src/lib_protocol_environment/tezos-protocol-environment-sigs" + ~opam:"src/lib_protocol_environment/tezos-protocol-environment" ~modules_without_implementation:["V_all"; "V2"; "V3"; "V4"] let tezos_protocol_environment_sigs = public_lib - "tezos-protocol-environment-sigs" + "tezos-protocol-environment.sigs" ~path:"src/lib_protocol_environment/sigs" - ~opam:"src/lib_protocol_environment/tezos-protocol-environment-sigs" + ~opam:"src/lib_protocol_environment/tezos-protocol-environment" ~ocaml:V.(at_least "4.12") - ~synopsis:"Tezos: restricted typing environment for the economic protocols" ~deps:[tezos_protocol_environment_sigs_stdlib_compat] - ~opam_only_deps: - [ - (* Build dependency but not for the (library) itself, - it's from one of the .inc files. *) - tezos_protocol_environment_packer; - ] ~nopervasives:true ~nostdlib:true ~modules:["V0"; "V1"; "V2"; "V3"; "V4"; "V5"] @@ -1542,10 +1525,9 @@ let tezos_protocol_environment_sigs = let tezos_protocol_environment_structs = public_lib - "tezos-protocol-environment-structs" + "tezos-protocol-environment.structs" ~path:"src/lib_protocol_environment/structs" - ~opam:"src/lib_protocol_environment/tezos-protocol-environment-structs" - ~synopsis:"Tezos: restricted typing environment for the economic protocols" + ~opam:"src/lib_protocol_environment/tezos-protocol-environment" ~deps: [ tezos_stdlib; @@ -1554,12 +1536,6 @@ let tezos_protocol_environment_structs = data_encoding; bls12_381_legacy; ] - ~opam_only_deps: - [ - (* Build dependency but not for the (library) itself, - it's from one of the .inc files. *) - tezos_protocol_environment_packer; - ] ~modules:["V0"; "V1"; "V2"; "V3"; "V4"; "V5"] ~dune: Dune. @@ -1576,9 +1552,19 @@ let tezos_protocol_environment = public_lib "tezos-protocol-environment" ~path:"src/lib_protocol_environment" - ~synopsis: - "Tezos: custom economic-protocols environment implementation for \ - `tezos-client` and testing" + ~synopsis:"Interface layer between the protocols and the shell" + ~description: + {|The protocol-environment is a two-sided component sitting between the shell and +the protocols. + +On one side, it provides a restricted typing environment to compile the +protocols against. This is a series of modules which replace the standard +library of OCaml. These modules purposefully omit many functionalities, thus +preventing the protocols from, say, directly writing to disk. + +On the other side, it provides the shell with specific call-sites in the +protocols. These are the only entry-points into the otherwise black-box +protocols.|} ~deps: [ zarith; @@ -1680,29 +1666,29 @@ let tezos_protocol_compiler_registerer = S "%{dep:.tezos_protocol_registerer.objs/byte/tezos_protocol_registerer__Registerer.cmi}"; S - "%{lib:tezos-protocol-environment-sigs.stdlib-compat:tezos_protocol_environment_sigs_stdlib_compat.cmi}"; + "%{lib:tezos-protocol-environment.sigs.stdlib-compat:tezos_protocol_environment_sigs_stdlib_compat.cmi}"; S - "%{lib:tezos-protocol-environment-sigs.stdlib-compat:tezos_protocol_environment_sigs_stdlib_compat__V_all.cmi}"; + "%{lib:tezos-protocol-environment.sigs.stdlib-compat:tezos_protocol_environment_sigs_stdlib_compat__V_all.cmi}"; S - "%{lib:tezos-protocol-environment-sigs.stdlib-compat:tezos_protocol_environment_sigs_stdlib_compat__V2.cmi}"; + "%{lib:tezos-protocol-environment.sigs.stdlib-compat:tezos_protocol_environment_sigs_stdlib_compat__V2.cmi}"; S - "%{lib:tezos-protocol-environment-sigs.stdlib-compat:tezos_protocol_environment_sigs_stdlib_compat__V3.cmi}"; + "%{lib:tezos-protocol-environment.sigs.stdlib-compat:tezos_protocol_environment_sigs_stdlib_compat__V3.cmi}"; S - "%{lib:tezos-protocol-environment-sigs.stdlib-compat:tezos_protocol_environment_sigs_stdlib_compat__V4.cmi}"; + "%{lib:tezos-protocol-environment.sigs.stdlib-compat:tezos_protocol_environment_sigs_stdlib_compat__V4.cmi}"; S - "%{lib:tezos-protocol-environment-sigs:tezos_protocol_environment_sigs.cmi}"; + "%{lib:tezos-protocol-environment.sigs:tezos_protocol_environment_sigs.cmi}"; S - "%{lib:tezos-protocol-environment-sigs:tezos_protocol_environment_sigs__V0.cmi}"; + "%{lib:tezos-protocol-environment.sigs:tezos_protocol_environment_sigs__V0.cmi}"; S - "%{lib:tezos-protocol-environment-sigs:tezos_protocol_environment_sigs__V1.cmi}"; + "%{lib:tezos-protocol-environment.sigs:tezos_protocol_environment_sigs__V1.cmi}"; S - "%{lib:tezos-protocol-environment-sigs:tezos_protocol_environment_sigs__V2.cmi}"; + "%{lib:tezos-protocol-environment.sigs:tezos_protocol_environment_sigs__V2.cmi}"; S - "%{lib:tezos-protocol-environment-sigs:tezos_protocol_environment_sigs__V3.cmi}"; + "%{lib:tezos-protocol-environment.sigs:tezos_protocol_environment_sigs__V3.cmi}"; S - "%{lib:tezos-protocol-environment-sigs:tezos_protocol_environment_sigs__V4.cmi}"; + "%{lib:tezos-protocol-environment.sigs:tezos_protocol_environment_sigs__V4.cmi}"; S - "%{lib:tezos-protocol-environment-sigs:tezos_protocol_environment_sigs__V5.cmi}"; + "%{lib:tezos-protocol-environment.sigs:tezos_protocol_environment_sigs__V5.cmi}"; ]; ] @@ -3028,14 +3014,14 @@ let _s_packer = private_exe "s_packer" ~path:"src/lib_protocol_environment/s_packer" - ~opam:"src/lib_protocol_environment/tezos-protocol-environment-packer" + ~opam:"src/lib_protocol_environment/tezos-protocol-environment" ~bisect_ppx:false ~dune: Dune. [ install [as_ "s_packer.exe" "s_packer"] - ~package:"tezos-protocol-environment-packer" + ~package:"tezos-protocol-environment" ~section:"libexec"; ] diff --git a/src/lib_protocol_compiler/dune b/src/lib_protocol_compiler/dune index c7a6666f6a..18aaf7311f 100644 --- a/src/lib_protocol_compiler/dune +++ b/src/lib_protocol_compiler/dune @@ -7,7 +7,7 @@ (instrumentation (backend bisect_ppx)) (libraries tezos-base - tezos-protocol-environment-sigs) + tezos-protocol-environment.sigs) (flags (:standard -opaque -open Tezos_base.TzPervasives)) (modules Registerer)) @@ -18,18 +18,18 @@ %{bin:ocp-ocamlres} -format ocaml -o %{targets} %{lib:stdlib:camlinternalFormatBasics.cmi} %{dep:.tezos_protocol_registerer.objs/byte/tezos_protocol_registerer__Registerer.cmi} - %{lib:tezos-protocol-environment-sigs.stdlib-compat:tezos_protocol_environment_sigs_stdlib_compat.cmi} - %{lib:tezos-protocol-environment-sigs.stdlib-compat:tezos_protocol_environment_sigs_stdlib_compat__V_all.cmi} - %{lib:tezos-protocol-environment-sigs.stdlib-compat:tezos_protocol_environment_sigs_stdlib_compat__V2.cmi} - %{lib:tezos-protocol-environment-sigs.stdlib-compat:tezos_protocol_environment_sigs_stdlib_compat__V3.cmi} - %{lib:tezos-protocol-environment-sigs.stdlib-compat:tezos_protocol_environment_sigs_stdlib_compat__V4.cmi} - %{lib:tezos-protocol-environment-sigs:tezos_protocol_environment_sigs.cmi} - %{lib:tezos-protocol-environment-sigs:tezos_protocol_environment_sigs__V0.cmi} - %{lib:tezos-protocol-environment-sigs:tezos_protocol_environment_sigs__V1.cmi} - %{lib:tezos-protocol-environment-sigs:tezos_protocol_environment_sigs__V2.cmi} - %{lib:tezos-protocol-environment-sigs:tezos_protocol_environment_sigs__V3.cmi} - %{lib:tezos-protocol-environment-sigs:tezos_protocol_environment_sigs__V4.cmi} - %{lib:tezos-protocol-environment-sigs:tezos_protocol_environment_sigs__V5.cmi}))) + %{lib:tezos-protocol-environment.sigs.stdlib-compat:tezos_protocol_environment_sigs_stdlib_compat.cmi} + %{lib:tezos-protocol-environment.sigs.stdlib-compat:tezos_protocol_environment_sigs_stdlib_compat__V_all.cmi} + %{lib:tezos-protocol-environment.sigs.stdlib-compat:tezos_protocol_environment_sigs_stdlib_compat__V2.cmi} + %{lib:tezos-protocol-environment.sigs.stdlib-compat:tezos_protocol_environment_sigs_stdlib_compat__V3.cmi} + %{lib:tezos-protocol-environment.sigs.stdlib-compat:tezos_protocol_environment_sigs_stdlib_compat__V4.cmi} + %{lib:tezos-protocol-environment.sigs:tezos_protocol_environment_sigs.cmi} + %{lib:tezos-protocol-environment.sigs:tezos_protocol_environment_sigs__V0.cmi} + %{lib:tezos-protocol-environment.sigs:tezos_protocol_environment_sigs__V1.cmi} + %{lib:tezos-protocol-environment.sigs:tezos_protocol_environment_sigs__V2.cmi} + %{lib:tezos-protocol-environment.sigs:tezos_protocol_environment_sigs__V3.cmi} + %{lib:tezos-protocol-environment.sigs:tezos_protocol_environment_sigs__V4.cmi} + %{lib:tezos-protocol-environment.sigs:tezos_protocol_environment_sigs__V5.cmi}))) (library (name tezos_protocol_compiler) @@ -39,7 +39,7 @@ tezos-base tezos-base.unix tezos-version - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos-stdlib-unix compiler-libs.common lwt.unix diff --git a/src/lib_protocol_compiler/dune_protocol.template.v0 b/src/lib_protocol_compiler/dune_protocol.template.v0 index 180d043b24..13579fb7ee 100644 --- a/src/lib_protocol_compiler/dune_protocol.template.v0 +++ b/src/lib_protocol_compiler/dune_protocol.template.v0 @@ -85,7 +85,7 @@ include Tezos_raw_protocol_%%LIB_VERSION%%.Main (public_name tezos-protocol-%%VERSION%%) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos_raw_protocol_%%LIB_VERSION%%) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" @@ -100,7 +100,7 @@ include Tezos_raw_protocol_%%LIB_VERSION%%.Main (public_name tezos-protocol-functor-%%VERSION%%) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos-protocol-%%VERSION%%.raw) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" diff --git a/src/lib_protocol_compiler/dune_protocol.template.v1 b/src/lib_protocol_compiler/dune_protocol.template.v1 index 40e9eca076..13e0f9924f 100644 --- a/src/lib_protocol_compiler/dune_protocol.template.v1 +++ b/src/lib_protocol_compiler/dune_protocol.template.v1 @@ -82,7 +82,7 @@ include Tezos_raw_protocol_%%LIB_VERSION%%.Main (public_name tezos-protocol-%%VERSION%%) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos_raw_protocol_%%LIB_VERSION%%) (flags -w "+a-4-40..42-44-45-48" -warn-error "+a" @@ -97,7 +97,7 @@ include Tezos_raw_protocol_%%LIB_VERSION%%.Main (public_name tezos-protocol-functor-%%VERSION%%) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos-protocol-%%VERSION%%.raw) (flags -w "+a-4-40..42-44-45-48" -warn-error "+a" diff --git a/src/lib_protocol_compiler/tezos-protocol-compiler.opam b/src/lib_protocol_compiler/tezos-protocol-compiler.opam index 64c5290b51..44a99b94a7 100644 --- a/src/lib_protocol_compiler/tezos-protocol-compiler.opam +++ b/src/lib_protocol_compiler/tezos-protocol-compiler.opam @@ -11,13 +11,12 @@ depends: [ "dune" { >= "2.9" } "ocaml" { >= "4.12.1" & < "4.13" } "tezos-base" - "tezos-protocol-environment-sigs" + "tezos-protocol-environment" "tezos-version" "tezos-stdlib-unix" "lwt" { >= "5.4.0" } "ocp-ocamlres" { >= "0.4" } "base-unix" - "tezos-protocol-environment" "re" { >= "1.7.2" } ] build: [ diff --git a/src/lib_protocol_environment/dune b/src/lib_protocol_environment/dune index 1c84ae6fc4..c9b2bdebe4 100644 --- a/src/lib_protocol_environment/dune +++ b/src/lib_protocol_environment/dune @@ -13,8 +13,8 @@ ringo-lwt tezos-base tezos-sapling - tezos-protocol-environment-sigs - tezos-protocol-environment-structs + tezos-protocol-environment.sigs + tezos-protocol-environment.structs tezos-micheline tezos-context.memory tezos-event-logging) diff --git a/src/lib_protocol_environment/s_packer/dune b/src/lib_protocol_environment/s_packer/dune index c28bbf69ae..cf41c7c48f 100644 --- a/src/lib_protocol_environment/s_packer/dune +++ b/src/lib_protocol_environment/s_packer/dune @@ -1,16 +1,10 @@ ; This file was automatically generated, do not edit. ; Edit file manifest/main.ml instead. -(library - (name tezos_protocol_environment_packer) - (public_name tezos-protocol-environment-packer) - (instrumentation (backend bisect_ppx)) - (modules)) - (executable (name s_packer)) (install - (package tezos-protocol-environment-packer) + (package tezos-protocol-environment) (section libexec) (files (s_packer.exe as s_packer))) diff --git a/src/lib_protocol_environment/sigs/dune b/src/lib_protocol_environment/sigs/dune index 07246b71d5..2991e3a664 100644 --- a/src/lib_protocol_environment/sigs/dune +++ b/src/lib_protocol_environment/sigs/dune @@ -3,10 +3,10 @@ (library (name tezos_protocol_environment_sigs) - (public_name tezos-protocol-environment-sigs) + (public_name tezos-protocol-environment.sigs) (instrumentation (backend bisect_ppx)) (libraries - tezos-protocol-environment-sigs.stdlib-compat) + tezos-protocol-environment.sigs.stdlib-compat) (flags (:standard -nostdlib -nopervasives)) (modules V0 V1 V2 V3 V4 V5)) diff --git a/src/lib_protocol_environment/sigs/stdlib_compat/dune b/src/lib_protocol_environment/sigs/stdlib_compat/dune index dac909726e..f5542e8118 100644 --- a/src/lib_protocol_environment/sigs/stdlib_compat/dune +++ b/src/lib_protocol_environment/sigs/stdlib_compat/dune @@ -3,6 +3,6 @@ (library (name tezos_protocol_environment_sigs_stdlib_compat) - (public_name tezos-protocol-environment-sigs.stdlib-compat) + (public_name tezos-protocol-environment.sigs.stdlib-compat) (instrumentation (backend bisect_ppx)) (modules_without_implementation V_all V2 V3 V4)) diff --git a/src/lib_protocol_environment/sigs/v0.dune.inc b/src/lib_protocol_environment/sigs/v0.dune.inc index e4982f994e..2217a93596 100644 --- a/src/lib_protocol_environment/sigs/v0.dune.inc +++ b/src/lib_protocol_environment/sigs/v0.dune.inc @@ -61,4 +61,4 @@ ) (action (with-stdout-to %{targets} (chdir %{workspace_root}} - (run %{libexec:tezos-protocol-environment-packer:s_packer} "sigs" %{deps}))))) + (run %{libexec:tezos-protocol-environment:s_packer} "sigs" %{deps}))))) diff --git a/src/lib_protocol_environment/sigs/v1.dune.inc b/src/lib_protocol_environment/sigs/v1.dune.inc index 7dc2c2ae07..d9ad78db41 100644 --- a/src/lib_protocol_environment/sigs/v1.dune.inc +++ b/src/lib_protocol_environment/sigs/v1.dune.inc @@ -67,4 +67,4 @@ ) (action (with-stdout-to %{targets} (chdir %{workspace_root}} - (run %{libexec:tezos-protocol-environment-packer:s_packer} "sigs" %{deps}))))) + (run %{libexec:tezos-protocol-environment:s_packer} "sigs" %{deps}))))) diff --git a/src/lib_protocol_environment/sigs/v2.dune.inc b/src/lib_protocol_environment/sigs/v2.dune.inc index ed403dc473..0b72e7ca8d 100644 --- a/src/lib_protocol_environment/sigs/v2.dune.inc +++ b/src/lib_protocol_environment/sigs/v2.dune.inc @@ -68,4 +68,4 @@ v2/equality_witness.mli ) (action (with-stdout-to %{targets} (chdir %{workspace_root}} - (run %{libexec:tezos-protocol-environment-packer:s_packer} "sigs" %{deps}))))) + (run %{libexec:tezos-protocol-environment:s_packer} "sigs" %{deps}))))) diff --git a/src/lib_protocol_environment/sigs/v3.dune.inc b/src/lib_protocol_environment/sigs/v3.dune.inc index 44fa338432..5e35ccb3e6 100644 --- a/src/lib_protocol_environment/sigs/v3.dune.inc +++ b/src/lib_protocol_environment/sigs/v3.dune.inc @@ -76,4 +76,4 @@ v3/RPC_context.mli ) (action (with-stdout-to %{targets} (chdir %{workspace_root}} - (run %{libexec:tezos-protocol-environment-packer:s_packer} "sigs" %{deps}))))) + (run %{libexec:tezos-protocol-environment:s_packer} "sigs" %{deps}))))) diff --git a/src/lib_protocol_environment/sigs/v4.dune.inc b/src/lib_protocol_environment/sigs/v4.dune.inc index f2debff5cd..9d7c978d74 100644 --- a/src/lib_protocol_environment/sigs/v4.dune.inc +++ b/src/lib_protocol_environment/sigs/v4.dune.inc @@ -77,4 +77,4 @@ v4/RPC_context.mli ) (action (with-stdout-to %{targets} (chdir %{workspace_root}} - (run %{libexec:tezos-protocol-environment-packer:s_packer} "sigs" %{deps}))))) + (run %{libexec:tezos-protocol-environment:s_packer} "sigs" %{deps}))))) diff --git a/src/lib_protocol_environment/sigs/v5.dune.inc b/src/lib_protocol_environment/sigs/v5.dune.inc index 38f63711f9..075a69f757 100644 --- a/src/lib_protocol_environment/sigs/v5.dune.inc +++ b/src/lib_protocol_environment/sigs/v5.dune.inc @@ -80,4 +80,4 @@ ) (action (with-stdout-to %{targets} (chdir %{workspace_root}} - (run %{libexec:tezos-protocol-environment-packer:s_packer} "sigs" %{deps}))))) + (run %{libexec:tezos-protocol-environment:s_packer} "sigs" %{deps}))))) diff --git a/src/lib_protocol_environment/structs/dune b/src/lib_protocol_environment/structs/dune index 75dd5f8d9c..1e4055c099 100644 --- a/src/lib_protocol_environment/structs/dune +++ b/src/lib_protocol_environment/structs/dune @@ -3,7 +3,7 @@ (library (name tezos_protocol_environment_structs) - (public_name tezos-protocol-environment-structs) + (public_name tezos-protocol-environment.structs) (instrumentation (backend bisect_ppx)) (libraries tezos-stdlib diff --git a/src/lib_protocol_environment/structs/v0.dune.inc b/src/lib_protocol_environment/structs/v0.dune.inc index 9313051612..02db3712e5 100644 --- a/src/lib_protocol_environment/structs/v0.dune.inc +++ b/src/lib_protocol_environment/structs/v0.dune.inc @@ -23,4 +23,4 @@ ) (action (with-stdout-to %{targets} (chdir %{workspace_root}} - (run %{libexec:tezos-protocol-environment-packer:s_packer} "structs" %{deps}))))) + (run %{libexec:tezos-protocol-environment:s_packer} "structs" %{deps}))))) diff --git a/src/lib_protocol_environment/structs/v1.dune.inc b/src/lib_protocol_environment/structs/v1.dune.inc index 8ef9fe0224..989efa6ef2 100644 --- a/src/lib_protocol_environment/structs/v1.dune.inc +++ b/src/lib_protocol_environment/structs/v1.dune.inc @@ -25,4 +25,4 @@ ) (action (with-stdout-to %{targets} (chdir %{workspace_root}} - (run %{libexec:tezos-protocol-environment-packer:s_packer} "structs" %{deps}))))) + (run %{libexec:tezos-protocol-environment:s_packer} "structs" %{deps}))))) diff --git a/src/lib_protocol_environment/structs/v2.dune.inc b/src/lib_protocol_environment/structs/v2.dune.inc index ff97ebdf4d..00b7e7b865 100644 --- a/src/lib_protocol_environment/structs/v2.dune.inc +++ b/src/lib_protocol_environment/structs/v2.dune.inc @@ -24,4 +24,4 @@ ) (action (with-stdout-to %{targets} (chdir %{workspace_root}} - (run %{libexec:tezos-protocol-environment-packer:s_packer} "structs" %{deps}))))) + (run %{libexec:tezos-protocol-environment:s_packer} "structs" %{deps}))))) diff --git a/src/lib_protocol_environment/structs/v3.dune.inc b/src/lib_protocol_environment/structs/v3.dune.inc index cd6b409318..77ad80ebd3 100644 --- a/src/lib_protocol_environment/structs/v3.dune.inc +++ b/src/lib_protocol_environment/structs/v3.dune.inc @@ -12,4 +12,4 @@ ) (action (with-stdout-to %{targets} (chdir %{workspace_root}} - (run %{libexec:tezos-protocol-environment-packer:s_packer} "structs" %{deps}))))) + (run %{libexec:tezos-protocol-environment:s_packer} "structs" %{deps}))))) diff --git a/src/lib_protocol_environment/structs/v4.dune.inc b/src/lib_protocol_environment/structs/v4.dune.inc index 49a1c2369f..f17dfe0061 100644 --- a/src/lib_protocol_environment/structs/v4.dune.inc +++ b/src/lib_protocol_environment/structs/v4.dune.inc @@ -7,5 +7,5 @@ ) (action (with-stdout-to %{targets} (chdir %{workspace_root}} - (run %{libexec:tezos-protocol-environment-packer:s_packer} "structs" %{deps}))))) + (run %{libexec:tezos-protocol-environment:s_packer} "structs" %{deps}))))) diff --git a/src/lib_protocol_environment/structs/v5.dune.inc b/src/lib_protocol_environment/structs/v5.dune.inc index e6abd391db..2eab0a72d0 100644 --- a/src/lib_protocol_environment/structs/v5.dune.inc +++ b/src/lib_protocol_environment/structs/v5.dune.inc @@ -4,4 +4,4 @@ ) (action (with-stdout-to %{targets} (chdir %{workspace_root}} - (run %{libexec:tezos-protocol-environment-packer:s_packer} "structs" %{deps}))))) + (run %{libexec:tezos-protocol-environment:s_packer} "structs" %{deps}))))) diff --git a/src/lib_protocol_environment/tezos-protocol-environment-packer.opam b/src/lib_protocol_environment/tezos-protocol-environment-packer.opam deleted file mode 100644 index 2b8bba4865..0000000000 --- a/src/lib_protocol_environment/tezos-protocol-environment-packer.opam +++ /dev/null @@ -1,18 +0,0 @@ -# This file was automatically generated, do not edit. -# Edit file manifest/main.ml instead. -opam-version: "2.0" -maintainer: "contact@tezos.com" -authors: ["Tezos devteam"] -homepage: "https://www.tezos.com/" -bug-reports: "https://gitlab.com/tezos/tezos/issues" -dev-repo: "git+https://gitlab.com/tezos/tezos.git" -license: "MIT" -depends: [ - "dune" { >= "2.9" } - "ocaml" { >= "4.03" } -] -build: [ - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos: sigs/structs packer for economic protocol environment" diff --git a/src/lib_protocol_environment/tezos-protocol-environment-sigs.opam b/src/lib_protocol_environment/tezos-protocol-environment-sigs.opam deleted file mode 100644 index 1d38102786..0000000000 --- a/src/lib_protocol_environment/tezos-protocol-environment-sigs.opam +++ /dev/null @@ -1,19 +0,0 @@ -# This file was automatically generated, do not edit. -# Edit file manifest/main.ml instead. -opam-version: "2.0" -maintainer: "contact@tezos.com" -authors: ["Tezos devteam"] -homepage: "https://www.tezos.com/" -bug-reports: "https://gitlab.com/tezos/tezos/issues" -dev-repo: "git+https://gitlab.com/tezos/tezos.git" -license: "MIT" -depends: [ - "dune" { >= "2.9" } - "ocaml" { >= "4.12" } - "tezos-protocol-environment-packer" -] -build: [ - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos: restricted typing environment for the economic protocols" diff --git a/src/lib_protocol_environment/tezos-protocol-environment-structs.opam b/src/lib_protocol_environment/tezos-protocol-environment-structs.opam deleted file mode 100644 index b50e936c3c..0000000000 --- a/src/lib_protocol_environment/tezos-protocol-environment-structs.opam +++ /dev/null @@ -1,23 +0,0 @@ -# This file was automatically generated, do not edit. -# Edit file manifest/main.ml instead. -opam-version: "2.0" -maintainer: "contact@tezos.com" -authors: ["Tezos devteam"] -homepage: "https://www.tezos.com/" -bug-reports: "https://gitlab.com/tezos/tezos/issues" -dev-repo: "git+https://gitlab.com/tezos/tezos.git" -license: "MIT" -depends: [ - "dune" { >= "2.9" } - "tezos-stdlib" - "tezos-crypto" - "tezos-lwt-result-stdlib" - "data-encoding" { >= "0.5.1" & < "0.6" } - "bls12-381-legacy" - "tezos-protocol-environment-packer" -] -build: [ - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos: restricted typing environment for the economic protocols" diff --git a/src/lib_protocol_environment/tezos-protocol-environment.opam b/src/lib_protocol_environment/tezos-protocol-environment.opam index 94f4fbdb04..b0beb89706 100644 --- a/src/lib_protocol_environment/tezos-protocol-environment.opam +++ b/src/lib_protocol_environment/tezos-protocol-environment.opam @@ -9,6 +9,12 @@ dev-repo: "git+https://gitlab.com/tezos/tezos.git" license: "MIT" depends: [ "dune" { >= "2.9" } + "ocaml" { >= "4.12" } + "tezos-stdlib" + "tezos-crypto" + "tezos-lwt-result-stdlib" + "data-encoding" { >= "0.5.1" & < "0.6" } + "bls12-381-legacy" "zarith" { >= "1.12" & < "1.13" } "zarith_stubs_js" "bls12-381" { >= "2.0.0" & < "2.1.0" } @@ -16,8 +22,6 @@ depends: [ "ringo-lwt" { = "0.7" } "tezos-base" "tezos-sapling" - "tezos-protocol-environment-sigs" - "tezos-protocol-environment-structs" "tezos-micheline" "tezos-context" "tezos-event-logging" @@ -31,4 +35,15 @@ build: [ ["dune" "build" "-p" name "-j" jobs] ["dune" "runtest" "-p" name "-j" jobs] {with-test} ] -synopsis: "Tezos: custom economic-protocols environment implementation for `tezos-client` and testing" +synopsis: "Interface layer between the protocols and the shell" +description: "The protocol-environment is a two-sided component sitting between the shell and +the protocols. + +On one side, it provides a restricted typing environment to compile the +protocols against. This is a series of modules which replace the standard +library of OCaml. These modules purposefully omit many functionalities, thus +preventing the protocols from, say, directly writing to disk. + +On the other side, it provides the shell with specific call-sites in the +protocols. These are the only entry-points into the otherwise black-box +protocols." diff --git a/src/proto_000_Ps9mPmXa/lib_protocol/dune.inc b/src/proto_000_Ps9mPmXa/lib_protocol/dune.inc index 2443b9ec9f..279398f180 100644 --- a/src/proto_000_Ps9mPmXa/lib_protocol/dune.inc +++ b/src/proto_000_Ps9mPmXa/lib_protocol/dune.inc @@ -101,7 +101,7 @@ include Tezos_raw_protocol_000_Ps9mPmXa.Main (public_name tezos-protocol-000-Ps9mPmXa) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos_raw_protocol_000_Ps9mPmXa) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" @@ -116,7 +116,7 @@ include Tezos_raw_protocol_000_Ps9mPmXa.Main (public_name tezos-protocol-functor-000-Ps9mPmXa) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos-protocol-000-Ps9mPmXa.raw) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" diff --git a/src/proto_001_PtCJ7pwo/lib_protocol/dune.inc b/src/proto_001_PtCJ7pwo/lib_protocol/dune.inc index ea23fb93d4..017441f7ea 100644 --- a/src/proto_001_PtCJ7pwo/lib_protocol/dune.inc +++ b/src/proto_001_PtCJ7pwo/lib_protocol/dune.inc @@ -357,7 +357,7 @@ include Tezos_raw_protocol_001_PtCJ7pwo.Main (public_name tezos-protocol-001-PtCJ7pwo) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos_raw_protocol_001_PtCJ7pwo) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" @@ -372,7 +372,7 @@ include Tezos_raw_protocol_001_PtCJ7pwo.Main (public_name tezos-protocol-functor-001-PtCJ7pwo) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos-protocol-001-PtCJ7pwo.raw) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" diff --git a/src/proto_002_PsYLVpVv/lib_protocol/dune.inc b/src/proto_002_PsYLVpVv/lib_protocol/dune.inc index 6c72a3eab4..43e1862001 100644 --- a/src/proto_002_PsYLVpVv/lib_protocol/dune.inc +++ b/src/proto_002_PsYLVpVv/lib_protocol/dune.inc @@ -357,7 +357,7 @@ include Tezos_raw_protocol_002_PsYLVpVv.Main (public_name tezos-protocol-002-PsYLVpVv) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos_raw_protocol_002_PsYLVpVv) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" @@ -372,7 +372,7 @@ include Tezos_raw_protocol_002_PsYLVpVv.Main (public_name tezos-protocol-functor-002-PsYLVpVv) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos-protocol-002-PsYLVpVv.raw) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" diff --git a/src/proto_003_PsddFKi3/lib_protocol/dune.inc b/src/proto_003_PsddFKi3/lib_protocol/dune.inc index cb99b0bc76..38a5269b3f 100644 --- a/src/proto_003_PsddFKi3/lib_protocol/dune.inc +++ b/src/proto_003_PsddFKi3/lib_protocol/dune.inc @@ -361,7 +361,7 @@ include Tezos_raw_protocol_003_PsddFKi3.Main (public_name tezos-protocol-003-PsddFKi3) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos_raw_protocol_003_PsddFKi3) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" @@ -376,7 +376,7 @@ include Tezos_raw_protocol_003_PsddFKi3.Main (public_name tezos-protocol-functor-003-PsddFKi3) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos-protocol-003-PsddFKi3.raw) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" diff --git a/src/proto_004_Pt24m4xi/lib_protocol/dune.inc b/src/proto_004_Pt24m4xi/lib_protocol/dune.inc index 473fa1795c..3486c62c6f 100644 --- a/src/proto_004_Pt24m4xi/lib_protocol/dune.inc +++ b/src/proto_004_Pt24m4xi/lib_protocol/dune.inc @@ -361,7 +361,7 @@ include Tezos_raw_protocol_004_Pt24m4xi.Main (public_name tezos-protocol-004-Pt24m4xi) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos_raw_protocol_004_Pt24m4xi) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" @@ -376,7 +376,7 @@ include Tezos_raw_protocol_004_Pt24m4xi.Main (public_name tezos-protocol-functor-004-Pt24m4xi) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos-protocol-004-Pt24m4xi.raw) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" diff --git a/src/proto_005_PsBABY5H/lib_protocol/dune.inc b/src/proto_005_PsBABY5H/lib_protocol/dune.inc index 0da0d35d80..116170d5ba 100644 --- a/src/proto_005_PsBABY5H/lib_protocol/dune.inc +++ b/src/proto_005_PsBABY5H/lib_protocol/dune.inc @@ -365,7 +365,7 @@ include Tezos_raw_protocol_005_PsBABY5H.Main (public_name tezos-protocol-005-PsBABY5H) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos_raw_protocol_005_PsBABY5H) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" @@ -380,7 +380,7 @@ include Tezos_raw_protocol_005_PsBABY5H.Main (public_name tezos-protocol-functor-005-PsBABY5H) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos-protocol-005-PsBABY5H.raw) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" diff --git a/src/proto_005_PsBabyM1/lib_protocol/dune.inc b/src/proto_005_PsBabyM1/lib_protocol/dune.inc index fec46d8f52..2516d2e044 100644 --- a/src/proto_005_PsBabyM1/lib_protocol/dune.inc +++ b/src/proto_005_PsBabyM1/lib_protocol/dune.inc @@ -365,7 +365,7 @@ include Tezos_raw_protocol_005_PsBabyM1.Main (public_name tezos-protocol-005-PsBabyM1) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos_raw_protocol_005_PsBabyM1) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" @@ -380,7 +380,7 @@ include Tezos_raw_protocol_005_PsBabyM1.Main (public_name tezos-protocol-functor-005-PsBabyM1) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos-protocol-005-PsBabyM1.raw) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" diff --git a/src/proto_006_PsCARTHA/lib_protocol/dune.inc b/src/proto_006_PsCARTHA/lib_protocol/dune.inc index 7c00dcae23..75103d5774 100644 --- a/src/proto_006_PsCARTHA/lib_protocol/dune.inc +++ b/src/proto_006_PsCARTHA/lib_protocol/dune.inc @@ -365,7 +365,7 @@ include Tezos_raw_protocol_006_PsCARTHA.Main (public_name tezos-protocol-006-PsCARTHA) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos_raw_protocol_006_PsCARTHA) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" @@ -380,7 +380,7 @@ include Tezos_raw_protocol_006_PsCARTHA.Main (public_name tezos-protocol-functor-006-PsCARTHA) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos-protocol-006-PsCARTHA.raw) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" diff --git a/src/proto_007_PsDELPH1/lib_protocol/dune.inc b/src/proto_007_PsDELPH1/lib_protocol/dune.inc index 8d131dba4c..0997ac7e80 100644 --- a/src/proto_007_PsDELPH1/lib_protocol/dune.inc +++ b/src/proto_007_PsDELPH1/lib_protocol/dune.inc @@ -373,7 +373,7 @@ include Tezos_raw_protocol_007_PsDELPH1.Main (public_name tezos-protocol-007-PsDELPH1) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos_raw_protocol_007_PsDELPH1) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" @@ -388,7 +388,7 @@ include Tezos_raw_protocol_007_PsDELPH1.Main (public_name tezos-protocol-functor-007-PsDELPH1) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos-protocol-007-PsDELPH1.raw) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" diff --git a/src/proto_008_PtEdo2Zk/lib_protocol/dune.inc b/src/proto_008_PtEdo2Zk/lib_protocol/dune.inc index 07747f6702..f21b296688 100644 --- a/src/proto_008_PtEdo2Zk/lib_protocol/dune.inc +++ b/src/proto_008_PtEdo2Zk/lib_protocol/dune.inc @@ -393,7 +393,7 @@ include Tezos_raw_protocol_008_PtEdo2Zk.Main (public_name tezos-protocol-008-PtEdo2Zk) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos_raw_protocol_008_PtEdo2Zk) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" @@ -408,7 +408,7 @@ include Tezos_raw_protocol_008_PtEdo2Zk.Main (public_name tezos-protocol-functor-008-PtEdo2Zk) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos-protocol-008-PtEdo2Zk.raw) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" diff --git a/src/proto_008_PtEdoTez/lib_protocol/dune.inc b/src/proto_008_PtEdoTez/lib_protocol/dune.inc index d142e09e99..736d903e8e 100644 --- a/src/proto_008_PtEdoTez/lib_protocol/dune.inc +++ b/src/proto_008_PtEdoTez/lib_protocol/dune.inc @@ -393,7 +393,7 @@ include Tezos_raw_protocol_008_PtEdoTez.Main (public_name tezos-protocol-008-PtEdoTez) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos_raw_protocol_008_PtEdoTez) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" @@ -408,7 +408,7 @@ include Tezos_raw_protocol_008_PtEdoTez.Main (public_name tezos-protocol-functor-008-PtEdoTez) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos-protocol-008-PtEdoTez.raw) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" diff --git a/src/proto_009_PsFLoren/lib_protocol/dune.inc b/src/proto_009_PsFLoren/lib_protocol/dune.inc index f6cc93d154..289c463f34 100644 --- a/src/proto_009_PsFLoren/lib_protocol/dune.inc +++ b/src/proto_009_PsFLoren/lib_protocol/dune.inc @@ -405,7 +405,7 @@ include Tezos_raw_protocol_009_PsFLoren.Main (public_name tezos-protocol-009-PsFLoren) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos_raw_protocol_009_PsFLoren) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" @@ -420,7 +420,7 @@ include Tezos_raw_protocol_009_PsFLoren.Main (public_name tezos-protocol-functor-009-PsFLoren) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos-protocol-009-PsFLoren.raw) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" diff --git a/src/proto_010_PtGRANAD/lib_protocol/dune.inc b/src/proto_010_PtGRANAD/lib_protocol/dune.inc index 7fb0c3cc40..4db2f5507a 100644 --- a/src/proto_010_PtGRANAD/lib_protocol/dune.inc +++ b/src/proto_010_PtGRANAD/lib_protocol/dune.inc @@ -425,7 +425,7 @@ include Tezos_raw_protocol_010_PtGRANAD.Main (public_name tezos-protocol-010-PtGRANAD) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos_raw_protocol_010_PtGRANAD) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" @@ -440,7 +440,7 @@ include Tezos_raw_protocol_010_PtGRANAD.Main (public_name tezos-protocol-functor-010-PtGRANAD) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos-protocol-010-PtGRANAD.raw) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" diff --git a/src/proto_011_PtHangz2/lib_protocol/dune.inc b/src/proto_011_PtHangz2/lib_protocol/dune.inc index 75b8afd94a..4e9543d80b 100644 --- a/src/proto_011_PtHangz2/lib_protocol/dune.inc +++ b/src/proto_011_PtHangz2/lib_protocol/dune.inc @@ -474,7 +474,7 @@ include Tezos_raw_protocol_011_PtHangz2.Main (public_name tezos-protocol-011-PtHangz2) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos_raw_protocol_011_PtHangz2) (flags -w "+a-4-40..42-44-45-48" -warn-error "+a" @@ -489,7 +489,7 @@ include Tezos_raw_protocol_011_PtHangz2.Main (public_name tezos-protocol-functor-011-PtHangz2) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos-protocol-011-PtHangz2.raw) (flags -w "+a-4-40..42-44-45-48" -warn-error "+a" diff --git a/src/proto_012_Psithaca/lib_protocol/dune.inc b/src/proto_012_Psithaca/lib_protocol/dune.inc index 0cd2252e62..36b87b5320 100644 --- a/src/proto_012_Psithaca/lib_protocol/dune.inc +++ b/src/proto_012_Psithaca/lib_protocol/dune.inc @@ -542,7 +542,7 @@ include Tezos_raw_protocol_012_Psithaca.Main (public_name tezos-protocol-012-Psithaca) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos_raw_protocol_012_Psithaca) (flags -w "+a-4-40..42-44-45-48" -warn-error "+a" @@ -557,7 +557,7 @@ include Tezos_raw_protocol_012_Psithaca.Main (public_name tezos-protocol-functor-012-Psithaca) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos-protocol-012-Psithaca.raw) (flags -w "+a-4-40..42-44-45-48" -warn-error "+a" diff --git a/src/proto_alpha/lib_protocol/dune.inc b/src/proto_alpha/lib_protocol/dune.inc index dd9bba3416..81529e75cf 100644 --- a/src/proto_alpha/lib_protocol/dune.inc +++ b/src/proto_alpha/lib_protocol/dune.inc @@ -766,7 +766,7 @@ include Tezos_raw_protocol_alpha.Main (public_name tezos-protocol-alpha) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos_raw_protocol_alpha) (flags -w "+a-4-40..42-44-45-48" -warn-error "+a" @@ -781,7 +781,7 @@ include Tezos_raw_protocol_alpha.Main (public_name tezos-protocol-functor-alpha) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos-protocol-alpha.raw) (flags -w "+a-4-40..42-44-45-48" -warn-error "+a" diff --git a/src/proto_demo_counter/lib_protocol/dune.inc b/src/proto_demo_counter/lib_protocol/dune.inc index 0a93a48631..29314bc2da 100644 --- a/src/proto_demo_counter/lib_protocol/dune.inc +++ b/src/proto_demo_counter/lib_protocol/dune.inc @@ -122,7 +122,7 @@ include Tezos_raw_protocol_demo_counter.Main (public_name tezos-protocol-demo-counter) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos_raw_protocol_demo_counter) (flags -w "+a-4-40..42-44-45-48" -warn-error "+a" @@ -137,7 +137,7 @@ include Tezos_raw_protocol_demo_counter.Main (public_name tezos-protocol-functor-demo-counter) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos-protocol-demo-counter.raw) (flags -w "+a-4-40..42-44-45-48" -warn-error "+a" diff --git a/src/proto_demo_noops/lib_protocol/dune.inc b/src/proto_demo_noops/lib_protocol/dune.inc index 42503252f2..2ae1db1bcc 100644 --- a/src/proto_demo_noops/lib_protocol/dune.inc +++ b/src/proto_demo_noops/lib_protocol/dune.inc @@ -90,7 +90,7 @@ include Tezos_raw_protocol_demo_noops.Main (public_name tezos-protocol-demo-noops) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos_raw_protocol_demo_noops) (flags -w "+a-4-40..42-44-45-48" -warn-error "+a" @@ -105,7 +105,7 @@ include Tezos_raw_protocol_demo_noops.Main (public_name tezos-protocol-functor-demo-noops) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos-protocol-demo-noops.raw) (flags -w "+a-4-40..42-44-45-48" -warn-error "+a" diff --git a/src/proto_genesis/lib_protocol/dune.inc b/src/proto_genesis/lib_protocol/dune.inc index da7c39a0a7..33347f0587 100644 --- a/src/proto_genesis/lib_protocol/dune.inc +++ b/src/proto_genesis/lib_protocol/dune.inc @@ -101,7 +101,7 @@ include Tezos_raw_protocol_genesis.Main (public_name tezos-protocol-genesis) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos_raw_protocol_genesis) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" @@ -116,7 +116,7 @@ include Tezos_raw_protocol_genesis.Main (public_name tezos-protocol-functor-genesis) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos-protocol-genesis.raw) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" diff --git a/src/proto_genesis_carthagenet/lib_protocol/dune.inc b/src/proto_genesis_carthagenet/lib_protocol/dune.inc index 1ae93da70c..795560b03c 100644 --- a/src/proto_genesis_carthagenet/lib_protocol/dune.inc +++ b/src/proto_genesis_carthagenet/lib_protocol/dune.inc @@ -101,7 +101,7 @@ include Tezos_raw_protocol_genesis_carthagenet.Main (public_name tezos-protocol-genesis-carthagenet) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos_raw_protocol_genesis_carthagenet) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" @@ -116,7 +116,7 @@ include Tezos_raw_protocol_genesis_carthagenet.Main (public_name tezos-protocol-functor-genesis-carthagenet) (libraries tezos-protocol-environment - tezos-protocol-environment-sigs + tezos-protocol-environment.sigs tezos-protocol-genesis-carthagenet.raw) (flags -w "+a-4-6-7-9-16-29-40..42-44-45-48-60-67-68" -warn-error "-A" From 5521152c3132d3ee2248e57d847cd7fbe9da8636 Mon Sep 17 00:00:00 2001 From: Arvid Jakobsson <arvid.jakobsson@nomadic-labs.com> Date: Wed, 16 Mar 2022 17:05:25 +0100 Subject: [PATCH 089/100] Docs/Proto/script_ir_translator: units in script/code_size docs --- src/proto_alpha/lib_protocol/script_ir_translator.mli | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/proto_alpha/lib_protocol/script_ir_translator.mli b/src/proto_alpha/lib_protocol/script_ir_translator.mli index 61bc87b46f..d6904f4765 100644 --- a/src/proto_alpha/lib_protocol/script_ir_translator.mli +++ b/src/proto_alpha/lib_protocol/script_ir_translator.mli @@ -502,7 +502,8 @@ val get_single_sapling_state : (Sapling.Id.t option * context) tzresult (** [code_size ctxt code views] returns an overapproximation of the size of - the in-memory representation of [code] and [views] in the context [ctxt]. *) + the in-memory representation of [code] and [views] in bytes in the + context [ctxt]. *) val code_size : context -> ('a, 'b) Script_typed_ir.lambda -> @@ -510,6 +511,6 @@ val code_size : (Cache_memory_helpers.sint * context) tzresult (** [script_size script] returns an overapproximation of the size of - the in-memory representation of [script] as well as the cost + the in-memory representation of [script] in bytes as well as the cost associated to computing that overapproximation. *) val script_size : ex_script -> int * Gas_limit_repr.cost From 64a89ea3a76f30c23f68b59dcfc527a32c0dc91e Mon Sep 17 00:00:00 2001 From: Thomas Letan <lthms@nomadic-labs.com> Date: Fri, 18 Mar 2022 14:36:19 +0100 Subject: [PATCH 090/100] Proto,tx_rollup: Refactor the Tx_rollup_state_repr module --- .../lib_protocol/alpha_context.mli | 14 +- .../integration/operations/test_tx_rollup.ml | 127 +++- .../tx_rollup_commitment_storage.ml | 100 ++-- .../lib_protocol/tx_rollup_inbox_storage.ml | 8 +- .../lib_protocol/tx_rollup_state_repr.ml | 554 +++++++++--------- .../lib_protocol/tx_rollup_state_repr.mli | 47 +- .../_regressions/tx_rollup_batch_encoding.out | 8 +- .../tx_rollup_finalize_commitment_future.out | 8 +- ...tx_rollup_finalize_commitment_no_batch.out | 4 +- ...llup_finalize_commitment_no_commitment.out | 8 +- ..._rollup_finalize_too_recent_commitment.out | 14 +- .../tx_rollup_limit_empty_batch.out | 8 +- .../tx_rollup_limit_maximum_size_batch.out | 8 +- .../tx_rollup_limit_maximum_size_inbox.out | 84 +-- .../_regressions/tx_rollup_rpc_commitment.out | 14 +- tezt/_regressions/tx_rollup_rpc_inbox.out | 8 +- ..._rollup_rpc_pending_bonded_commitments.out | 14 +- tezt/_regressions/tx_rollup_rpc_state.out | 12 +- tezt/lib_tezos/rollup.ml | 81 +-- tezt/lib_tezos/rollup.mli | 10 +- tezt/tests/tx_rollup.ml | 15 +- 21 files changed, 652 insertions(+), 494 deletions(-) diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index 65c1ca14ba..b0df126b83 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -1570,7 +1570,7 @@ module Tx_rollup_state : sig val assert_exist : context -> Tx_rollup.t -> context tzresult Lwt.t - val head_level : t -> (Tx_rollup_level.t * Raw_level.t) option + val head_levels : t -> (Tx_rollup_level.t * Raw_level.t) option val check_level_can_be_rejected : t -> Tx_rollup_level.t -> unit tzresult @@ -1583,10 +1583,11 @@ module Tx_rollup_state : sig ?inbox_ema:int -> ?last_removed_commitment_hashes: Tx_rollup_message_result_hash.t * Tx_rollup_commitment_hash.t -> - ?commitment_tail_level:Tx_rollup_level.t -> - ?oldest_inbox_level:Tx_rollup_level.t -> - ?commitment_head_level:Tx_rollup_level.t * Tx_rollup_commitment_hash.t -> - ?head_level:Tx_rollup_level.t * Raw_level.t -> + ?finalized_commitments:Tx_rollup_level.t * Tx_rollup_level.t -> + ?unfinalized_commitments:Tx_rollup_level.t * Tx_rollup_level.t -> + ?uncommitted_inboxes:Tx_rollup_level.t * Tx_rollup_level.t -> + ?commitment_newest_hash:Tx_rollup_commitment_hash.t -> + ?tezos_head_level:Raw_level.t -> unit -> t @@ -1594,6 +1595,8 @@ module Tx_rollup_state : sig t -> elapsed:int -> factor:int -> final_size:int -> hard_limit:int -> t val get_inbox_ema : t -> int + + val record_inbox_deletion : t -> Tx_rollup_level.t -> t tzresult end end @@ -1895,6 +1898,7 @@ module Tx_rollup_errors : sig | Wrong_inbox_hash | Bond_does_not_exist of Signature.public_key_hash | Bond_in_use of Signature.public_key_hash + | No_uncommitted_inbox | No_commitment_to_finalize | No_commitment_to_remove | Commitment_does_not_exist of Tx_rollup_level.t diff --git a/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml b/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml index 6d81f87524..ff1f8a8cb5 100644 --- a/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml +++ b/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml @@ -135,6 +135,9 @@ let message_hash_testable : Tx_rollup_message.hash Alcotest.testable = let sint_testable : _ Saturation_repr.t Alcotest.testable = Alcotest.testable Saturation_repr.pp ( = ) +let tx_rollup_state_testable : Tx_rollup_state.t Alcotest.testable = + Alcotest.testable Tx_rollup_state.pp ( = ) + let wrap m = m >|= Environment.wrap_tzresult (** [inbox_burn state size] computes the burn (per byte of message) @@ -1267,10 +1270,7 @@ let test_commitment_duplication () = | Ok _ -> failwith "an error was expected" | Error e -> check_proto_error_f - (function - | Tx_rollup_errors.Level_already_has_commitment level1 -> - Tx_rollup_level.root = level1 - | _ -> false) + (function Tx_rollup_errors.No_uncommitted_inbox -> true | _ -> false) e) >>=? fun _ -> (* No charge. *) @@ -1880,6 +1880,124 @@ module Rejection = struct ] end +(** [test_state] tests some edge cases in state management around + rejecting commitments. *) +let test_state () = + context_init1 () >>=? fun (b, account1) -> + originate b account1 >>=? fun (b, tx_rollup) -> + let pkh = is_implicit_exn account1 in + Incremental.begin_construction b >>=? fun i -> + let ctxt = Incremental.alpha_ctxt i in + let (message, _) = Tx_rollup_message.make_batch "bogus" in + let state = Tx_rollup_state.initial_state in + wrap (Tx_rollup_inbox.append_message ctxt tx_rollup state message) + >>=? fun (ctxt, state) -> + let append_inbox i ctxt state = + let i = Incremental.set_alpha_ctxt i ctxt in + (* need to increment state so that the second message goes into a new inbox *) + Incremental.finalize_block i >>=? fun b -> + Incremental.begin_construction b >>=? fun i -> + let ctxt = Incremental.alpha_ctxt i in + wrap (Tx_rollup_inbox.append_message ctxt tx_rollup state message) + >|=? fun (ctxt, state) -> (i, ctxt, state) + in + append_inbox i ctxt state >>=? fun (i, ctxt, state) -> + append_inbox i ctxt state >>=? fun (i, ctxt, state) -> + let level0 = Tx_rollup_level.root in + let inbox_hash = Tx_rollup_inbox.hash_inbox [message] in + let add_commitment ctxt state level predecessor = + let commitment = + Tx_rollup_commitment. + { + level; + messages = [Tx_rollup_message_result_hash.zero]; + predecessor; + inbox_hash; + } + in + wrap + (Tx_rollup_commitment.add_commitment ctxt tx_rollup state pkh commitment) + >|=? fun (ctxt, state) -> (ctxt, state, commitment) + in + let state_before = state in + (* Create and reject a commitment at level 0 *) + add_commitment ctxt state Tx_rollup_level.root None + >>=? fun (ctxt, state, _) -> + wrap (Tx_rollup_commitment.reject_commitment ctxt tx_rollup state level0) + >>=? fun (ctxt, state) -> + Alcotest.( + check + tx_rollup_state_testable + "state unchanged by commit/reject at root" + state_before + state) ; + (* Create a commitment at level 0; create and reject a commitment at level 1 *) + add_commitment ctxt state Tx_rollup_level.root None + >>=? fun (ctxt, state, commitment0) -> + let level1 = Tx_rollup_level.succ level0 in + let commitment0_hash = Tx_rollup_commitment.hash commitment0 in + let state_before_reject_1 = state in + add_commitment ctxt state level1 (Some commitment0_hash) + >>=? fun (ctxt, state, _) -> + wrap (Tx_rollup_commitment.reject_commitment ctxt tx_rollup state level1) + >>=? fun (ctxt, state) -> + Alcotest.( + check + tx_rollup_state_testable + "state unchanged by commit/reject at l1" + state_before_reject_1 + state) ; + wrap + (Tx_rollup_commitment.reject_commitment + ctxt + tx_rollup + state + Tx_rollup_level.root) + >>=? fun (ctxt, state) -> + Alcotest.( + check + tx_rollup_state_testable + "state unchanged from initial after rejecting all commitments" + state_before + state) ; + (* Now let's try commitments and rejections when there exist some finalized commits. *) + add_commitment ctxt state level0 None >>=? fun (ctxt, state, commitment0) -> + let commitment0_hash = Tx_rollup_commitment.hash commitment0 in + wrap + (Lwt.return + @@ Tx_rollup_state.Internal_for_tests.record_inbox_deletion state level0) + >>=? fun state -> + let state_before = state in + add_commitment ctxt state level1 (Some commitment0_hash) + >>=? fun (ctxt, state, _commitment1) -> + wrap (Tx_rollup_commitment.reject_commitment ctxt tx_rollup state level1) + >>=? fun (ctxt, state) -> + Alcotest.( + check + tx_rollup_state_testable + "state unchanged after add/reject with one final commitment" + state_before + state) ; + (* Add two commitments and reject the first *) + add_commitment ctxt state level1 (Some commitment0_hash) + >>=? fun (ctxt, state, commitment1) -> + let commitment1_hash = Tx_rollup_commitment.hash commitment1 in + let level2 = Tx_rollup_level.succ level1 in + add_commitment ctxt state level2 (Some commitment1_hash) + >>=? fun (ctxt, state, _commitment2) -> + wrap (Tx_rollup_commitment.reject_commitment ctxt tx_rollup state level1) + >>=? fun (ctxt, state) -> + Alcotest.( + check + tx_rollup_state_testable + "state unchanged after add/reject with one final commitment" + state_before + state) ; + ignore state ; + ignore ctxt ; + ignore i ; + return () + module Withdraw = struct module Nat_ticket = struct let ty_str = "nat" @@ -3115,5 +3233,6 @@ let tests = `Quick test_too_many_commitments; Tztest.tztest "Test bond finalization" `Quick test_bond_finalization; + Tztest.tztest "Test state" `Quick test_state; ] @ Withdraw.tests @ Rejection.tests @ parsing_tests diff --git a/src/proto_alpha/lib_protocol/tx_rollup_commitment_storage.ml b/src/proto_alpha/lib_protocol/tx_rollup_commitment_storage.ml index 7b012ec710..5f755aa1af 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_commitment_storage.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_commitment_storage.ml @@ -105,7 +105,7 @@ let get_finalized : fun ctxt tx_rollup level -> Tx_rollup_state_storage.assert_exist ctxt tx_rollup >>=? fun ctxt -> Storage.Tx_rollup.State.get ctxt tx_rollup >>=? fun (ctxt, state) -> - Tx_rollup_state_repr.finalized_commitments_range state >>?= fun window -> + let window = Tx_rollup_state_repr.finalized_commitments_range state in (match window with | Some (first, last) -> error_unless @@ -214,10 +214,8 @@ let has_bond : >|=? fun (ctxt, pending) -> (ctxt, Option.is_some pending) let finalize_commitment ctxt rollup state = - match - Tx_rollup_state_repr.(oldest_inbox_level state, commitment_head_level state) - with - | (Some oldest_inbox_level, Some _) -> + match Tx_rollup_state_repr.next_commitment_to_finalize state with + | Some oldest_inbox_level -> (* Since the commitment head is not null, we know the oldest inbox has a commitment. *) get ctxt rollup oldest_inbox_level >>=? fun (ctxt, commitment) -> @@ -248,10 +246,10 @@ let finalize_commitment ctxt rollup state = (* We update the state *) Tx_rollup_state_repr.record_inbox_deletion state oldest_inbox_level >>?= fun state -> return (ctxt, state, oldest_inbox_level) - | _ -> fail No_commitment_to_finalize + | None -> fail No_commitment_to_finalize let remove_commitment ctxt rollup state = - match Tx_rollup_state_repr.commitment_tail_level state with + match Tx_rollup_state_repr.next_commitment_to_remove state with | Some tail -> (* We check the commitment is old enough *) get ctxt rollup tail >>=? fun (ctxt, commitment) -> @@ -320,33 +318,33 @@ let get_before_and_after_results ctxt tx_rollup | Some pred_level -> ( Storage.Tx_rollup.Commitment.find ctxt (pred_level, tx_rollup) >>=? function - | (ctxt, None) -> + | (ctxt, None) -> ( (* In this case, the predecessor commitment is not stored. We need to check a bunch of things to ensure that the last removed commitment is a valid predecessor. *) - if Option.is_none (Tx_rollup_state_repr.commitment_tail_level state) - then - match - Tx_rollup_state_repr.last_removed_commitment_hashes state - with - | None -> fail (Internal_error "Missing last removed commitment") - | Some (message_commitment, commitment_hash) -> - Option.value_e - ~error: - (Error_monad.trace_of_error - (Internal_error - "Non-initial commitment has empty predecessor")) - commitment.predecessor - >>?= fun predecessor_commitment_hash -> - fail_unless - (Commitment_hash.( = ) - predecessor_commitment_hash - commitment_hash) - (Internal_error - "Last removed commitment has wrong predecessor hash") - >>=? fun () -> return (ctxt, message_commitment, after_hash) - else fail (Internal_error "Missing commitment predecessor") + fail_unless + (Option.is_none + (Tx_rollup_state_repr.finalized_commitment_oldest_level state)) + (Internal_error "Missing commitment predecessor") + >>=? fun () -> + match Tx_rollup_state_repr.last_removed_commitment_hashes state with + | None -> fail (Internal_error "Missing last removed commitment") + | Some (message_commitment, commitment_hash) -> + Option.value_e + ~error: + (Error_monad.trace_of_error + (Internal_error + "Non-initial commitment has empty predecessor")) + commitment.predecessor + >>?= fun predecessor_commitment_hash -> + fail_unless + (Commitment_hash.( = ) + predecessor_commitment_hash + commitment_hash) + (Internal_error + "Last removed commitment has wrong predecessor hash") + >>=? fun () -> return (ctxt, message_commitment, after_hash)) | (ctxt, Some {commitment = {messages; _}; _}) -> Option.value_e ~error: @@ -362,28 +360,20 @@ let get_before_and_after_results ctxt tx_rollup return (ctxt, before_hash, after_hash) let reject_commitment ctxt rollup state level = - match - Tx_rollup_state_repr.(oldest_inbox_level state, commitment_head_level state) - with - | (Some inbox_tail, Some commitment_head) -> - fail_unless - Tx_rollup_level_repr.(inbox_tail <= level && level <= commitment_head) - Invalid_rejection_level_argument - >>=? fun () -> - (* Fetching the next predecessor hash to be used *) - (match Tx_rollup_level_repr.pred level with - | Some pred_level -> - find ctxt rollup pred_level >>=? fun (ctxt, pred_commitment) -> - let pred_hash = - Option.map - (fun (x : Submitted_commitment.t) -> - Tx_rollup_commitment_repr.hash x.commitment) - pred_commitment - in - return (ctxt, pred_hash) - | None -> return (ctxt, None)) - (* We record in the state *) - >>=? fun (ctxt, pred_hash) -> - Tx_rollup_state_repr.record_commitment_rejection state level pred_hash - >>?= fun state -> return (ctxt, state) - | _ -> fail Invalid_rejection_level_argument + Tx_rollup_state_repr.check_level_can_be_rejected state level >>?= fun () -> + (* Fetching the next predecessor hash to be used *) + (match Tx_rollup_level_repr.pred level with + | Some pred_level -> + find ctxt rollup pred_level >>=? fun (ctxt, pred_commitment) -> + let pred_hash = + Option.map + (fun (x : Submitted_commitment.t) -> + Tx_rollup_commitment_repr.hash x.commitment) + pred_commitment + in + return (ctxt, pred_hash) + | None -> return (ctxt, None)) + (* We record in the state *) + >>=? fun (ctxt, pred_hash) -> + Tx_rollup_state_repr.record_commitment_rejection state level pred_hash + >>?= fun state -> return (ctxt, state) diff --git a/src/proto_alpha/lib_protocol/tx_rollup_inbox_storage.ml b/src/proto_alpha/lib_protocol/tx_rollup_inbox_storage.ml index 07fe36c7f9..41c21090c7 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_inbox_storage.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_inbox_storage.ml @@ -84,8 +84,8 @@ let prepare_inbox : <= Tx_rollup_state_repr.inboxes_count state) Too_many_inboxes >>=? fun () -> - let current_level = Tx_rollup_state_repr.head_level state in - match current_level with + let current_levels = Tx_rollup_state_repr.head_levels state in + match current_levels with | Some (_, tezos_lvl) when Raw_level_repr.(level < tezos_lvl) -> fail (Internal_error "Trying to write into an inbox from the past") | Some (tx_lvl, tezos_lvl) when Raw_level_repr.(tezos_lvl = level) -> @@ -97,7 +97,7 @@ let prepare_inbox : Option.fold ~none:None ~some:(fun (tx_level, _) -> Tx_rollup_level_repr.pred tx_level) - current_level + current_levels in (match pred_level with | None -> return (ctxt, state) @@ -110,7 +110,7 @@ let prepare_inbox : Constants_storage.tx_rollup_cost_per_byte_ema_factor ctxt in let elapsed = - match current_level with + match current_levels with | None -> 0 | Some (_, tezos_level) -> let diff = Raw_level_repr.diff level tezos_level in diff --git a/src/proto_alpha/lib_protocol/tx_rollup_state_repr.ml b/src/proto_alpha/lib_protocol/tx_rollup_state_repr.ml index 063404eac6..34897f1d2a 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_state_repr.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_state_repr.ml @@ -27,6 +27,94 @@ open Tx_rollup_errors_repr +type range = + | Interval of { + oldest : Tx_rollup_level_repr.t; + newest : Tx_rollup_level_repr.t; + } + | Empty of {next : Tx_rollup_level_repr.t} + +let range_newest = function Interval {newest; _} -> Some newest | _ -> None + +let range_oldest = function Interval {oldest; _} -> Some oldest | _ -> None + +let extend = function + | Empty {next} -> (Interval {oldest = next; newest = next}, next) + | Interval {oldest; newest} -> + let newest = Tx_rollup_level_repr.succ newest in + (Interval {oldest; newest}, newest) + +let shrink = function + | Empty _ -> error (Internal_error "cannot shrink range") + | Interval {oldest; newest} when Tx_rollup_level_repr.(oldest < newest) -> + ok (Interval {oldest = Tx_rollup_level_repr.succ oldest; newest}) + | Interval {newest; oldest = _} -> + ok (Empty {next = Tx_rollup_level_repr.succ newest}) + +let belongs_to range level = + match range with + | Empty _ -> false + | Interval {oldest; newest} -> + Tx_rollup_level_repr.(oldest <= level && level <= newest) + +let right_cut range level = + match Tx_rollup_level_repr.pred level with + | None -> ok (Empty {next = Tx_rollup_level_repr.root}) + | Some predecessor -> ( + match range with + | Interval {oldest; newest = _} when belongs_to range level -> + if Tx_rollup_level_repr.(oldest <= predecessor) then + ok (Interval {oldest; newest = predecessor}) + else ok (Empty {next = level}) + | _ -> error (Internal_error "cannot cut range")) + +let left_extend range level = + match range with + | Interval {oldest = _; newest} -> ok (Interval {oldest = level; newest}) + | Empty {next} -> + let newest = + Option.value ~default:level (Tx_rollup_level_repr.pred next) + in + ok (Interval {oldest = level; newest}) + +let range_count = function + | Empty _ -> 0 + | Interval {oldest; newest} -> + Int32.(succ @@ Tx_rollup_level_repr.diff newest oldest |> to_int) + +let range_encoding : range Data_encoding.t = + Data_encoding.( + union + [ + case + (Tag 0) + ~title:"empty" + (obj1 (req "next" Tx_rollup_level_repr.encoding)) + (function Empty {next} -> Some next | _ -> None) + (fun next -> Empty {next}); + case + (Tag 1) + ~title:"interval" + (obj2 + (req "newest" Tx_rollup_level_repr.encoding) + (req "oldest" Tx_rollup_level_repr.encoding)) + (function + | Interval {newest; oldest} -> Some (newest, oldest) | _ -> None) + (fun (newest, oldest) -> Interval {newest; oldest}); + ]) + +let pp_range fmt = function + | Empty {next} -> Format.(fprintf fmt "next: %a" Tx_rollup_level_repr.pp next) + | Interval {oldest; newest} -> + Format.( + fprintf + fmt + "oldest: %a newest: %a" + Tx_rollup_level_repr.pp + oldest + Tx_rollup_level_repr.pp + newest) + (** The state of a transaction rollup is composed of [burn_per_byte] and [inbox_ema] fields. [initial_state] introduces their initial values. Both values are updated by [update_burn_per_byte] as the @@ -46,16 +134,16 @@ open Tx_rollup_errors_repr The state of the transaction rollup also keeps track of four pointers to four different rollup levels. - - The [commitment_tail_level] is the level of the oldest + - The [commitment_oldest_level] is the level of the oldest finalized commitment still stored in the layer-1 storage. - - The [commitment_head_level] is the level of the most recent + - The [commitment_newest_level] is the level of the most recent unfinalized commitment in the layer-1 storage. - The [oldest_inbox_level] is the level of the oldest inbox still stored in the layer-1 storage. - - The [head_level] is the level of the most recent inbox in the + - The [newest_level] is the level of the most recent inbox in the layer-1 storage. *) type t = { @@ -63,12 +151,11 @@ type t = { (Tx_rollup_commitment_repr.Message_result_hash.t * Tx_rollup_commitment_repr.Commitment_hash.t) option; - commitment_tail_level : Tx_rollup_level_repr.t option; - oldest_inbox_level : Tx_rollup_level_repr.t option; - commitment_head_level : - (Tx_rollup_level_repr.t * Tx_rollup_commitment_repr.Commitment_hash.t) - option; - head_level : (Tx_rollup_level_repr.t * Raw_level_repr.t) option; + finalized_commitments : range; + unfinalized_commitments : range; + uncommitted_inboxes : range; + commitment_newest_hash : Tx_rollup_commitment_repr.Commitment_hash.t option; + tezos_head_level : Raw_level_repr.t option; burn_per_byte : Tez_repr.t; inbox_ema : int; } @@ -83,73 +170,49 @@ type t = { yet. Because inboxes and commitments can be removed from the layer-1 context under certain circumstances, they can be reset to [None]. - Given [CT] the commitment tail, [OI] the oldest inbox, [CH] the - commitment head, and [H] the head, a typical rollup state is + The state allows us to keep track of three intervals: the finalized + commitments (whose inboxes have been removed from the layer-1 + storage), the unfinalized commitments (whose inboxes are still in + the layer-1 storage), and uncommitted inboxes (that is, inboxes + which are still waiting for a commitment). finalized uncommitted ^^^^^^ ^^^^^^^^ - CT CH [------------] commitments [--------------] inboxes - OI H ^^^^^^^^ unfinalized - Note that the oldest inbox level is not always lesser than the - commitment head. If the commitment head is equal to [None], it - means all the inboxes currently stored in layer-1 are “uncommitted”, - that is, no commitments have been submitted for them. - - In such a case, the rollup state is analoguous to + Note that this layout is not the only one that we can witness in + the layer-1 storage, even if it is the more common. It is possible + for instance that there is no unfinalized commitments at a given + time. finalized ^^^^^^ - CT - [-----[ commitments + [----] commitments [--------------] inboxes - OI H ^^^^^^^^^^^^^^^^ uncommitted - Similarly, it is possible to see the oldest inbox level and head level - set to [None]. For instance, when each commitment in the - layer-1 storage has been properly finalized. In this case, the - layout will be + Or that we have no more inboxes, but only finalized commitments. finalized ^^^^^^ CT - [-----[ commitments - [ inboxes - - - When a pointer is reset to [None], its next value will be decided - by its previous value. For instance, when the oldest inbox level is - set from [Some l] to [None], its next value is the successor level - of [l]. - - To implement this behavior, this module relies on four fields and - four functions which share the same name. Once set to a given - value, the fields are never set back to [None]. It is the purpose - of the functions to determine if a value is correct, or kept in - memory for future use, and only the functions are exposed to other - modules. - - Let’s take the [oldest_inbox_level], for instance. It is supposed - to be [None] iff there is no “uncommitted” inbox in the context, - and we can retreive the number of uncommitted inbox by computing - the difference between the fields [head_level] and - [oldest_inbox_level]. + [-----] commitments + inboxes *) let initial_state = { last_removed_commitment_hashes = None; - commitment_tail_level = None; - oldest_inbox_level = None; - commitment_head_level = None; - head_level = None; + finalized_commitments = Empty {next = Tx_rollup_level_repr.root}; + unfinalized_commitments = Empty {next = Tx_rollup_level_repr.root}; + uncommitted_inboxes = Empty {next = Tx_rollup_level_repr.root}; + commitment_newest_hash = None; + tezos_head_level = None; burn_per_byte = Tez_repr.zero; inbox_ema = 0; } @@ -159,37 +222,41 @@ let encoding : t Data_encoding.t = conv (fun { last_removed_commitment_hashes; - commitment_tail_level; - oldest_inbox_level; - commitment_head_level; - head_level; + finalized_commitments; + unfinalized_commitments; + uncommitted_inboxes; + commitment_newest_hash; + tezos_head_level; burn_per_byte; inbox_ema; } -> ( last_removed_commitment_hashes, - commitment_tail_level, - oldest_inbox_level, - commitment_head_level, - head_level, + finalized_commitments, + unfinalized_commitments, + uncommitted_inboxes, + commitment_newest_hash, + tezos_head_level, burn_per_byte, inbox_ema )) (fun ( last_removed_commitment_hashes, - commitment_tail_level, - oldest_inbox_level, - commitment_head_level, - head_level, + finalized_commitments, + unfinalized_commitments, + uncommitted_inboxes, + commitment_newest_hash, + tezos_head_level, burn_per_byte, inbox_ema ) -> { last_removed_commitment_hashes; - commitment_tail_level; - oldest_inbox_level; - commitment_head_level; - head_level; + finalized_commitments; + unfinalized_commitments; + uncommitted_inboxes; + commitment_newest_hash; + tezos_head_level; burn_per_byte; inbox_ema; }) - (obj7 + (obj8 (req "last_removed_commitment_hashes" (option @@ -200,64 +267,47 @@ let encoding : t Data_encoding.t = (req "commitment_hash" Tx_rollup_commitment_repr.Commitment_hash.encoding))) - (req "commitment_tail_level" (option Tx_rollup_level_repr.encoding)) - (req "oldest_inbox_level" (option Tx_rollup_level_repr.encoding)) - (req - "commitment_head_level" - (option - (obj2 - (req "level" Tx_rollup_level_repr.encoding) - (req "hash" Tx_rollup_commitment_repr.Commitment_hash.encoding)))) + (req "finalized_commitments" range_encoding) + (req "unfinalized_commitments" range_encoding) + (req "uncommitted_inboxes" range_encoding) (req - "head_level" - (option - (obj2 - (req "level" Tx_rollup_level_repr.encoding) - (req "tezos_level" Raw_level_repr.encoding)))) + "commitment_newest_hash" + (option Tx_rollup_commitment_repr.Commitment_hash.encoding)) + (req "tezos_head_level" (option Raw_level_repr.encoding)) (req "burn_per_byte" Tez_repr.encoding) (req "inbox_ema" int31)) let pp fmt { last_removed_commitment_hashes; - commitment_tail_level; - oldest_inbox_level; - commitment_head_level; - head_level; + finalized_commitments; + unfinalized_commitments; + uncommitted_inboxes; + commitment_newest_hash; + tezos_head_level; burn_per_byte; inbox_ema; } = Format.( fprintf fmt - "oldest_inbox_level: %a cost_per_byte: %a inbox_ema: %d head inbox: %a \ - commitment tail: %a commitment head: %a last_removed_commitment_hashes: \ - %a" - (Format.pp_print_option Tx_rollup_level_repr.pp) - oldest_inbox_level + "cost_per_byte: %a inbox_ema: %d finalized_commitments: %a \ + unfinalized_commitments: %a uncommitted_inboxes: %a \ + commitment_newest_hash: %a tezos_head_level: %a \ + last_removed_commitment_hashes: %a" Tez_repr.pp burn_per_byte inbox_ema - (pp_print_option (fun fmt (tx_lvl, tezos_lvl) -> - fprintf - fmt - "(rollup level: %a, tezos level: %a)" - Tx_rollup_level_repr.pp - tx_lvl - Raw_level_repr.pp - tezos_lvl)) - head_level - (Format.pp_print_option Tx_rollup_level_repr.pp) - commitment_tail_level - (pp_print_option (fun fmt (tx_lvl, tezos_lvl) -> - fprintf - fmt - "(rollup level: %a, commitment: %a)" - Tx_rollup_level_repr.pp - tx_lvl - Tx_rollup_commitment_repr.Commitment_hash.pp - tezos_lvl)) - commitment_head_level + pp_range + finalized_commitments + pp_range + unfinalized_commitments + pp_range + uncommitted_inboxes + (pp_print_option Tx_rollup_commitment_repr.Commitment_hash.pp) + commitment_newest_hash + (pp_print_option Raw_level_repr.pp) + tezos_head_level (pp_print_option (fun fmt (m, c) -> fprintf fmt @@ -332,114 +382,67 @@ let rec update_burn_per_byte : let elapsed = elapsed - 1 in update_burn_per_byte state' ~elapsed ~factor ~final_size ~hard_limit -let inboxes_count {head_level; oldest_inbox_level; _} = - match (oldest_inbox_level, head_level) with - | (Some oldest_level, Some (newest_level, _)) -> - let delta = - (* [Int32.succ] because the range is inclusive, i.e., [l; l] - has one inbox at level [l]. *) - Int32.succ @@ Tx_rollup_level_repr.diff newest_level oldest_level - in - Compare.Int32.max 0l delta |> Int32.to_int - | _ -> 0 - -let committed_inboxes_count {oldest_inbox_level; commitment_head_level; _} = - match (oldest_inbox_level, commitment_head_level) with - | (Some oldest_level, Some (newest_level, _)) -> - let delta = - (* [Int32.succ] because the range is inclusive, i.e., [l; l] - has one committed inbox at level [l]. *) - Int32.succ @@ Tx_rollup_level_repr.diff newest_level oldest_level - in - Compare.Int32.max 0l delta |> Int32.to_int - | _ -> 0 - -let uncommitted_inboxes_count {head_level; commitment_head_level; _} = - match (commitment_head_level, head_level) with - | (Some (oldest_level, _), Some (newest_level, _)) -> - let delta = - (* No [Int32.succ] because the range is not inclusive. More - precisely, the [commitment_head_level] has one commitment, - and therefore is not part of the count. *) - Tx_rollup_level_repr.diff newest_level oldest_level - in - Compare.Int32.max 0l delta |> Int32.to_int - | _ -> 0 - -let finalized_commitments_count {commitment_tail_level; oldest_inbox_level; _} = - match (commitment_tail_level, oldest_inbox_level) with - | (Some oldest_level, Some newest_level) -> - let delta = - (* No [Int32.succ] because the range is not inclusive. More - precisely, the [oldest_inbox_level] has not yet been - finalized. *) - Tx_rollup_level_repr.diff newest_level oldest_level - in - Compare.Int32.max 0l delta |> Int32.to_int - | _ -> 0 +let inboxes_count {unfinalized_commitments; uncommitted_inboxes; _} = + range_count unfinalized_commitments + range_count uncommitted_inboxes -let commitment_head_level state = - if Compare.Int.(committed_inboxes_count state = 0) then None - else Option.map fst state.commitment_head_level +let uncommitted_inboxes_count {uncommitted_inboxes; _} = + range_count uncommitted_inboxes -let commitment_tail_level state = - if Compare.Int.(finalized_commitments_count state = 0) then None - else state.commitment_tail_level +let finalized_commitments_count {finalized_commitments; _} = + range_count finalized_commitments -let head_level state = - if Compare.Int.(inboxes_count state = 0) then None else state.head_level +let record_inbox_creation t level = + (match t.tezos_head_level with + | Some tezos_lvl -> + error_when + Raw_level_repr.(level <= tezos_lvl) + (Internal_error "Trying to create an inbox in the past") + | None -> ok ()) + >>? fun () -> + let (uncommitted_inboxes, new_level) = extend t.uncommitted_inboxes in + ok ({t with tezos_head_level = Some level; uncommitted_inboxes}, new_level) + +let next_commitment_predecessor state = state.commitment_newest_hash -let oldest_inbox_level state = - if Compare.Int.(inboxes_count state = 0) then None - else state.oldest_inbox_level +let finalized_commitment_oldest_level state = + range_oldest state.finalized_commitments let next_commitment_level state = - match (commitment_head_level state, oldest_inbox_level state) with - | (Some commitment_head, Some _) -> - ok (Tx_rollup_level_repr.succ commitment_head) - | (None, Some oldest_inbox) -> ok oldest_inbox - | (_, _) -> error No_uncommitted_inbox + match range_oldest state.uncommitted_inboxes with + | Some level -> ok level + | None -> error No_uncommitted_inbox -let next_commitment_predecessor state = - Option.map snd state.commitment_head_level +let next_commitment_to_finalize state = + range_oldest state.unfinalized_commitments -let record_inbox_creation t level = - (match t.head_level with - | Some (tx_lvl, tezos_lvl) -> - (if Raw_level_repr.(level <= tezos_lvl) then - error (Internal_error "Trying to create an inbox in the past") - else ok ()) - >>? fun () -> ok (Tx_rollup_level_repr.succ tx_lvl) - | None -> ok Tx_rollup_level_repr.root) - >>? fun tx_level -> - let oldest_inbox_level = - Some (Option.value ~default:tx_level t.oldest_inbox_level) - in - ok ({t with head_level = Some (tx_level, level); oldest_inbox_level}, tx_level) +let next_commitment_to_remove state = range_oldest state.finalized_commitments let record_inbox_deletion state candidate = - match state.oldest_inbox_level with - | Some level - when Compare.Int.(0 < inboxes_count state) - && Tx_rollup_level_repr.(candidate = level) -> - let oldest_inbox_level = Some (Tx_rollup_level_repr.succ level) in - ok {state with oldest_inbox_level} + match range_oldest state.unfinalized_commitments with + | Some level when Tx_rollup_level_repr.(candidate = level) -> + shrink state.unfinalized_commitments >>? fun unfinalized_commitments -> + let (finalized_commitments, _) = extend state.finalized_commitments in + ok {state with unfinalized_commitments; finalized_commitments} | _ -> error (Internal_error "Trying to delete the wrong inbox") let record_commitment_creation state level hash = - let commitment_tail_level = - Some (Option.value ~default:level state.commitment_tail_level) - in - let state = {state with commitment_tail_level} in - match (commitment_head_level state, oldest_inbox_level state) with - | (Some commitment_head, Some _) - when Tx_rollup_level_repr.(level = succ commitment_head) -> - ok {state with commitment_head_level = Some (level, hash)} - | (None, Some oldest) when Tx_rollup_level_repr.(level = oldest) -> - ok {state with commitment_head_level = Some (level, hash)} - | _ -> - error - (Internal_error "Trying to create a commitment at an incorrect level") + match range_oldest state.uncommitted_inboxes with + | Some oldest -> + error_unless + Tx_rollup_level_repr.(level = oldest) + (Internal_error "Trying to create the wrong commitment") + >>? fun () -> + shrink state.uncommitted_inboxes >>? fun uncommitted_inboxes -> + let (unfinalized_commitments, _) = extend state.unfinalized_commitments in + ok + { + state with + uncommitted_inboxes; + unfinalized_commitments; + commitment_newest_hash = Some hash; + } + | None -> + error (Internal_error "Cannot create a commitment due to lack of inbox") let record_commitment_rejection state level predecessor_hash = let unwrap_option msg = function @@ -450,39 +453,49 @@ let record_commitment_rejection state level predecessor_hash = | None -> ok () | Some _ -> error (Internal_error msg) in - match (oldest_inbox_level state, commitment_head_level state) with - | (Some inbox_tail, Some commitment_head) - when Tx_rollup_level_repr.(inbox_tail <= level && level <= commitment_head) - -> ( - match (commitment_tail_level state, Tx_rollup_level_repr.pred level) with - | (Some commitment_tail, Some pred_level) - when Tx_rollup_level_repr.(commitment_tail <= pred_level) -> - unwrap_option "Missing predecessor commitment" predecessor_hash - >>? fun pred_hash -> - ok {state with commitment_head_level = Some (pred_level, pred_hash)} - | (None, Some pred_level) -> - check_none "Unexpected predecessor hash" predecessor_hash - >>? fun () -> - unwrap_option - "Missing commitment hash" - state.last_removed_commitment_hashes - >>? fun (_, pred_hash) -> - ok {state with commitment_head_level = Some (pred_level, pred_hash)} - | (None, None) -> - check_none - "Unexpected last removed commitment" - state.last_removed_commitment_hashes - >>? fun () -> ok {state with commitment_head_level = None} - | _ -> error (Internal_error "Machine state inconsistency")) - | _ -> error (Internal_error "No commitment to reject") + left_extend state.uncommitted_inboxes level >>? fun uncommitted_inboxes -> + let state = {state with uncommitted_inboxes} in + right_cut state.unfinalized_commitments level + >>? fun unfinalized_commitments -> + match Tx_rollup_level_repr.pred level with + | Some pred_level + when belongs_to state.unfinalized_commitments pred_level + || belongs_to state.finalized_commitments pred_level -> + (* Case 1. Predecessor level of the rejected commitments has a commitment in the storage *) + unwrap_option "Missing predecessor commitment" predecessor_hash + >>? fun predecessor_hash -> + ok + { + state with + unfinalized_commitments; + commitment_newest_hash = Some predecessor_hash; + } + | Some _ -> + (* Case 2. Predecessor level of the rejected commitments has its + commitment removed from the storage *) + check_none "Unexpected predecessor hash" predecessor_hash >>? fun () -> + unwrap_option + "Missing commitment hash" + state.last_removed_commitment_hashes + >>? fun (_, pred_hash) -> + ok + { + state with + unfinalized_commitments; + commitment_newest_hash = Some pred_hash; + } + | None -> + (* Case 3. The rejected commitment is the commitment of the root level *) + ok {state with unfinalized_commitments; commitment_newest_hash = None} let record_commitment_deletion state level hash message_hash = - match commitment_tail_level state with - | Some tail when Tx_rollup_level_repr.(level = tail) -> + match range_oldest state.finalized_commitments with + | Some oldest when Tx_rollup_level_repr.(level = oldest) -> + shrink state.finalized_commitments >>? fun finalized_commitments -> ok { state with - commitment_tail_level = Some (Tx_rollup_level_repr.succ tail); + finalized_commitments; last_removed_commitment_hashes = Some (message_hash, hash); } | _ -> error (Internal_error "Trying to remove an incorrect commitment") @@ -495,33 +508,33 @@ let burn_cost ~limit state size = | _ -> ok burn let finalized_commitments_range state = - if Compare.Int.(0 < finalized_commitments_count state) then - match (state.commitment_tail_level, state.oldest_inbox_level) with - | (Some commitment_tail, Some oldest_inbox) -> ( - match Tx_rollup_level_repr.pred oldest_inbox with - | Some res -> ok (Some (commitment_tail, res)) - | None -> - error - (Internal_error - "oldest inbox has no predecessor, but commitments have been \ - finalized")) - | (_, _) -> - error - (Internal_error - "unreachable code per definition of [finalized_commitments_count]") - else ok None + match + ( range_oldest state.finalized_commitments, + range_newest state.finalized_commitments ) + with + | (Some oldest, Some newest) -> Some (oldest, newest) + | _ -> None let check_level_can_be_rejected state level = - match (oldest_inbox_level state, commitment_head_level state) with + match + ( range_oldest state.unfinalized_commitments, + range_newest state.unfinalized_commitments ) + with | (Some oldest, Some newest) -> error_unless Tx_rollup_level_repr.(oldest <= level && level <= newest) @@ Cannot_reject_level {provided = level; accepted_range = Some (oldest, newest)} - | (_, _) -> - error @@ Cannot_reject_level {provided = level; accepted_range = None} + | _ -> error @@ Cannot_reject_level {provided = level; accepted_range = None} let last_removed_commitment_hashes state = state.last_removed_commitment_hashes +let head_levels state = + match (state.uncommitted_inboxes, state.tezos_head_level) with + | (Empty {next = l}, Some tz_level) -> + Option.map (fun l -> (l, tz_level)) (Tx_rollup_level_repr.pred l) + | (Interval {newest; _}, Some tz_level) -> Some (newest, tz_level) + | _ -> None + module Internal_for_tests = struct let make : ?burn_per_byte:Tez_repr.t -> @@ -529,29 +542,42 @@ module Internal_for_tests = struct ?last_removed_commitment_hashes: Tx_rollup_commitment_repr.Message_result_hash.t * Tx_rollup_commitment_repr.Commitment_hash.t -> - ?commitment_tail_level:Tx_rollup_level_repr.t -> - ?oldest_inbox_level:Tx_rollup_level_repr.t -> - ?commitment_head_level: - Tx_rollup_level_repr.t * Tx_rollup_commitment_repr.Commitment_hash.t -> - ?head_level:Tx_rollup_level_repr.t * Raw_level_repr.t -> + ?finalized_commitments:Tx_rollup_level_repr.t * Tx_rollup_level_repr.t -> + ?unfinalized_commitments:Tx_rollup_level_repr.t * Tx_rollup_level_repr.t -> + ?uncommitted_inboxes:Tx_rollup_level_repr.t * Tx_rollup_level_repr.t -> + ?commitment_newest_hash:Tx_rollup_commitment_repr.Commitment_hash.t -> + ?tezos_head_level:Raw_level_repr.t -> unit -> t = fun ?(burn_per_byte = Tez_repr.zero) ?(inbox_ema = 0) ?last_removed_commitment_hashes - ?commitment_tail_level - ?oldest_inbox_level - ?commitment_head_level - ?head_level + ?finalized_commitments + ?unfinalized_commitments + ?uncommitted_inboxes + ?commitment_newest_hash + ?tezos_head_level () -> + let to_range = function + | Some (oldest, newest) -> + assert (Tx_rollup_level_repr.(oldest <= newest)) ; + Interval {oldest; newest} + | _ -> Empty {next = Tx_rollup_level_repr.root} + in + + let unfinalized_commitments = to_range unfinalized_commitments in + let finalized_commitments = to_range finalized_commitments in + let uncommitted_inboxes = to_range uncommitted_inboxes in + { last_removed_commitment_hashes; burn_per_byte; inbox_ema; - commitment_tail_level; - oldest_inbox_level; - commitment_head_level; - head_level; + finalized_commitments; + unfinalized_commitments; + uncommitted_inboxes; + commitment_newest_hash; + tezos_head_level; } let get_inbox_ema : t -> int = fun {inbox_ema; _} -> inbox_ema diff --git a/src/proto_alpha/lib_protocol/tx_rollup_state_repr.mli b/src/proto_alpha/lib_protocol/tx_rollup_state_repr.mli index 784e58bf35..7831275d50 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_state_repr.mli +++ b/src/proto_alpha/lib_protocol/tx_rollup_state_repr.mli @@ -71,20 +71,6 @@ val update_burn_per_byte : *) val burn_cost : limit:Tez_repr.t option -> t -> int -> Tez_repr.t tzresult -(** [head_level state] returns the rollup level of the most recent - inbox —if it exists— long with the Tezos level at which this inbox - was created. *) -val head_level : t -> (Tx_rollup_level_repr.t * Raw_level_repr.t) option - -(** [commitment_head_level state] returns the rollup level of the most - recent unfinalized commitment, if it exists. *) -val commitment_head_level : t -> Tx_rollup_level_repr.t option - -(** [commitment_tail_level state] returns the rollup level of the - oldest finalized commitment still in the layer-1 context, if it - exists. *) -val commitment_tail_level : t -> Tx_rollup_level_repr.t option - (** [uncommitted_inboxes_count state] returns the number of inboxes the rollup current has in the storage which did not receive a commitment yet. *) @@ -98,9 +84,17 @@ val finalized_commitments_count : t -> int current has in the storage. *) val inboxes_count : t -> int -(** [oldest_inbox_level state] returns the level of the oldest inbox - of a rollup that is still in the layer-1 context, if it exists. *) -val oldest_inbox_level : t -> Tx_rollup_level_repr.t option +(** [next_commitment_to_finalize state] returns the rollup level of + the next commitment to be finalized. *) +val next_commitment_to_finalize : t -> Tx_rollup_level_repr.t option + +(** [next_commitment_to_remove state] returns the rollup level of the + next commitment to be removed from the layer-1 context. *) +val next_commitment_to_remove : t -> Tx_rollup_level_repr.t option + +(** [finalized_commitment_oldest_level state] returns the rollup level + of the oldest finalized commitment. *) +val finalized_commitment_oldest_level : t -> Tx_rollup_level_repr.t option (** [next_commitment_level state] returns the expected level of the next valid commitment. @@ -178,10 +172,10 @@ val record_commitment_deletion : (** [finalized_commitments_range state] returns the window of finalized commitments that have not yet been cleaned out - This function returns an [Internal_error] if the state is inconsistent, + This function returns an [Internal_error] if the state is inconsistent, which should not be possible. *) val finalized_commitments_range : - t -> (Tx_rollup_level_repr.t * Tx_rollup_level_repr.t) option tzresult + t -> (Tx_rollup_level_repr.t * Tx_rollup_level_repr.t) option (** [check_level_can_be_rejected state level] raises [Cannot_reject_level] iff there does not exist a commitment at @@ -197,6 +191,11 @@ val last_removed_commitment_hashes : * Tx_rollup_commitment_repr.Commitment_hash.t) option +(** [head_levels state] returns the level of the last inbox which has + been created in the layer-1 context, along with the Tezos level at + which said inbox has been created. *) +val head_levels : t -> (Tx_rollup_level_repr.t * Raw_level_repr.t) option + module Internal_for_tests : sig (** [make] returns a state for tests *) val make : @@ -205,11 +204,11 @@ module Internal_for_tests : sig ?last_removed_commitment_hashes: Tx_rollup_commitment_repr.Message_result_hash.t * Tx_rollup_commitment_repr.Commitment_hash.t -> - ?commitment_tail_level:Tx_rollup_level_repr.t -> - ?oldest_inbox_level:Tx_rollup_level_repr.t -> - ?commitment_head_level: - Tx_rollup_level_repr.t * Tx_rollup_commitment_repr.Commitment_hash.t -> - ?head_level:Tx_rollup_level_repr.t * Raw_level_repr.t -> + ?finalized_commitments:Tx_rollup_level_repr.t * Tx_rollup_level_repr.t -> + ?unfinalized_commitments:Tx_rollup_level_repr.t * Tx_rollup_level_repr.t -> + ?uncommitted_inboxes:Tx_rollup_level_repr.t * Tx_rollup_level_repr.t -> + ?commitment_newest_hash:Tx_rollup_commitment_repr.Commitment_hash.t -> + ?tezos_head_level:Raw_level_repr.t -> unit -> t diff --git a/tezt/_regressions/tx_rollup_batch_encoding.out b/tezt/_regressions/tx_rollup_batch_encoding.out index fee5052f59..bea72e4622 100644 --- a/tezt/_regressions/tx_rollup_batch_encoding.out +++ b/tezt/_regressions/tx_rollup_batch_encoding.out @@ -2,7 +2,7 @@ tezt/_regressions/tx_rollup_batch_encoding.out ./tezos-client --wait none originate tx rollup from '[PUBLIC_KEY_HASH]' --burn-cap 9999999 --storage-limit 60000 Node is bootstrapped. -Estimated gas: 1410.040 units (will add 100 for safety) +Estimated gas: 1410.092 units (will add 100 for safety) Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' NOT waiting for the operation to be included. @@ -25,13 +25,13 @@ This sequence of operations was run: Balance updates: [PUBLIC_KEY_HASH] ... -ꜩ15 storage fees ........................... +ꜩ15 - Consumed gas: 1410.040 + Consumed gas: 1410.092 Originated tx rollup: [TX_ROLLUP_HASH] ./tezos-client --wait none submit tx rollup batch 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' Node is bootstrapped. -Estimated gas: 2021.864 units (will add 100 for safety) +Estimated gas: 2021.926 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -53,6 +53,6 @@ This sequence of operations was run: This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2021.864 + Consumed gas: 2021.926 "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" diff --git a/tezt/_regressions/tx_rollup_finalize_commitment_future.out b/tezt/_regressions/tx_rollup_finalize_commitment_future.out index 6f42e5f4c2..cc80e3e4e6 100644 --- a/tezt/_regressions/tx_rollup_finalize_commitment_future.out +++ b/tezt/_regressions/tx_rollup_finalize_commitment_future.out @@ -2,7 +2,7 @@ tezt/_regressions/tx_rollup_finalize_commitment_future.out ./tezos-client --wait none originate tx rollup from '[PUBLIC_KEY_HASH]' --burn-cap 9999999 --storage-limit 60000 Node is bootstrapped. -Estimated gas: 1410.040 units (will add 100 for safety) +Estimated gas: 1410.092 units (will add 100 for safety) Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' NOT waiting for the operation to be included. @@ -25,13 +25,13 @@ This sequence of operations was run: Balance updates: [PUBLIC_KEY_HASH] ... -ꜩ15 storage fees ........................... +ꜩ15 - Consumed gas: 1410.040 + Consumed gas: 1410.092 Originated tx rollup: [TX_ROLLUP_HASH] ./tezos-client --wait none submit tx rollup batch 626c6f62 to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' Node is bootstrapped. -Estimated gas: 2021.296 units (will add 100 for safety) +Estimated gas: 2021.358 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -53,7 +53,7 @@ This sequence of operations was run: This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2021.296 + Consumed gas: 2021.358 ./tezos-client --wait none submit tx rollup finalize commitment to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' diff --git a/tezt/_regressions/tx_rollup_finalize_commitment_no_batch.out b/tezt/_regressions/tx_rollup_finalize_commitment_no_batch.out index 276a8a2049..4f2be1fcdc 100644 --- a/tezt/_regressions/tx_rollup_finalize_commitment_no_batch.out +++ b/tezt/_regressions/tx_rollup_finalize_commitment_no_batch.out @@ -2,7 +2,7 @@ tezt/_regressions/tx_rollup_finalize_commitment_no_batch.out ./tezos-client --wait none originate tx rollup from '[PUBLIC_KEY_HASH]' --burn-cap 9999999 --storage-limit 60000 Node is bootstrapped. -Estimated gas: 1410.040 units (will add 100 for safety) +Estimated gas: 1410.092 units (will add 100 for safety) Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' NOT waiting for the operation to be included. @@ -25,7 +25,7 @@ This sequence of operations was run: Balance updates: [PUBLIC_KEY_HASH] ... -ꜩ15 storage fees ........................... +ꜩ15 - Consumed gas: 1410.040 + Consumed gas: 1410.092 Originated tx rollup: [TX_ROLLUP_HASH] diff --git a/tezt/_regressions/tx_rollup_finalize_commitment_no_commitment.out b/tezt/_regressions/tx_rollup_finalize_commitment_no_commitment.out index 4c1cdc1b9b..ccd9390b48 100644 --- a/tezt/_regressions/tx_rollup_finalize_commitment_no_commitment.out +++ b/tezt/_regressions/tx_rollup_finalize_commitment_no_commitment.out @@ -2,7 +2,7 @@ tezt/_regressions/tx_rollup_finalize_commitment_no_commitment.out ./tezos-client --wait none originate tx rollup from '[PUBLIC_KEY_HASH]' --burn-cap 9999999 --storage-limit 60000 Node is bootstrapped. -Estimated gas: 1410.040 units (will add 100 for safety) +Estimated gas: 1410.092 units (will add 100 for safety) Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' NOT waiting for the operation to be included. @@ -25,13 +25,13 @@ This sequence of operations was run: Balance updates: [PUBLIC_KEY_HASH] ... -ꜩ15 storage fees ........................... +ꜩ15 - Consumed gas: 1410.040 + Consumed gas: 1410.092 Originated tx rollup: [TX_ROLLUP_HASH] ./tezos-client --wait none submit tx rollup batch 626c6f62 to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' Node is bootstrapped. -Estimated gas: 2021.296 units (will add 100 for safety) +Estimated gas: 2021.358 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -53,7 +53,7 @@ This sequence of operations was run: This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2021.296 + Consumed gas: 2021.358 ./tezos-client --wait none submit tx rollup finalize commitment to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' diff --git a/tezt/_regressions/tx_rollup_finalize_too_recent_commitment.out b/tezt/_regressions/tx_rollup_finalize_too_recent_commitment.out index d860b47c42..6d91aa2079 100644 --- a/tezt/_regressions/tx_rollup_finalize_too_recent_commitment.out +++ b/tezt/_regressions/tx_rollup_finalize_too_recent_commitment.out @@ -2,7 +2,7 @@ tezt/_regressions/tx_rollup_finalize_too_recent_commitment.out ./tezos-client --wait none originate tx rollup from '[PUBLIC_KEY_HASH]' --burn-cap 9999999 --storage-limit 60000 Node is bootstrapped. -Estimated gas: 1410.040 units (will add 100 for safety) +Estimated gas: 1410.092 units (will add 100 for safety) Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' NOT waiting for the operation to be included. @@ -25,13 +25,13 @@ This sequence of operations was run: Balance updates: [PUBLIC_KEY_HASH] ... -ꜩ15 storage fees ........................... +ꜩ15 - Consumed gas: 1410.040 + Consumed gas: 1410.092 Originated tx rollup: [TX_ROLLUP_HASH] ./tezos-client --wait none submit tx rollup batch 626c6f62 to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' Node is bootstrapped. -Estimated gas: 2021.296 units (will add 100 for safety) +Estimated gas: 2021.358 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -53,12 +53,12 @@ This sequence of operations was run: This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2021.296 + Consumed gas: 2021.358 ./tezos-client --wait none submit tx rollup commitment 0 '[TX_ROLLUP_INBOX_HASH]' '[TX_ROLLUP_MESSAGE_RESULT_HASH]' to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' Node is bootstrapped. -Estimated gas: 3690.976 units (will add 100 for safety) +Estimated gas: 3691.016 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -71,7 +71,7 @@ This sequence of operations was run: From: [PUBLIC_KEY_HASH] Fee to the baker: ꜩ0.000697 Expected counter: 3 - Gas limit: 3791 + Gas limit: 3792 Storage limit: 0 bytes Balance updates: [PUBLIC_KEY_HASH] ... -ꜩ0.000697 @@ -82,7 +82,7 @@ This sequence of operations was run: Balance updates: [PUBLIC_KEY_HASH] ....................................................... -ꜩ10000 Frozen_bonds([PUBLIC_KEY_HASH],[TX_ROLLUP_HASH]) ... +ꜩ10000 - Consumed gas: 3690.976 + Consumed gas: 3691.016 ./tezos-client --wait none submit tx rollup finalize commitment to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' diff --git a/tezt/_regressions/tx_rollup_limit_empty_batch.out b/tezt/_regressions/tx_rollup_limit_empty_batch.out index 72eb78e785..16e938fac9 100644 --- a/tezt/_regressions/tx_rollup_limit_empty_batch.out +++ b/tezt/_regressions/tx_rollup_limit_empty_batch.out @@ -2,7 +2,7 @@ tezt/_regressions/tx_rollup_limit_empty_batch.out ./tezos-client --wait none originate tx rollup from '[PUBLIC_KEY_HASH]' --burn-cap 9999999 --storage-limit 60000 Node is bootstrapped. -Estimated gas: 1410.040 units (will add 100 for safety) +Estimated gas: 1410.092 units (will add 100 for safety) Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' NOT waiting for the operation to be included. @@ -25,13 +25,13 @@ This sequence of operations was run: Balance updates: [PUBLIC_KEY_HASH] ... -ꜩ15 storage fees ........................... +ꜩ15 - Consumed gas: 1410.040 + Consumed gas: 1410.092 Originated tx rollup: [TX_ROLLUP_HASH] ./tezos-client --wait none submit tx rollup batch to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' Node is bootstrapped. -Estimated gas: 2021.288 units (will add 100 for safety) +Estimated gas: 2021.350 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -53,5 +53,5 @@ This sequence of operations was run: This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2021.288 + Consumed gas: 2021.350 diff --git a/tezt/_regressions/tx_rollup_limit_maximum_size_batch.out b/tezt/_regressions/tx_rollup_limit_maximum_size_batch.out index 850cc88cb8..dbbda54cc4 100644 --- a/tezt/_regressions/tx_rollup_limit_maximum_size_batch.out +++ b/tezt/_regressions/tx_rollup_limit_maximum_size_batch.out @@ -2,7 +2,7 @@ tezt/_regressions/tx_rollup_limit_maximum_size_batch.out ./tezos-client --wait none originate tx rollup from '[PUBLIC_KEY_HASH]' --burn-cap 9999999 --storage-limit 60000 Node is bootstrapped. -Estimated gas: 1410.040 units (will add 100 for safety) +Estimated gas: 1410.092 units (will add 100 for safety) Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' NOT waiting for the operation to be included. @@ -25,13 +25,13 @@ This sequence of operations was run: Balance updates: [PUBLIC_KEY_HASH] ... -ꜩ15 storage fees ........................... +ꜩ15 - Consumed gas: 1410.040 + Consumed gas: 1410.092 Originated tx rollup: [TX_ROLLUP_HASH] ./tezos-client --wait none submit tx rollup batch 6262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262 to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' Node is bootstrapped. -Estimated gas: 2032.538 units (will add 100 for safety) +Estimated gas: 2032.600 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -53,7 +53,7 @@ This sequence of operations was run: This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2032.538 + Consumed gas: 2032.600 ./tezos-client --wait none submit tx rollup batch 636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363 to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' diff --git a/tezt/_regressions/tx_rollup_limit_maximum_size_inbox.out b/tezt/_regressions/tx_rollup_limit_maximum_size_inbox.out index ed8a6aaff4..ce0b1b39b5 100644 --- a/tezt/_regressions/tx_rollup_limit_maximum_size_inbox.out +++ b/tezt/_regressions/tx_rollup_limit_maximum_size_inbox.out @@ -2,7 +2,7 @@ tezt/_regressions/tx_rollup_limit_maximum_size_inbox.out ./tezos-client --wait none originate tx rollup from '[PUBLIC_KEY_HASH]' --burn-cap 9999999 --storage-limit 60000 Node is bootstrapped. -Estimated gas: 1410.040 units (will add 100 for safety) +Estimated gas: 1410.092 units (will add 100 for safety) Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' NOT waiting for the operation to be included. @@ -25,13 +25,13 @@ This sequence of operations was run: Balance updates: [PUBLIC_KEY_HASH] ... -ꜩ15 storage fees ........................... +ꜩ15 - Consumed gas: 1410.040 + Consumed gas: 1410.092 Originated tx rollup: [TX_ROLLUP_HASH] ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap1 Node is bootstrapped. -Estimated gas: 2032.538 units (will add 100 for safety) +Estimated gas: 2032.600 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -53,12 +53,12 @@ This sequence of operations was run: This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2032.538 + Consumed gas: 2032.600 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap2 Node is bootstrapped. -Estimated gas: 2032.538 units (will add 100 for safety) +Estimated gas: 2032.600 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -80,12 +80,12 @@ This sequence of operations was run: This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2032.538 + Consumed gas: 2032.600 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap3 Node is bootstrapped. -Estimated gas: 2032.538 units (will add 100 for safety) +Estimated gas: 2032.600 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -107,12 +107,12 @@ This sequence of operations was run: This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2032.538 + Consumed gas: 2032.600 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap4 Node is bootstrapped. -Estimated gas: 2032.538 units (will add 100 for safety) +Estimated gas: 2032.600 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -134,12 +134,12 @@ This sequence of operations was run: This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2032.538 + Consumed gas: 2032.600 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap5 Node is bootstrapped. -Estimated gas: 2032.538 units (will add 100 for safety) +Estimated gas: 2032.600 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -161,13 +161,13 @@ This sequence of operations was run: This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2032.538 + Consumed gas: 2032.600 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap6 Node is bootstrapped. Estimated storage: no bytes added -Estimated gas: 2032.538 units (will add 100 for safety) +Estimated gas: 2032.600 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -203,13 +203,13 @@ This sequence of operations was run: This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2032.538 + Consumed gas: 2032.600 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap7 Node is bootstrapped. Estimated storage: no bytes added -Estimated gas: 2032.538 units (will add 100 for safety) +Estimated gas: 2032.600 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -245,13 +245,13 @@ This sequence of operations was run: This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2032.538 + Consumed gas: 2032.600 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap8 Node is bootstrapped. Estimated storage: no bytes added -Estimated gas: 2032.538 units (will add 100 for safety) +Estimated gas: 2032.600 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -287,13 +287,13 @@ This sequence of operations was run: This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2032.538 + Consumed gas: 2032.600 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap9 Node is bootstrapped. Estimated storage: no bytes added -Estimated gas: 2032.538 units (will add 100 for safety) +Estimated gas: 2032.600 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -329,13 +329,13 @@ This sequence of operations was run: This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2032.538 + Consumed gas: 2032.600 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap10 Node is bootstrapped. Estimated storage: no bytes added -Estimated gas: 2032.538 units (will add 100 for safety) +Estimated gas: 2032.600 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -371,13 +371,13 @@ This sequence of operations was run: This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2032.538 + Consumed gas: 2032.600 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap11 Node is bootstrapped. Estimated storage: no bytes added -Estimated gas: 2032.538 units (will add 100 for safety) +Estimated gas: 2032.600 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -413,13 +413,13 @@ This sequence of operations was run: This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2032.538 + Consumed gas: 2032.600 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap12 Node is bootstrapped. Estimated storage: no bytes added -Estimated gas: 2032.538 units (will add 100 for safety) +Estimated gas: 2032.600 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -455,13 +455,13 @@ This sequence of operations was run: This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2032.538 + Consumed gas: 2032.600 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap13 Node is bootstrapped. Estimated storage: no bytes added -Estimated gas: 2032.538 units (will add 100 for safety) +Estimated gas: 2032.600 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -497,13 +497,13 @@ This sequence of operations was run: This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2032.538 + Consumed gas: 2032.600 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap14 Node is bootstrapped. Estimated storage: no bytes added -Estimated gas: 2032.538 units (will add 100 for safety) +Estimated gas: 2032.600 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -539,13 +539,13 @@ This sequence of operations was run: This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2032.538 + Consumed gas: 2032.600 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap15 Node is bootstrapped. Estimated storage: no bytes added -Estimated gas: 2032.538 units (will add 100 for safety) +Estimated gas: 2032.600 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -581,13 +581,13 @@ This sequence of operations was run: This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2032.538 + Consumed gas: 2032.600 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap16 Node is bootstrapped. Estimated storage: no bytes added -Estimated gas: 2032.538 units (will add 100 for safety) +Estimated gas: 2032.600 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -623,13 +623,13 @@ This sequence of operations was run: This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2032.538 + Consumed gas: 2032.600 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap17 Node is bootstrapped. Estimated storage: no bytes added -Estimated gas: 2032.538 units (will add 100 for safety) +Estimated gas: 2032.600 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -665,13 +665,13 @@ This sequence of operations was run: This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2032.538 + Consumed gas: 2032.600 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap18 Node is bootstrapped. Estimated storage: no bytes added -Estimated gas: 2032.538 units (will add 100 for safety) +Estimated gas: 2032.600 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -707,13 +707,13 @@ This sequence of operations was run: This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2032.538 + Consumed gas: 2032.600 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap19 Node is bootstrapped. Estimated storage: no bytes added -Estimated gas: 2032.538 units (will add 100 for safety) +Estimated gas: 2032.600 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -749,13 +749,13 @@ This sequence of operations was run: This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2032.538 + Consumed gas: 2032.600 ./tezos-client --wait none submit tx rollup batch 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 to '[TX_ROLLUP_HASH]' from bootstrap20 Node is bootstrapped. Estimated storage: no bytes added -Estimated gas: 2032.538 units (will add 100 for safety) +Estimated gas: 2032.600 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -791,7 +791,7 @@ This sequence of operations was run: This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2032.538 + Consumed gas: 2032.600 ./tezos-client rpc get '/chains/main/blocks/head/context/tx_rollup/[TX_ROLLUP_HASH]/inbox/0' diff --git a/tezt/_regressions/tx_rollup_rpc_commitment.out b/tezt/_regressions/tx_rollup_rpc_commitment.out index b468828cfd..b8d34655ca 100644 --- a/tezt/_regressions/tx_rollup_rpc_commitment.out +++ b/tezt/_regressions/tx_rollup_rpc_commitment.out @@ -2,7 +2,7 @@ tezt/_regressions/tx_rollup_rpc_commitment.out ./tezos-client --wait none originate tx rollup from '[PUBLIC_KEY_HASH]' --burn-cap 9999999 --storage-limit 60000 Node is bootstrapped. -Estimated gas: 1410.040 units (will add 100 for safety) +Estimated gas: 1410.092 units (will add 100 for safety) Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' NOT waiting for the operation to be included. @@ -25,13 +25,13 @@ This sequence of operations was run: Balance updates: [PUBLIC_KEY_HASH] ... -ꜩ15 storage fees ........................... +ꜩ15 - Consumed gas: 1410.040 + Consumed gas: 1410.092 Originated tx rollup: [TX_ROLLUP_HASH] ./tezos-client --wait none submit tx rollup batch 626c6f62 to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' Node is bootstrapped. -Estimated gas: 2021.296 units (will add 100 for safety) +Estimated gas: 2021.358 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -53,12 +53,12 @@ This sequence of operations was run: This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2021.296 + Consumed gas: 2021.358 ./tezos-client --wait none submit tx rollup commitment 0 '[TX_ROLLUP_INBOX_HASH]' '[TX_ROLLUP_MESSAGE_RESULT_HASH]' to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' Node is bootstrapped. -Estimated gas: 3690.976 units (will add 100 for safety) +Estimated gas: 3691.016 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -71,7 +71,7 @@ This sequence of operations was run: From: [PUBLIC_KEY_HASH] Fee to the baker: ꜩ0.000697 Expected counter: 3 - Gas limit: 3791 + Gas limit: 3792 Storage limit: 0 bytes Balance updates: [PUBLIC_KEY_HASH] ... -ꜩ0.000697 @@ -82,7 +82,7 @@ This sequence of operations was run: Balance updates: [PUBLIC_KEY_HASH] ....................................................... -ꜩ10000 Frozen_bonds([PUBLIC_KEY_HASH],[TX_ROLLUP_HASH]) ... +ꜩ10000 - Consumed gas: 3690.976 + Consumed gas: 3691.016 ./tezos-client rpc get '/chains/main/blocks/head/context/tx_rollup/[TX_ROLLUP_HASH]/commitment/0' diff --git a/tezt/_regressions/tx_rollup_rpc_inbox.out b/tezt/_regressions/tx_rollup_rpc_inbox.out index 9f02e4d0dc..d0c7f6a0a4 100644 --- a/tezt/_regressions/tx_rollup_rpc_inbox.out +++ b/tezt/_regressions/tx_rollup_rpc_inbox.out @@ -2,7 +2,7 @@ tezt/_regressions/tx_rollup_rpc_inbox.out ./tezos-client --wait none originate tx rollup from '[PUBLIC_KEY_HASH]' --burn-cap 9999999 --storage-limit 60000 Node is bootstrapped. -Estimated gas: 1410.040 units (will add 100 for safety) +Estimated gas: 1410.092 units (will add 100 for safety) Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' NOT waiting for the operation to be included. @@ -25,13 +25,13 @@ This sequence of operations was run: Balance updates: [PUBLIC_KEY_HASH] ... -ꜩ15 storage fees ........................... +ꜩ15 - Consumed gas: 1410.040 + Consumed gas: 1410.092 Originated tx rollup: [TX_ROLLUP_HASH] ./tezos-client --wait none submit tx rollup batch 626c6f62 to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' Node is bootstrapped. -Estimated gas: 2021.296 units (will add 100 for safety) +Estimated gas: 2021.358 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -53,7 +53,7 @@ This sequence of operations was run: This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2021.296 + Consumed gas: 2021.358 ./tezos-client rpc get '/chains/main/blocks/head/context/tx_rollup/[TX_ROLLUP_HASH]/inbox/0' diff --git a/tezt/_regressions/tx_rollup_rpc_pending_bonded_commitments.out b/tezt/_regressions/tx_rollup_rpc_pending_bonded_commitments.out index 0af0bfcfa3..21b3d4de15 100644 --- a/tezt/_regressions/tx_rollup_rpc_pending_bonded_commitments.out +++ b/tezt/_regressions/tx_rollup_rpc_pending_bonded_commitments.out @@ -2,7 +2,7 @@ tezt/_regressions/tx_rollup_rpc_pending_bonded_commitments.out ./tezos-client --wait none originate tx rollup from '[PUBLIC_KEY_HASH]' --burn-cap 9999999 --storage-limit 60000 Node is bootstrapped. -Estimated gas: 1410.040 units (will add 100 for safety) +Estimated gas: 1410.092 units (will add 100 for safety) Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' NOT waiting for the operation to be included. @@ -25,13 +25,13 @@ This sequence of operations was run: Balance updates: [PUBLIC_KEY_HASH] ... -ꜩ15 storage fees ........................... +ꜩ15 - Consumed gas: 1410.040 + Consumed gas: 1410.092 Originated tx rollup: [TX_ROLLUP_HASH] ./tezos-client --wait none submit tx rollup batch 626c6f62 to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' Node is bootstrapped. -Estimated gas: 2021.296 units (will add 100 for safety) +Estimated gas: 2021.358 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -53,12 +53,12 @@ This sequence of operations was run: This tx rollup submit operation was successfully applied Balance updates: - Consumed gas: 2021.296 + Consumed gas: 2021.358 ./tezos-client --wait none submit tx rollup commitment 0 '[TX_ROLLUP_INBOX_HASH]' '[TX_ROLLUP_MESSAGE_RESULT_HASH]' to '[TX_ROLLUP_HASH]' from '[PUBLIC_KEY_HASH]' Node is bootstrapped. -Estimated gas: 3690.976 units (will add 100 for safety) +Estimated gas: 3691.016 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -71,7 +71,7 @@ This sequence of operations was run: From: [PUBLIC_KEY_HASH] Fee to the baker: ꜩ0.000697 Expected counter: 3 - Gas limit: 3791 + Gas limit: 3792 Storage limit: 0 bytes Balance updates: [PUBLIC_KEY_HASH] ... -ꜩ0.000697 @@ -82,7 +82,7 @@ This sequence of operations was run: Balance updates: [PUBLIC_KEY_HASH] ....................................................... -ꜩ10000 Frozen_bonds([PUBLIC_KEY_HASH],[TX_ROLLUP_HASH]) ... +ꜩ10000 - Consumed gas: 3690.976 + Consumed gas: 3691.016 ./tezos-client rpc get '/chains/main/blocks/head/context/tx_rollup/[TX_ROLLUP_HASH]/pending_bonded_commitments/[PUBLIC_KEY_HASH]' diff --git a/tezt/_regressions/tx_rollup_rpc_state.out b/tezt/_regressions/tx_rollup_rpc_state.out index e9578fad78..197c22041d 100644 --- a/tezt/_regressions/tx_rollup_rpc_state.out +++ b/tezt/_regressions/tx_rollup_rpc_state.out @@ -2,7 +2,7 @@ tezt/_regressions/tx_rollup_rpc_state.out ./tezos-client --wait none originate tx rollup from '[PUBLIC_KEY_HASH]' --burn-cap 9999999 --storage-limit 60000 Node is bootstrapped. -Estimated gas: 1410.040 units (will add 100 for safety) +Estimated gas: 1410.092 units (will add 100 for safety) Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' NOT waiting for the operation to be included. @@ -25,11 +25,13 @@ This sequence of operations was run: Balance updates: [PUBLIC_KEY_HASH] ... -ꜩ15 storage fees ........................... +ꜩ15 - Consumed gas: 1410.040 + Consumed gas: 1410.092 Originated tx rollup: [TX_ROLLUP_HASH] ./tezos-client rpc get '/chains/main/blocks/head/context/tx_rollup/[TX_ROLLUP_HASH]/state' -{ "last_removed_commitment_hashes": null, "commitment_tail_level": null, - "oldest_inbox_level": null, "commitment_head_level": null, - "head_level": null, "burn_per_byte": "0", "inbox_ema": 0 } +{ "last_removed_commitment_hashes": null, + "finalized_commitments": { "next": 0 }, + "unfinalized_commitments": { "next": 0 }, + "uncommitted_inboxes": { "next": 0 }, "commitment_newest_hash": null, + "tezos_head_level": null, "burn_per_byte": "0", "inbox_ema": 0 } diff --git a/tezt/lib_tezos/rollup.ml b/tezt/lib_tezos/rollup.ml index d9f253accb..28a02d18b3 100644 --- a/tezt/lib_tezos/rollup.ml +++ b/tezt/lib_tezos/rollup.ml @@ -24,10 +24,26 @@ (*****************************************************************************) module Tx_rollup = struct + type range = Empty of int | Interval of int * int + + let pp_range fmt = function + | Empty x -> Format.fprintf fmt "next: %d" x + | Interval (t, h) -> Format.fprintf fmt "oldest: %d newest: %d" t h + + let range_of_json json = + if JSON.(json |-> "newest" |> is_null) then + Empty JSON.(json |-> "next" |> as_int) + else + let tail = JSON.(json |-> "oldest" |> as_int) in + let head = JSON.(json |-> "newest" |> as_int) in + Interval (tail, head) + type state = { - oldest_inbox_level : int option; - head_level : (int * int) option; - commitment_head_level : (int * string) option; + finalized_commitments : range; + unfinalized_commitments : range; + uncommitted_inboxes : range; + tezos_head_level : int option; + commitment_head_hash : string option; burn_per_byte : int; inbox_ema : int; } @@ -36,29 +52,27 @@ module Tx_rollup = struct let get_state ?hooks ~rollup client = let parse json = - let oldest_inbox_level = - JSON.(json |-> "oldest_inbox_level" |> as_opt |> Option.map as_int) + let finalized_commitments = + JSON.(json |-> "finalized_commitments" |> range_of_json) in - let head_level = - JSON.( - match json |-> "head_level" |> as_opt with - | None -> None - | Some json -> - Some (json |-> "level" |> as_int, json |-> "tezos_level" |> as_int)) + let unfinalized_commitments = + JSON.(json |-> "unfinalized_commitments" |> range_of_json) in - let commitment_head_level = - JSON.( - match json |-> "commitment_head_level" |> as_opt with - | None -> None - | Some json -> - Some (json |-> "level" |> as_int, json |-> "hash" |> as_string)) + let uncommitted_inboxes = + JSON.(json |-> "uncommitted_inboxes" |> range_of_json) + in + let tezos_head_level = JSON.(json |-> "tezos_head_level" |> as_int_opt) in + let commitment_head_hash = + JSON.(json |-> "commitment_head_hash" |> as_string_opt) in let burn_per_byte = JSON.(json |-> "burn_per_byte" |> as_int) in let inbox_ema = JSON.(json |-> "inbox_ema" |> as_int) in { - oldest_inbox_level; - commitment_head_level; - head_level; + finalized_commitments; + unfinalized_commitments; + uncommitted_inboxes; + tezos_head_level; + commitment_head_hash; burn_per_byte; inbox_ema; } @@ -140,27 +154,26 @@ module Tx_rollup = struct } module Check = struct + let range : range Check.typ = Check.equalable pp_range ( = ) + let state : state Check.typ = let open Check in convert (fun { - head_level; - commitment_head_level; - oldest_inbox_level; + finalized_commitments; + unfinalized_commitments; + uncommitted_inboxes; + tezos_head_level; + commitment_head_hash; burn_per_byte; inbox_ema; } -> - ( head_level, - commitment_head_level, - oldest_inbox_level, - burn_per_byte, - inbox_ema )) - (tuple5 - (option (tuple2 int int)) - (option (tuple2 int string)) - (option int) - int - int) + ( finalized_commitments, + unfinalized_commitments, + uncommitted_inboxes, + tezos_head_level, + (commitment_head_hash, burn_per_byte, inbox_ema) )) + (tuple5 range range range (option int) (tuple3 (option string) int int)) let inbox : inbox Check.typ = let open Check in diff --git a/tezt/lib_tezos/rollup.mli b/tezt/lib_tezos/rollup.mli index 1bf4e72003..4f22799e55 100644 --- a/tezt/lib_tezos/rollup.mli +++ b/tezt/lib_tezos/rollup.mli @@ -24,10 +24,14 @@ (*****************************************************************************) module Tx_rollup : sig + type range = Empty of int | Interval of int * int + type state = { - oldest_inbox_level : int option; - head_level : (int * int) option; - commitment_head_level : (int * string) option; + finalized_commitments : range; + unfinalized_commitments : range; + uncommitted_inboxes : range; + tezos_head_level : int option; + commitment_head_hash : string option; burn_per_byte : int; inbox_ema : int; } diff --git a/tezt/tests/tx_rollup.ml b/tezt/tests/tx_rollup.ml index 192a1cdea5..9716060f33 100644 --- a/tezt/tests/tx_rollup.ml +++ b/tezt/tests/tx_rollup.ml @@ -605,9 +605,11 @@ let test_submit_batches_in_several_blocks = let expected_state = Rollup. { - oldest_inbox_level = None; - head_level = None; - commitment_head_level = None; + finalized_commitments = Empty 0; + unfinalized_commitments = Empty 0; + uncommitted_inboxes = Empty 0; + tezos_head_level = None; + commitment_head_hash = None; burn_per_byte = 0; inbox_ema = 0; } @@ -945,10 +947,9 @@ let test_rollup_wrong_rejection = Check.(error_id = "proto.alpha.tx_rollup_invalid_proof") Check.string ~error_msg:"Expected error id: %R. Got %L" ; - match state.commitment_head_level with - | Some (0, _) -> unit - | None | Some _ -> - Test.fail "Wrong rollup state: Expected commitment head at level 0" + match state.unfinalized_commitments with + | Interval (0, _) -> unit + | _ -> Test.fail "Wrong rollup state: Expected commitment head at level 0" let register ~protocols = Regressions.register protocols ; From c2dd6904634683295669e9844594a1fe024c8d0a Mon Sep 17 00:00:00 2001 From: Valentin Chaboche <valentin.chaboche@nomadic-labs.com> Date: Thu, 10 Mar 2022 17:25:36 +0100 Subject: [PATCH 091/100] Tx_rollup,Proto: expose [init_counter] for addresses and tickets --- src/proto_alpha/lib_protocol/tx_rollup_l2_context.ml | 4 ++++ src/proto_alpha/lib_protocol/tx_rollup_l2_context_sig.ml | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/src/proto_alpha/lib_protocol/tx_rollup_l2_context.ml b/src/proto_alpha/lib_protocol/tx_rollup_l2_context.ml index be60ee7cc1..bd934a5b49 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_l2_context.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_l2_context.ml @@ -281,6 +281,8 @@ struct let+ count = get ctxt Address_count in Option.value ~default:0l count + let init_counter ctxt = set ctxt Address_count 0l + let associate_index ctxt addr = let open Syntax in let* i = count ctxt in @@ -316,6 +318,8 @@ struct let+ count = get ctxt Ticket_count in Option.value ~default:0l count + let init_counter ctxt = set ctxt Ticket_count 0l + let associate_index ctxt ticket = let open Syntax in let* i = count ctxt in diff --git a/src/proto_alpha/lib_protocol/tx_rollup_l2_context_sig.ml b/src/proto_alpha/lib_protocol/tx_rollup_l2_context_sig.ml index 54f7c95cca..ba8d16138f 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_l2_context_sig.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_l2_context_sig.ml @@ -259,6 +259,10 @@ module type CONTEXT = sig in future layer2 operations. *) module Address_index : sig + (** [init_counter ctxt] writes the default counter (i.e. [0L]) in + the context. *) + val init_counter : t -> t m + (** [get ctxt addr] returns the index associated to [addr], if any. *) val get : t -> Tx_rollup_l2_address.t -> address_index option m @@ -298,6 +302,10 @@ module type CONTEXT = sig in future layer2 operations. *) module Ticket_index : sig + (** [init_counter ctxt] writes the default counter (i.e. [0L]) in + the context. *) + val init_counter : t -> t m + (** [get ctxt ticket] returns the index associated to [ticket], if any. *) val get : t -> Alpha_context.Ticket_hash.t -> ticket_index option m From 1b1656ce32f843dd991fd394ede0cf34e1e0aae6 Mon Sep 17 00:00:00 2001 From: David Turner <novalis@novalis.org> Date: Tue, 8 Mar 2022 09:10:46 -0500 Subject: [PATCH 092/100] Proto,alpha: Verify proofs submitted during a rejection Co-authored-by: Thomas Letan <lthms@nomadic-labs.com> --- .../lib_client/client_proto_context.ml | 5 + .../lib_client/client_proto_context.mli | 2 +- src/proto_alpha/lib_client/mockup.ml | 26 +- .../client_proto_context_commands.ml | 5 +- .../lib_parameters/default_parameters.ml | 4 + .../lib_protocol/alpha_context.mli | 10 +- src/proto_alpha/lib_protocol/apply.ml | 13 +- .../lib_protocol/constants_repr.ml | 13 +- .../lib_protocol/constants_repr.mli | 3 + .../lib_protocol/constants_storage.ml | 4 + .../lib_protocol/constants_storage.mli | 2 + .../lib_protocol/operation_repr.ml | 2 +- src/proto_alpha/lib_protocol/raw_context.ml | 1 + .../lib_protocol/test/helpers/op.ml | 3 +- .../lib_protocol/test/helpers/op.mli | 2 +- .../integration/operations/test_tx_rollup.ml | 1074 +++++- .../lib_protocol/tx_rollup_commitment_repr.ml | 3 +- .../tx_rollup_commitment_repr.mli | 12 +- .../lib_protocol/tx_rollup_errors_repr.ml | 53 +- .../lib_protocol/tx_rollup_l2_proof.ml | 4 +- .../lib_protocol/tx_rollup_l2_proof.mli | 4 +- .../lib_protocol/tx_rollup_l2_verifier.ml | 113 +- .../lib_protocol/tx_rollup_l2_verifier.mli | 28 +- tests_python/tests_alpha/test_mockup.py | 1 + .../_regressions/rpc/alpha.client.mempool.out | 3230 ++++++++++++++++- tezt/_regressions/rpc/alpha.client.others.out | 3 +- tezt/_regressions/rpc/alpha.light.others.out | 3 +- tezt/_regressions/rpc/alpha.proxy.mempool.out | 3230 ++++++++++++++++- tezt/_regressions/rpc/alpha.proxy.others.out | 3 +- .../rpc/alpha.proxy_server.others.out | 3 +- tezt/lib_tezos/client.ml | 3 +- tezt/lib_tezos/client.mli | 2 +- tezt/lib_tezos/constant.ml | 15 +- tezt/lib_tezos/operation.ml | 4 +- tezt/lib_tezos/operation.mli | 4 +- tezt/tests/tx_rollup.ml | 18 +- 36 files changed, 7380 insertions(+), 525 deletions(-) diff --git a/src/proto_alpha/lib_client/client_proto_context.ml b/src/proto_alpha/lib_client/client_proto_context.ml index c2d7e384b8..68f5dbb529 100644 --- a/src/proto_alpha/lib_client/client_proto_context.ml +++ b/src/proto_alpha/lib_client/client_proto_context.ml @@ -1018,6 +1018,11 @@ let submit_tx_rollup_rejection (cctxt : #full) ~chain ~block ?confirmations | Error err -> failwith "Message path is not a valid JSON-encoded message: %s" err) >>=? fun message_path -> + (match Data_encoding.Json.from_string proof with + | Ok json -> + Data_encoding.Json.destruct Tx_rollup_l2_proof.encoding json |> return + | Error err -> failwith "Proof is not a valid JSON-encoded message: %s" err) + >>=? fun proof -> let contents : Kind.tx_rollup_rejection Annotated_manager_operation.annotated_list = Annotated_manager_operation.Single_manager diff --git a/src/proto_alpha/lib_client/client_proto_context.mli b/src/proto_alpha/lib_client/client_proto_context.mli index c5de55c8da..45e5015d3b 100644 --- a/src/proto_alpha/lib_client/client_proto_context.mli +++ b/src/proto_alpha/lib_client/client_proto_context.mli @@ -568,7 +568,7 @@ val submit_tx_rollup_rejection : message_path:string -> context_hash:string -> withdrawals_merkle_root:string -> - proof:bool -> + proof:string -> unit -> (Operation_hash.t * Kind.tx_rollup_rejection Kind.manager contents diff --git a/src/proto_alpha/lib_client/mockup.ml b/src/proto_alpha/lib_client/mockup.ml index 1954e48e55..425602d29b 100644 --- a/src/proto_alpha/lib_client/mockup.ml +++ b/src/proto_alpha/lib_client/mockup.ml @@ -85,6 +85,7 @@ module Protocol_constants_overrides = struct tx_rollup_max_finalized_levels : int option; tx_rollup_cost_per_byte_ema_factor : int option; tx_rollup_max_ticket_payload_size : int option; + tx_rollup_rejection_max_proof_size : int option; sc_rollup_enable : bool option; sc_rollup_origination_size : int option; sc_rollup_challenge_window_in_blocks : int option; @@ -149,7 +150,8 @@ module Protocol_constants_overrides = struct c.tx_rollup_max_messages_per_inbox ), ( c.tx_rollup_max_finalized_levels, c.tx_rollup_cost_per_byte_ema_factor, - c.tx_rollup_max_ticket_payload_size ) ), + c.tx_rollup_max_ticket_payload_size, + c.tx_rollup_rejection_max_proof_size ) ), ( c.sc_rollup_enable, c.sc_rollup_origination_size, c.sc_rollup_challenge_window_in_blocks ) ) ) ) ) ) )) @@ -203,7 +205,8 @@ module Protocol_constants_overrides = struct tx_rollup_max_messages_per_inbox ), ( tx_rollup_max_finalized_levels, tx_rollup_cost_per_byte_ema_factor, - tx_rollup_max_ticket_payload_size ) ), + tx_rollup_max_ticket_payload_size, + tx_rollup_rejection_max_proof_size ) ), ( sc_rollup_enable, sc_rollup_origination_size, sc_rollup_challenge_window_in_blocks ) ) ) ) ) ) ) -> @@ -256,6 +259,7 @@ module Protocol_constants_overrides = struct tx_rollup_max_finalized_levels; tx_rollup_cost_per_byte_ema_factor; tx_rollup_max_ticket_payload_size; + tx_rollup_rejection_max_proof_size; sc_rollup_enable; sc_rollup_origination_size; sc_rollup_challenge_window_in_blocks; @@ -330,10 +334,11 @@ module Protocol_constants_overrides = struct (opt "tx_rollup_max_unfinalized_levels" int31) (opt "tx_rollup_withdraw_period" int31) (opt "tx_rollup_max_messages_per_inbox" int31)) - (obj3 + (obj4 (opt "tx_rollup_max_finalized_levels" int31) (opt "tx_rollup_cost_per_byte_ema_factor" int31) - (opt "tx_rollup_max_ticket_payload_size" int31))) + (opt "tx_rollup_max_ticket_payload_size" int31) + (opt "tx_rollup_rejection_max_proof_size" int31))) (obj3 (opt "sc_rollup_enable" bool) (opt "sc_rollup_origination_size" int31) @@ -421,6 +426,8 @@ module Protocol_constants_overrides = struct Some parametric.tx_rollup_cost_per_byte_ema_factor; tx_rollup_max_ticket_payload_size = Some parametric.tx_rollup_max_ticket_payload_size; + tx_rollup_rejection_max_proof_size = + Some parametric.tx_rollup_rejection_max_proof_size; sc_rollup_enable = Some parametric.sc_rollup_enable; sc_rollup_origination_size = Some parametric.sc_rollup_origination_size; sc_rollup_challenge_window_in_blocks = @@ -483,6 +490,7 @@ module Protocol_constants_overrides = struct tx_rollup_max_finalized_levels = None; tx_rollup_cost_per_byte_ema_factor = None; tx_rollup_max_ticket_payload_size = None; + tx_rollup_rejection_max_proof_size = None; sc_rollup_enable = None; sc_rollup_origination_size = None; sc_rollup_challenge_window_in_blocks = None; @@ -760,6 +768,12 @@ module Protocol_constants_overrides = struct override_value = o.tx_rollup_cost_per_byte_ema_factor; pp = pp_print_int; }; + O + { + name = "tx_rollup_rejection_max_proof_size"; + override_value = o.tx_rollup_rejection_max_proof_size; + pp = pp_print_int; + }; ] in let fields_with_override = @@ -940,6 +954,10 @@ module Protocol_constants_overrides = struct Option.value ~default:c.tx_rollup_max_ticket_payload_size o.tx_rollup_max_ticket_payload_size; + tx_rollup_rejection_max_proof_size = + Option.value + ~default:c.tx_rollup_rejection_max_proof_size + o.tx_rollup_rejection_max_proof_size; sc_rollup_enable = Option.value ~default:c.sc_rollup_enable o.sc_rollup_enable; sc_rollup_origination_size = diff --git a/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml b/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml index 073933ddb0..8b4265502d 100644 --- a/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml +++ b/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml @@ -103,10 +103,7 @@ let tx_rollup_proof_param = Clic.param ~name:"tx_rollup rejection proof" ~desc:"The proof associated to the rejection operation" - (Clic.parameter (fun _ s -> - match bool_of_string_opt s with - | Some c -> return c - | None -> failwith "Parameter '%s' is not a boolean" s)) + string_parameter let rollup_kind_param = Clic.parameter (fun _ name -> diff --git a/src/proto_alpha/lib_parameters/default_parameters.ml b/src/proto_alpha/lib_parameters/default_parameters.ml index 875646612a..973097ffe1 100644 --- a/src/proto_alpha/lib_parameters/default_parameters.ml +++ b/src/proto_alpha/lib_parameters/default_parameters.ml @@ -122,6 +122,10 @@ let constants_mainnet = tx_rollup_max_finalized_levels = tx_rollup_withdraw_period + 100; tx_rollup_cost_per_byte_ema_factor = 120; tx_rollup_max_ticket_payload_size = 10_240; + (* Must be smaller than maximum limit of a manager operation + (minus overhead), since we need to limit our proofs to those + that can fit in an operation. *) + tx_rollup_rejection_max_proof_size = 30000; sc_rollup_enable = false; (* The following value is chosen to prevent spam. *) sc_rollup_origination_size = 6_314; diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index b0df126b83..c11fcec7b0 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -804,6 +804,7 @@ module Constants : sig tx_rollup_max_finalized_levels : int; tx_rollup_cost_per_byte_ema_factor : int; tx_rollup_max_ticket_payload_size : int; + tx_rollup_rejection_max_proof_size : int; sc_rollup_enable : bool; sc_rollup_origination_size : int; sc_rollup_challenge_window_in_blocks : int; @@ -910,6 +911,8 @@ module Constants : sig val tx_rollup_max_ticket_payload_size : context -> int + val tx_rollup_rejection_max_proof_size : context -> int + val sc_rollup_enable : context -> bool val sc_rollup_origination_size : context -> int @@ -1907,7 +1910,6 @@ module Tx_rollup_errors : sig expected : Tx_rollup_commitment_hash.t option; } | Invalid_rejection_level_argument - | Invalid_proof | Internal_error of string | Wrong_message_position of { level : Tx_rollup_level.t; @@ -1932,6 +1934,12 @@ module Tx_rollup_errors : sig } | Deposit_wrong_ticketer of Tx_rollup.t | Wrong_deposit_parameters + | Proof_failed_to_reject + | Proof_produced_rejected_state + | Proof_invalid_before of { + agreed : Context_hash.t; + provided : Context_hash.t; + } end module Bond_id : sig diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index d03767acb8..85a3186734 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -1792,13 +1792,22 @@ let apply_external_manager_operation_content : message_path >>=? fun ctxt -> (* Check [proof] *) + let parameters = + Tx_rollup_l2_apply. + { + tx_rollup_max_withdrawals_per_batch = + Constants.tx_rollup_max_withdrawals_per_batch ctxt; + } + in Tx_rollup_l2_verifier.verify_proof + parameters message proof ~agreed:previous_message_result ~rejected - >>= fun verified -> - fail_unless verified Tx_rollup_errors.Invalid_proof >>=? fun () -> + ~max_proof_size: + (Alpha_context.Constants.tx_rollup_rejection_max_proof_size ctxt) + >>=? fun () -> (* Proof is correct, removing *) Tx_rollup_commitment.reject_commitment ctxt tx_rollup state level >>=? fun (ctxt, state) -> diff --git a/src/proto_alpha/lib_protocol/constants_repr.ml b/src/proto_alpha/lib_protocol/constants_repr.ml index c00b6e21c2..d33574ef28 100644 --- a/src/proto_alpha/lib_protocol/constants_repr.ml +++ b/src/proto_alpha/lib_protocol/constants_repr.ml @@ -172,6 +172,7 @@ type parametric = { tx_rollup_max_finalized_levels : int; tx_rollup_cost_per_byte_ema_factor : int; tx_rollup_max_ticket_payload_size : int; + tx_rollup_rejection_max_proof_size : int; sc_rollup_enable : bool; sc_rollup_origination_size : int; sc_rollup_challenge_window_in_blocks : int; @@ -229,7 +230,8 @@ let parametric_encoding = c.tx_rollup_max_messages_per_inbox ), ( c.tx_rollup_max_finalized_levels, c.tx_rollup_cost_per_byte_ema_factor, - c.tx_rollup_max_ticket_payload_size ) ), + c.tx_rollup_max_ticket_payload_size, + c.tx_rollup_rejection_max_proof_size ) ), ( c.sc_rollup_enable, c.sc_rollup_origination_size, c.sc_rollup_challenge_window_in_blocks ) ) ) ) ) ) )) @@ -281,7 +283,8 @@ let parametric_encoding = tx_rollup_max_messages_per_inbox ), ( tx_rollup_max_finalized_levels, tx_rollup_cost_per_byte_ema_factor, - tx_rollup_max_ticket_payload_size ) ), + tx_rollup_max_ticket_payload_size, + tx_rollup_rejection_max_proof_size ) ), ( sc_rollup_enable, sc_rollup_origination_size, sc_rollup_challenge_window_in_blocks ) ) ) ) ) ) ) -> @@ -335,6 +338,7 @@ let parametric_encoding = tx_rollup_max_finalized_levels; tx_rollup_cost_per_byte_ema_factor; tx_rollup_max_ticket_payload_size; + tx_rollup_rejection_max_proof_size; sc_rollup_enable; sc_rollup_origination_size; sc_rollup_challenge_window_in_blocks; @@ -404,10 +408,11 @@ let parametric_encoding = (req "tx_rollup_withdraw_period" int31) (req "tx_rollup_max_unfinalized_levels" int31) (req "tx_rollup_max_messages_per_inbox" int31)) - (obj3 + (obj4 (req "tx_rollup_max_finalized_levels" int31) (req "tx_rollup_cost_per_byte_ema_factor" int31) - (req "tx_rollup_max_ticket_payload_size" int31))) + (req "tx_rollup_max_ticket_payload_size" int31) + (req "tx_rollup_rejection_max_proof_size" int31))) (obj3 (req "sc_rollup_enable" bool) (req "sc_rollup_origination_size" int31) diff --git a/src/proto_alpha/lib_protocol/constants_repr.mli b/src/proto_alpha/lib_protocol/constants_repr.mli index 88341a1139..35bf13f603 100644 --- a/src/proto_alpha/lib_protocol/constants_repr.mli +++ b/src/proto_alpha/lib_protocol/constants_repr.mli @@ -151,6 +151,9 @@ type parametric = { tx_rollup_cost_per_byte_ema_factor : int; (* maximum size, in bytes, of the contents given in deposited tickets. *) tx_rollup_max_ticket_payload_size : int; + (* The maximum size, in bytes, of a Merkle proof. Operations which would + require proofs larger than this should be no-ops. *) + tx_rollup_rejection_max_proof_size : int; sc_rollup_enable : bool; sc_rollup_origination_size : int; sc_rollup_challenge_window_in_blocks : int; diff --git a/src/proto_alpha/lib_protocol/constants_storage.ml b/src/proto_alpha/lib_protocol/constants_storage.ml index b431575429..c8418674f9 100644 --- a/src/proto_alpha/lib_protocol/constants_storage.ml +++ b/src/proto_alpha/lib_protocol/constants_storage.ml @@ -198,6 +198,10 @@ let tx_rollup_max_ticket_payload_size c = let constants = Raw_context.constants c in constants.tx_rollup_max_ticket_payload_size +let tx_rollup_rejection_max_proof_size c = + let constants = Raw_context.constants c in + constants.tx_rollup_rejection_max_proof_size + let ratio_of_frozen_deposits_slashed_per_double_endorsement c = let constants = Raw_context.constants c in constants.ratio_of_frozen_deposits_slashed_per_double_endorsement diff --git a/src/proto_alpha/lib_protocol/constants_storage.mli b/src/proto_alpha/lib_protocol/constants_storage.mli index 0ac4f5b3e2..78119d5bc0 100644 --- a/src/proto_alpha/lib_protocol/constants_storage.mli +++ b/src/proto_alpha/lib_protocol/constants_storage.mli @@ -110,6 +110,8 @@ val tx_rollup_cost_per_byte_ema_factor : Raw_context.t -> int val tx_rollup_max_ticket_payload_size : Raw_context.t -> int +val tx_rollup_rejection_max_proof_size : Raw_context.t -> int + val ratio_of_frozen_deposits_slashed_per_double_endorsement : Raw_context.t -> Constants_repr.ratio diff --git a/src/proto_alpha/lib_protocol/operation_repr.ml b/src/proto_alpha/lib_protocol/operation_repr.ml index 6fc002bf5a..4a9ef3f137 100644 --- a/src/proto_alpha/lib_protocol/operation_repr.ml +++ b/src/proto_alpha/lib_protocol/operation_repr.ml @@ -712,7 +712,7 @@ module Encoding = struct (req "previous_message_result" Tx_rollup_commitment_repr.message_result_encoding) - (req "proof" bool); + (req "proof" Tx_rollup_l2_proof.encoding); select = (function | Manager (Tx_rollup_rejection _ as op) -> Some op | _ -> None); diff --git a/src/proto_alpha/lib_protocol/raw_context.ml b/src/proto_alpha/lib_protocol/raw_context.ml index fc27377f97..6b22758eb3 100644 --- a/src/proto_alpha/lib_protocol/raw_context.ml +++ b/src/proto_alpha/lib_protocol/raw_context.ml @@ -921,6 +921,7 @@ let prepare_first_block ~level ~timestamp ctxt = (* The default ema factor is [120] blocks, so about one hour. *) tx_rollup_cost_per_byte_ema_factor = 120; tx_rollup_max_ticket_payload_size = 10_240; + tx_rollup_rejection_max_proof_size = 30_000; sc_rollup_enable = false; (* The following value is chosen to prevent spam. *) sc_rollup_origination_size = 6_314; diff --git a/src/proto_alpha/lib_protocol/test/helpers/op.ml b/src/proto_alpha/lib_protocol/test/helpers/op.ml index b7971edb3c..1a7582fde0 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/op.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/op.ml @@ -641,7 +641,8 @@ let tx_rollup_withdraw ?counter ?fee ?gas_limit ?storage_limit ctxt let tx_rollup_reject ?counter ?fee ?gas_limit ?storage_limit ctxt (source : Contract.t) (tx_rollup : Tx_rollup.t) (level : Tx_rollup_level.t) (message : Tx_rollup_message.t) ~(message_position : int) - ~(message_path : Tx_rollup_inbox.Merkle.path) ~(proof : bool) + ~(message_path : Tx_rollup_inbox.Merkle.path) + ~(proof : Tx_rollup_l2_proof.t) ~(previous_message_result : Tx_rollup_commitment.message_result) = manager_operation ?counter diff --git a/src/proto_alpha/lib_protocol/test/helpers/op.mli b/src/proto_alpha/lib_protocol/test/helpers/op.mli index f5ce022582..81cd738d29 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/op.mli +++ b/src/proto_alpha/lib_protocol/test/helpers/op.mli @@ -352,6 +352,6 @@ val tx_rollup_reject : Tx_rollup_message.t -> message_position:int -> message_path:Tx_rollup_inbox.Merkle.path -> - proof:bool -> + proof:Tx_rollup_l2_proof.t -> previous_message_result:Tx_rollup_commitment.message_result -> Operation.packed tzresult Lwt.t diff --git a/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml b/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml index ff1f8a8cb5..661356b058 100644 --- a/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml +++ b/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml @@ -153,6 +153,7 @@ let burn_per_byte state = inbox_burn state 1 to not interfere with balances prediction. It returns the created context and [n] contracts. *) let context_init ?(tx_rollup_max_unfinalized_levels = 2100) + ?(tx_rollup_rejection_max_proof_size = 30_000) ?(tx_rollup_max_ticket_payload_size = 10_240) n = Context.init_with_constants { @@ -162,6 +163,7 @@ let context_init ?(tx_rollup_max_unfinalized_levels = 2100) tx_rollup_finality_period = 1; tx_rollup_withdraw_period = 1; tx_rollup_max_finalized_levels = 2; + tx_rollup_rejection_max_proof_size; tx_rollup_max_unfinalized_levels; endorsing_reward_per_slot = Tez.zero; baking_reward_bonus_per_slot = Tez.zero; @@ -174,10 +176,11 @@ let context_init ?(tx_rollup_max_unfinalized_levels = 2100) to not interfere with balances prediction. It returns the created context and 1 contract. *) let context_init1 ?tx_rollup_max_unfinalized_levels - ?tx_rollup_max_ticket_payload_size () = + ?tx_rollup_max_ticket_payload_size ?tx_rollup_rejection_max_proof_size () = context_init ?tx_rollup_max_unfinalized_levels ?tx_rollup_max_ticket_payload_size + ?tx_rollup_rejection_max_proof_size 1 >|=? function | (b, contract_1 :: _) -> (b, contract_1) @@ -216,6 +219,19 @@ let init_originate_and_submit ?(batch = String.make 5 'c') () = Block.bake ~operation b >>=? fun b -> return ((contract, balance), state, tx_rollup, b) +let l2_parameters : Tx_rollup_l2_apply.parameters = + let res = + Lwt_main.run + ( context_init1 () >>=? fun (b, _) -> + Incremental.begin_construction b >>=? fun i -> + let ctxt = Incremental.alpha_ctxt i in + let tx_rollup_max_withdrawals_per_batch = + Constants.tx_rollup_max_withdrawals_per_batch ctxt + in + return Tx_rollup_l2_apply.{tx_rollup_max_withdrawals_per_batch} ) + in + match res with Ok x -> x | Error _ -> assert false + let commitment_testable = Alcotest.testable Tx_rollup_commitment.pp Tx_rollup_commitment.( = ) @@ -287,16 +303,19 @@ let print_deposit_arg tx_rollup account = let assert_ok res = match res with Ok r -> r | Error _ -> assert false +let assert_some res = match res with Some r -> r | None -> assert false + let raw_level level = assert_ok @@ Raw_level.of_int32 level let merkle_root_empty_withdraw_list = Tx_rollup_withdraw.merkelize_list [] -(* Make a valid commitment for a batch. TODO/TORU: roots are still wrong, of - course, until we get Merkle proofs In the mean time provides the list of - withdraw in a association list of [batch_index -> withdraw_list]. - Be careful not to provide a too big withdraw_list as the construction - is expensive *) -let make_commitment_for_batch i level tx_rollup withdraw_list = +(** Create an incomplete (but valid) commitment for a given level. It + is incomplete in the sense that the Merkle roots for each message + are {!Tx_rollup_commitment.empty_l2_context_hash}. In the meantime + provides the list of withdraw in a association list of + [batch_index -> withdraw_list]. Be careful not to provide a too-big + withdraw_list as the construction is expensive *) +let make_incomplete_commitment_for_batch i level tx_rollup withdraw_list = let ctxt = Incremental.alpha_ctxt i in wrap (Alpha_context.Tx_rollup_inbox.get ctxt level tx_rollup) >>=? fun (ctxt, metadata) -> @@ -1234,7 +1253,7 @@ let test_commitment_duplication () = >>=? fun operation -> Block.bake ~operation b >>=? fun b -> Incremental.begin_construction b >>=? fun i -> - make_commitment_for_batch i Tx_rollup_level.root tx_rollup [] + make_incomplete_commitment_for_batch i Tx_rollup_level.root tx_rollup [] >>=? fun (commitment, _) -> (* Successfully fail to submit a different commitment from contract2 *) let batches2 : Tx_rollup_message_result_hash.t list = @@ -1337,7 +1356,7 @@ let test_commitment_predecessor () = Tx_rollup_commitment_hash.of_bytes_exn (Bytes.of_string "tcu1deadbeefdeadbeefdeadbeefdead") in - make_commitment_for_batch i Tx_rollup_level.root tx_rollup [] + make_incomplete_commitment_for_batch i Tx_rollup_level.root tx_rollup [] >>=? fun (commitment, _) -> let commitment_for_invalid_inbox = {commitment with level = tx_level 10l} in Op.tx_rollup_commit (I i) contract1 tx_rollup commitment_for_invalid_inbox @@ -1352,7 +1371,11 @@ let test_commitment_predecessor () = Op.tx_rollup_commit (I i) contract1 tx_rollup commitment >>=? fun op -> Incremental.add_operation i op >>=? fun i -> (* Commitment without predecessor for block with predecessor*) - make_commitment_for_batch i Tx_rollup_level.(succ root) tx_rollup [] + make_incomplete_commitment_for_batch + i + Tx_rollup_level.(succ root) + tx_rollup + [] >>=? fun (commitment, _) -> let commitment_with_missing_predecessor = {commitment with predecessor = None} @@ -1444,7 +1467,7 @@ let test_bond_finalization () = | Tx_rollup_errors.Bond_does_not_exist a_pkh1 -> a_pkh1 = pkh1 | _ -> false) >>=? fun i -> - make_commitment_for_batch i Tx_rollup_level.root tx_rollup [] + make_incomplete_commitment_for_batch i Tx_rollup_level.root tx_rollup [] >>=? fun (commitment_a, _) -> Op.tx_rollup_commit (I i) contract1 tx_rollup commitment_a >>=? fun op -> Incremental.add_operation i op >>=? fun i -> @@ -1491,7 +1514,8 @@ let test_too_many_commitments () = let rec make_commitments i level n = if n = 0 then return (i, level) else - make_commitment_for_batch i level tx_rollup [] >>=? fun (commitment, _) -> + make_incomplete_commitment_for_batch i level tx_rollup [] + >>=? fun (commitment, _) -> Op.tx_rollup_commit (I i) contract1 tx_rollup commitment >>=? fun op -> Incremental.add_operation i op >>=? fun i -> make_commitments i (Tx_rollup_level.succ level) (n - 1) @@ -1504,7 +1528,8 @@ let test_too_many_commitments () = Op.tx_rollup_finalize (I i) contract1 tx_rollup >>=? fun op -> Incremental.add_operation i op >>=? fun i -> (* Fail to add a new commitment. *) - make_commitment_for_batch i level tx_rollup [] >>=? fun (commitment, _) -> + make_incomplete_commitment_for_batch i level tx_rollup [] + >>=? fun (commitment, _) -> Op.tx_rollup_commit (I i) contract1 tx_rollup commitment >>=? fun op -> Incremental.add_operation i @@ -1525,37 +1550,437 @@ let test_too_many_commitments () = return () module Rejection = struct - let init_with_valid_commitment () = + open Protocol + + exception Error of Environment.Error_monad.error + + module Prover_storage : + Tx_rollup_l2_storage_sig.STORAGE + with type t = Tezos_context_memory.Context_binary.tree + and type 'a m = 'a Lwt.t = struct + type t = Tezos_context_memory.Context_binary.tree + + type 'a m = 'a Lwt.t + + module Syntax = struct + include Lwt.Syntax + + let return = Lwt.return + + let fail e = Lwt.fail (Error e) + + let catch (m : 'a m) k h = + Lwt.catch + (fun () -> m >>= k) + (function Error e -> h e | e -> Lwt.fail e) + + let list_fold_left_m = Lwt_list.fold_left_s + end + + let path k = [Bytes.to_string k] + + let get store key = + Tezos_context_memory.Context_binary.Tree.find store (path key) + + let set store key value = + Tezos_context_memory.Context_binary.Tree.add store (path key) value + + let remove store key = + Tezos_context_memory.Context_binary.Tree.remove store (path key) + end + + module Storage : + Tx_rollup_l2_storage_sig.STORAGE + with type t = Tezos_context_memory.Context_binary.t + and type 'a m = 'a Lwt.t = struct + type t = Tezos_context_memory.Context_binary.t + + type 'a m = 'a Lwt.t + + module Syntax = struct + include Lwt.Syntax + + let return = Lwt.return + + let fail e = Lwt.fail (Error e) + + let catch (m : 'a m) k h = + Lwt.catch + (fun () -> m >>= k) + (function Error e -> h e | e -> Lwt.fail e) + + let list_fold_left_m = Lwt_list.fold_left_s + end + + let path k = [Bytes.to_string k] + + let get store key = + Tezos_context_memory.Context_binary.find store (path key) + + let set store key value = + Tezos_context_memory.Context_binary.add store (path key) value + + let remove store key = + Tezos_context_memory.Context_binary.remove store (path key) + end + + module Prover_context = Tx_rollup_l2_context.Make (Prover_storage) + module Context = Tx_rollup_l2_context.Make (Storage) + module Prover_apply = Tx_rollup_l2_apply.Make (Prover_context) + module Apply = Tx_rollup_l2_apply.Make (Context) + module C = Tezos_context_memory.Context_binary + + let previous_message_result : Tx_rollup_commitment.message_result = + { + context_hash = Tx_rollup_commitment.empty_l2_context_hash; + withdrawals_merkle_root = Tx_rollup_withdraw.empty_withdrawals_merkle_root; + } + + let init_with_bogus_batch () = context_init1 () >>=? fun (b, contract1) -> originate b contract1 >>=? fun (b, tx_rollup) -> let message = "bogus" in Op.tx_rollup_submit_batch (B b) contract1 tx_rollup message >>=? fun operation -> Block.bake ~operation b >>=? fun b -> - Incremental.begin_construction b >>=? fun i -> + Incremental.begin_construction b >|=? fun i -> let level = Tx_rollup_level.root in - make_commitment_for_batch i level tx_rollup [] + (i, contract1, tx_rollup, level, message) + + let init_with_valid_commitment () = + init_with_bogus_batch () + >>=? fun (i, contract1, tx_rollup, level, message) -> + make_incomplete_commitment_for_batch i level tx_rollup [] >>=? fun (commitment, _batches_result) -> Op.tx_rollup_commit (I i) contract1 tx_rollup commitment >>=? fun op -> - Incremental.add_operation i op >>=? fun i -> - return (i, contract1, tx_rollup, level, message) + Incremental.add_operation i op >|=? fun i -> + (i, contract1, tx_rollup, level, message) - (** [test_success] tests that rejection succeeds if the commitment is - wrong and the proof is correct. *) - let test_success () = - init_with_valid_commitment () + let init_with_invalid_commitment () = + init_with_bogus_batch () >>=? fun (i, contract1, tx_rollup, level, message) -> - let proof = true in - let (message, _size) = Tx_rollup_message.make_batch message in + make_incomplete_commitment_for_batch i level tx_rollup [] + >>=? fun (commitment, _batches_result) -> + let commitment = + { + commitment with + messages = + [ + Tx_rollup_commitment.hash_message_result + { + context_hash = + Context_hash.of_b58check_exn + "CoUiEnajKeukmYFUgWTJF2z3v24MycpTaomF8a9hRzVy7as9hvgy"; + withdrawals_merkle_root = + Tx_rollup_withdraw.empty_withdrawals_merkle_root; + }; + ]; + } + in + Op.tx_rollup_commit (I i) contract1 tx_rollup commitment >>=? fun op -> + Incremental.add_operation i op >|=? fun i -> + (i, contract1, tx_rollup, level, message) + + let run_transaction ctxt msg = + let open Prover_context.Syntax in + let* (ctxt, _) = Prover_apply.apply_message ctxt l2_parameters msg in + return ctxt + + let time () = + Time.System.now () |> Time.System.to_notation + |> Time.Protocol.of_notation_exn + + (** [init_l2_store ()] creates the required empty storage and tree. + It creates a tree where the counters are explicitly set (it's an Irmin + restriction that we can not hash an empty tree). It returns the + persistent store containing the tree. + + {!Tx_rollup_commitment.empty_l2_context_hash} is the hash of the + tree produced in this function. + *) + let init_l2_store () = + let open Context.Syntax in + let store = C.empty in + let time = time () in + let tree = C.Tree.empty store in + let* tree = Prover_context.Address_index.init_counter tree in + let* tree = Prover_context.Ticket_index.init_counter tree in + let* ctxt = C.add_tree store [] tree in + let* h = C.commit ~time ctxt in + let index = C.index ctxt in + let* store = C.checkout_exn index h in + return store + + let get_tree_from_store store = + let open Context.Syntax in + let* tree_opt = C.find_tree store [] in + match tree_opt with Some x -> return x | None -> assert false + + let hash_tree_from_store store = + let open Context.Syntax in + let+ tree = get_tree_from_store store in + C.Tree.hash tree + + let commit_store store = + let open Context.Syntax in + let time = time () in + let* h = C.commit ~time store in + let index = C.index store in + let* store = C.checkout_exn index h in + return store + + (** See {!Tx_rollup_commitment.empty_l2_context_hash} documentation. + The constant is created from the hash of the underlying tree in + the store generated by {!init_l2_store}. We then add a regression + test to ensure these two are synchronized. *) + let test_empty_l2_context_hash () = + let open Context.Syntax in + let* store = init_l2_store () in + let* hash_tree = hash_tree_from_store store in + assert ( + Context_hash.(hash_tree = Tx_rollup_commitment.empty_l2_context_hash)) ; + return_unit + + (** [make_proof store msg] applies [msg] on [store] and returns the + created proof. *) + let make_proof store msg = + let open Context.Syntax in + let index = C.index store in + let* hash = hash_tree_from_store store in + let* (proof, ()) = + C.produce_stream_proof index (`Node hash) (fun ctxt -> + catch + (run_transaction ctxt msg) + (fun ctxt -> return (ctxt, ())) + (fun _ -> return (ctxt, ()))) + in + return proof + + let valid_empty_proof () = + let open Context.Syntax in + let* l2_store = init_l2_store () in + let (message, _) = Tx_rollup_message.make_batch "bogus" in + make_proof l2_store message + + let invalid_proof : Tx_rollup_l2_proof.t = + { + version = 1; + before = `Value Tx_rollup_commitment.empty_l2_context_hash; + after = `Value Context_hash.zero; + state = Seq.empty; + } + + (** Takes a commitment and replaces the message results with valid results. + + FIXME/TORU: this overrides the withdrawals merkle roots. This is not good + but there is yet not tests calling this function which uses these roots. + Although, it shouldn't be to hard to fix this. *) + let replace_commitment ~store ~commitment messages = + let open Context in + let open Syntax in + let* (_, rev_results) = + list_fold_left_m + (fun (store, rev_results) msg -> + let* store = + catch + (Apply.apply_message store l2_parameters msg) + (fun (store, _) -> return store) + (fun _reason -> return store) + in + let* hash_tree = hash_tree_from_store store in + let result_hash = + Tx_rollup_commitment.hash_message_result + { + context_hash = hash_tree; + withdrawals_merkle_root = merkle_root_empty_withdraw_list; + } + in + return (store, result_hash :: rev_results)) + (store, []) + messages + in + let results = List.rev rev_results in + return Tx_rollup_commitment.{commitment with messages = results} + + (** Produce an invalid commitment with {!make_incomplete_commitment_for_batch}, + then changes the Merkle roots for each message result. + + FIXME/TORU: it is not perfectly valid, the withdrawals are still missing. + see {!replace_commitment} documentation. *) + let make_valid_commitment_for_messages ~i ~level ~tx_rollup + ?(withdrawals = []) ~store messages = + make_incomplete_commitment_for_batch i level tx_rollup withdrawals + >>=? fun (commitment, _) -> + replace_commitment ~commitment ~store messages >>= fun commitment -> + return commitment + + (** Create a deposit on the layer1 side through the origination of a contract + and return the associated deposit message to apply in the layer2. *) + let make_deposit b tx_rollup account = + let (sk, pk, addr) = gen_l2_account () in + Contract_helpers.originate_contract + "contracts/tx_rollup_deposit.tz" + "Unit" + account + b + (is_implicit_exn account) + >>=? fun (contract, b) -> + let parameters = print_deposit_arg (`Typed tx_rollup) (`Hash addr) in + let fee = Test_tez.of_int 10 in + Op.transaction + ~counter:(Z.of_int 2) + ~fee + (B b) + account + contract + Tez.zero + ~parameters + >>=? fun operation -> + Block.bake ~operation b >>=? fun b -> + make_unit_ticket_key (B b) ~ticketer:contract tx_rollup + >>=? fun ticket_hash -> + let (deposit, _) = + Tx_rollup_message.make_deposit + (is_implicit_exn account) + (Tx_rollup_l2_address.Indexable.value addr) + ticket_hash + (Tx_rollup_l2_qty.of_int64_exn 10L) + in + return (b, deposit, (sk, pk, addr), ticket_hash) + + let init_with_deposit () = + init_l2_store () >>= fun store -> + context_init1 () >>=? fun (b, account) -> + originate b account >>=? fun (b, tx_rollup) -> + make_deposit b tx_rollup account + >>=? fun (b, deposit, l2_account, ticket_hash) -> + let deposit_hash = Tx_rollup_message.hash_uncarbonated deposit in + let message_path = + match Tx_rollup_inbox.Merkle.(compute_path [deposit_hash] 0) with + | Error _ -> assert false + | Ok path -> path + in + Incremental.begin_construction b >>=? fun i -> + make_valid_commitment_for_messages + ~i + ~level:Tx_rollup_level.root + ~tx_rollup + ~store + [deposit] + >>=? fun commitment -> + Op.tx_rollup_commit (I i) account tx_rollup commitment >>=? fun op -> + Incremental.add_operation i op >>=? fun i -> + Incremental.finalize_block i >>=? fun b -> + (* We try to reject the previous commitment, but as it was valid, + we can not reject a valid state. We do not really need to test this + here, as there are dedicated tests, but this behaves like a regression + test. *) + make_proof store deposit >>= fun proof -> + Incremental.begin_construction b >>=? fun i -> + Op.tx_rollup_reject + (I i) + account + tx_rollup + Tx_rollup_level.root + deposit + ~message_position:0 + ~message_path + ~proof + ~previous_message_result + >>=? fun op -> + Incremental.add_operation + i + op + ~expect_failure: + (check_proto_error Tx_rollup_errors.Proof_produced_rejected_state) + >>=? fun i -> + Incremental.finalize_block i >>=? fun b -> + (* Finally, we apply the deposit manually to have the good resulting store + for next operations *) + Apply.apply_message store l2_parameters deposit >>= fun (store, _) -> + commit_store store >>= fun store -> + return (b, account, tx_rollup, store, l2_account, ticket_hash) + + let operation_content destination ticket_hash qty = + let open Tx_rollup_l2_batch.V1 in + Transfer + { + destination = Indexable.from_value destination; + ticket_hash = Indexable.from_value ticket_hash; + qty = Tx_rollup_l2_qty.of_int64_exn qty; + } + + let operation signer ?(counter = 1L) contents = + let open Tx_rollup_l2_batch.V1 in + {signer = Indexable.from_value signer; counter; contents} + + let make_transfers src counter transfers = + let rec contents acc = function + | [] -> acc + | (destination, ticket_hash, qty) :: rst -> + let acc = operation_content destination ticket_hash qty :: acc in + contents acc rst + in + let contents = contents [] transfers in + operation src ?counter contents + + let make_message_transfer ~signers all_transfers = + let transaction = + List.map + (fun (src, counter, transfers) -> make_transfers src counter transfers) + all_transfers + in + let signatures = + Tx_rollup_l2_helpers.sign_transaction signers transaction + in + let signature = + assert_some + @@ Environment.Bls_signature.aggregate_signature_opt signatures + in + let batch = + Tx_rollup_l2_batch.V1. + {contents = [transaction]; aggregated_signature = signature} + in + let batch_bytes = + Data_encoding.Binary.to_string_exn Tx_rollup_l2_batch.encoding (V1 batch) + in + let msg = Tx_rollup_message.make_batch batch_bytes |> fst in + (msg, batch_bytes) + + (** Test that we can produce a simple but valid proof. *) + let test_valid_proof_on_invalid_commitment () = + init_with_deposit () + >>=? fun (b, account, tx_rollup, store, (sk, pk, _pkh), ticket_hash) -> + hash_tree_from_store store >>= fun l2_context_hash -> + (* Create a transfer from [pk] to a new address *) + let (_, _, addr) = gen_l2_account () in + let (message, batch_bytes) = + make_message_transfer + ~signers:[sk] + [(Bls_pk pk, None, [(addr, ticket_hash, 1L)])] + in let message_hash = Tx_rollup_message.hash_uncarbonated message in let message_path = match Tx_rollup_inbox.Merkle.(compute_path [message_hash] 0) with | Error _ -> assert false | Ok path -> path in + Op.tx_rollup_submit_batch (B b) account tx_rollup batch_bytes + >>=? fun operation -> + Block.bake ~operation b >>=? fun b -> + (* Make an invalid commitment for the submitted transfer *) + let level = Tx_rollup_level.(succ root) in + Incremental.begin_construction b >>=? fun i -> + make_incomplete_commitment_for_batch i level tx_rollup [] + >>=? fun (commitment, _) -> + Op.tx_rollup_commit (I i) account tx_rollup commitment >>=? fun op -> + Incremental.add_operation i op >>=? fun i -> + Incremental.finalize_block i >>=? fun b -> + (* Now we produce a valid proof rejecting the commitment *) + make_proof store message >>= fun proof -> Op.tx_rollup_reject - (I i) - contract1 + (B b) + account tx_rollup level message @@ -1564,32 +1989,107 @@ module Rejection = struct ~proof ~previous_message_result: { - context_hash = Tx_rollup_commitment.empty_l2_context_hash; + context_hash = l2_context_hash; withdrawals_merkle_root = Tx_rollup_withdraw.empty_withdrawals_merkle_root; } >>=? fun op -> + Incremental.add_operation i op >>=? fun _ -> return_unit + + (** It is really similar to {!test_valid_proof_on_invalid_commitment} but it + tries to reject a valid commitment, thus, fails. *) + let test_valid_proof_on_valid_commitment () = + init_with_deposit () + >>=? fun (b, account, tx_rollup, store, (sk, pk, _pkh), ticket_hash) -> + hash_tree_from_store store >>= fun l2_context_hash -> + (* Create a transfer from [pk] to a new address *) + let (_, _, addr) = gen_l2_account () in + let (message, batch_bytes) = + make_message_transfer + ~signers:[sk] + [(Bls_pk pk, None, [(addr, ticket_hash, 1L)])] + in + let message_hash = Tx_rollup_message.hash_uncarbonated message in + let message_path = + match Tx_rollup_inbox.Merkle.(compute_path [message_hash] 0) with + | Error _ -> assert false + | Ok path -> path + in + Op.tx_rollup_submit_batch (B b) account tx_rollup batch_bytes + >>=? fun operation -> + Block.bake ~operation b >>=? fun b -> + (* Make an invalid commitment for the submitted transfer *) + let level = Tx_rollup_level.(succ root) in + Incremental.begin_construction b >>=? fun i -> + make_valid_commitment_for_messages ~i ~level ~tx_rollup ~store [message] + >>=? fun commitment -> + Op.tx_rollup_commit (I i) account tx_rollup commitment >>=? fun op -> Incremental.add_operation i op >>=? fun i -> - ignore i ; - - return () + Incremental.finalize_block i >>=? fun b -> + (* Now we produce a valid proof rejecting the commitment *) + make_proof store message >>= fun proof -> + Op.tx_rollup_reject + (B b) + account + tx_rollup + level + message + ~message_position:0 + ~message_path + ~proof + ~previous_message_result: + { + context_hash = l2_context_hash; + withdrawals_merkle_root = + Tx_rollup_withdraw.empty_withdrawals_merkle_root; + } + >>=? fun op -> + Incremental.add_operation + i + op + ~expect_failure: + (check_proto_error_f @@ function + | Tx_rollup_errors.Proof_produced_rejected_state -> true + | _ -> false) + >>=? fun _ -> return_unit - (** [test_invalid_proof] tests that rejection successfully fails - with an invalid proof. *) - let test_invalid_proof () = - init_with_valid_commitment () - >>=? fun (i, contract1, tx_rollup, level, message) -> - let proof = false in - let (message, _size) = Tx_rollup_message.make_batch message in + (** Test the proof production (used in this test file) and the proof + verification handles a hard failure. For instance, we try to + a proof with a ill-signed batch. *) + let test_proof_with_hard_fail_message () = + init_with_deposit () + >>=? fun (b, account, tx_rollup, store, (_sk, pk, addr), ticket_hash) -> + hash_tree_from_store store >>= fun l2_context_hash -> + (* We build a dummy transfer, we don't care about the content, it will hard + fail on the check signature. *) + let (random_sk, _, _) = gen_l2_account () in + let (message, batch_bytes) = + make_message_transfer + ~signers:[random_sk] + [(Bls_pk pk, None, [(addr, ticket_hash, 1L)])] + in let message_hash = Tx_rollup_message.hash_uncarbonated message in let message_path = match Tx_rollup_inbox.Merkle.(compute_path [message_hash] 0) with | Error _ -> assert false | Ok path -> path in + Op.tx_rollup_submit_batch (B b) account tx_rollup batch_bytes + >>=? fun operation -> + Block.bake ~operation b >>=? fun b -> + (* Make an invalid commitment for the submitted transfer *) + let level = Tx_rollup_level.(succ root) in + Incremental.begin_construction b >>=? fun i -> + make_incomplete_commitment_for_batch i level tx_rollup [] + >>=? fun (commitment, _) -> + Op.tx_rollup_commit (I i) account tx_rollup commitment >>=? fun op -> + Incremental.add_operation i op >>=? fun i -> + Incremental.finalize_block i >>=? fun b -> + (* Now we produce a valid proof rejecting the commitment *) + make_proof store message >>= fun proof -> Op.tx_rollup_reject - (I i) - contract1 + (B b) + account tx_rollup level message @@ -1598,27 +2098,75 @@ module Rejection = struct ~proof ~previous_message_result: { - context_hash = Tx_rollup_commitment.empty_l2_context_hash; + context_hash = l2_context_hash; withdrawals_merkle_root = Tx_rollup_withdraw.empty_withdrawals_merkle_root; } >>=? fun op -> + Incremental.add_operation i op >>=? fun _ -> return_unit + + (** Test that an empty proof is enough to reject a commitment on an + invalid message. Yhe committed message does not change the + context at all (i.e. the message can not be decoded). *) + let test_empty_proof_on_invalid_message () = + init_with_invalid_commitment () + >>=? fun (i, contract, tx_rollup, level, message) -> + let (msg, _) = Tx_rollup_message.make_batch message in + let message_hash = Tx_rollup_message.hash_uncarbonated msg in + let message_path = + match Tx_rollup_inbox.Merkle.(compute_path [message_hash] 0) with + | Error _ -> assert false + | Ok path -> path + in + valid_empty_proof () >>= fun proof -> + Op.tx_rollup_reject + (I i) + contract + tx_rollup + level + msg + ~message_position:0 + ~message_path + ~proof + ~previous_message_result + >>=? fun op -> + Incremental.add_operation i op >>=? fun _ -> return_unit + + (** Test that an empty proof is not able to reject a valid commitment. *) + let test_invalid_proof_on_invalid_commitment () = + init_with_valid_commitment () + >>=? fun (i, contract, tx_rollup, level, message) -> + let (msg, _) = Tx_rollup_message.make_batch message in + let message_hash = Tx_rollup_message.hash_uncarbonated msg in + let message_path = + match Tx_rollup_inbox.Merkle.(compute_path [message_hash] 0) with + | Error _ -> assert false + | Ok path -> path + in + Op.tx_rollup_reject + (I i) + contract + tx_rollup + level + msg + ~message_position:0 + ~message_path + ~proof:invalid_proof + ~previous_message_result + >>=? fun op -> Incremental.add_operation i op - ~expect_failure:(check_proto_error Tx_rollup_errors.Invalid_proof) - >>=? fun i -> - ignore i ; - - return () + ~expect_failure: + (check_proto_error Tx_rollup_errors.Proof_failed_to_reject) + >>=? fun _ -> return_unit - (** [test_invalid_agreed] tests that rejection successfully fails - when there is a disagreement about the previous state. *) + (** Test that rejection successfully fails when there is a disagreement about + the previous state. *) let test_invalid_agreed () = init_with_valid_commitment () - >>=? fun (i, contract1, tx_rollup, level, message) -> - let proof = false in - let (message, _size) = Tx_rollup_message.make_batch message in + >>=? fun (i, contract, tx_rollup, level, message) -> + let (msg, _) = Tx_rollup_message.make_batch message in (* This intentionally does not match *) let previous_message_result : Tx_rollup_commitment.message_result = { @@ -1628,7 +2176,7 @@ module Rejection = struct Tx_rollup_withdraw.empty_withdrawals_merkle_root; } in - let message_hash = Tx_rollup_message.hash_uncarbonated message in + let message_hash = Tx_rollup_message.hash_uncarbonated msg in let message_path = match Tx_rollup_inbox.Merkle.(compute_path [message_hash] 0) with | Error _ -> assert false @@ -1636,13 +2184,13 @@ module Rejection = struct in Op.tx_rollup_reject (I i) - contract1 + contract tx_rollup level - message + msg ~message_position:0 ~message_path - ~proof + ~proof:invalid_proof (* doesn't matter -- we'll never check it*) ~previous_message_result >>=? fun op -> Incremental.add_operation @@ -1658,28 +2206,24 @@ module Rejection = struct "txmr3jXfJ6zu4AAxg6VEnDAXxDYyucP3ZPoLuzxLn4QcRsyArSHMmX"; expected = Tx_rollup_message_result_hash.of_b58check_exn - "txmr2RQL6pMQMkjZwL28kEeyAGpmaorNx2nT6G9JpQj81ER4XqDpD7"; + "txmr1zhXvqor6BUgtzA6GKtWLK7orXHNiYtCmQ3R4RJPCNxoF4jQCS"; })) - >>=? fun i -> - ignore i ; - - return () + >>=? fun _ -> return_unit - (** [test_no_commitment] tests that rejection successfully fails - when there's no commitment to reject *) + (** Test that rejection successfully fails when there's no commitment to + reject *) let test_no_commitment () = - context_init 2 >>=? fun (b, contracts) -> - let contract1 = + context_init 1 >>=? fun (b, contracts) -> + let contract = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 0 in - originate b contract1 >>=? fun (b, tx_rollup) -> + originate b contract >>=? fun (b, tx_rollup) -> let message = "bogus" in - Op.tx_rollup_submit_batch (B b) contract1 tx_rollup message + Op.tx_rollup_submit_batch (B b) contract tx_rollup message >>=? fun operation -> Block.bake ~operation b >>=? fun b -> Incremental.begin_construction b >>=? fun i -> let level = Tx_rollup_level.root in - let proof = true in let (message, _size) = Tx_rollup_message.make_batch message in let message_hash = Tx_rollup_message.hash_uncarbonated message in let message_path = @@ -1687,21 +2231,17 @@ module Rejection = struct | Error _ -> assert false | Ok path -> path in + valid_empty_proof () >>= fun proof -> Op.tx_rollup_reject (I i) - contract1 + contract tx_rollup level message ~message_position:0 ~message_path ~proof - ~previous_message_result: - { - context_hash = Tx_rollup_commitment.empty_l2_context_hash; - withdrawals_merkle_root = - Tx_rollup_withdraw.empty_withdrawals_merkle_root; - } + ~previous_message_result >>=? fun op -> Incremental.add_operation i @@ -1710,30 +2250,26 @@ module Rejection = struct (check_proto_error (Tx_rollup_errors.Cannot_reject_level {provided = level; accepted_range = None})) - >>=? fun i -> - ignore i ; - - return () + >>=? fun _ -> return_unit - (** [test_commitment_is_final] tests that rejection successfully fails - when the rejected commitment is already final *) + (** Test that rejection successfully fails when the rejected commitment is + already final *) let test_commitment_is_final () = init_with_valid_commitment () - >>=? fun (i, contract1, tx_rollup, level, message) -> - (* Create a new commitment so that once we have finalized the fist one, + >>=? fun (i, contract, tx_rollup, level, message) -> + (* Create a new commitment so that once we have finalized the first one, we still have a range of valid final commitments *) - Op.tx_rollup_submit_batch (I i) contract1 tx_rollup message >>=? fun op -> + Op.tx_rollup_submit_batch (I i) contract tx_rollup message >>=? fun op -> Incremental.add_operation i op >>=? fun i -> Incremental.finalize_block i >>=? fun b -> Incremental.begin_construction b >>=? fun i -> let level2 = Tx_rollup_level.succ level in - make_commitment_for_batch i level2 tx_rollup [] - >>=? fun (commitment2, _batches_result) -> - Op.tx_rollup_commit (I i) contract1 tx_rollup commitment2 >>=? fun op -> + make_incomplete_commitment_for_batch i level2 tx_rollup [] + >>=? fun (commitment2, _) -> + Op.tx_rollup_commit (I i) contract tx_rollup commitment2 >>=? fun op -> Incremental.add_operation i op >>=? fun i -> - Op.tx_rollup_finalize (I i) contract1 tx_rollup >>=? fun op -> + Op.tx_rollup_finalize (I i) contract tx_rollup >>=? fun op -> Incremental.add_operation i op >>=? fun i -> - let proof = true in let (message, _size) = Tx_rollup_message.make_batch message in let message_hash = Tx_rollup_message.hash_uncarbonated message in let message_path = @@ -1741,21 +2277,17 @@ module Rejection = struct | Error _ -> assert false | Ok path -> path in + valid_empty_proof () >>= fun proof -> Op.tx_rollup_reject (I i) - contract1 + contract tx_rollup level message ~message_position:0 ~message_path ~proof - ~previous_message_result: - { - context_hash = Tx_rollup_commitment.empty_l2_context_hash; - withdrawals_merkle_root = - Tx_rollup_withdraw.empty_withdrawals_merkle_root; - } + ~previous_message_result >>=? fun op -> Incremental.add_operation i @@ -1764,17 +2296,18 @@ module Rejection = struct (check_proto_error (Tx_rollup_errors.Cannot_reject_level {provided = level; accepted_range = Some (level2, level2)})) - >>=? fun i -> - ignore i ; - - return () + >>=? fun _ -> return_unit - (** [test_wrong_message_hash] tests that rejection successfully fails - when the message hash does not match the one stored in the inbox *) + (** Test that rejection successfully fails when the message hash does not + match the one stored in the inbox *) let test_wrong_message_hash () = init_with_valid_commitment () - >>=? fun (i, contract1, tx_rollup, level, _message) -> - let proof = true in + >>=? fun (i, contract1, tx_rollup, level, prev_message) -> + let (prev_message, _size) = Tx_rollup_message.make_batch prev_message in + let prev_message_hash = Tx_rollup_message.hash_uncarbonated prev_message in + let expected_root = + Tx_rollup_inbox.Merkle.merklize_list [prev_message_hash] + in let (message, _size) = Tx_rollup_message.make_batch "wrong message" in let message_hash = Tx_rollup_message.hash_uncarbonated message in let message_path = @@ -1782,6 +2315,7 @@ module Rejection = struct | Error _ -> assert false | Ok path -> path in + valid_empty_proof () >>= fun proof -> Op.tx_rollup_reject (I i) contract1 @@ -1791,30 +2325,21 @@ module Rejection = struct ~message_position:0 ~message_path ~proof - ~previous_message_result: - { - context_hash = Tx_rollup_commitment.empty_l2_context_hash; - withdrawals_merkle_root = - Tx_rollup_withdraw.empty_withdrawals_merkle_root; - } + ~previous_message_result >>=? fun op -> - let expected = - Tx_rollup_inbox.Merkle.root_of_b58check_opt - "txi1pvHiq799LSL2SXnRipQoCmSHnJ3SYH6SqjvJEQEKyfCLj3hCh" - |> Option.value_f ~default:(fun () -> assert false) - in - let error = Tx_rollup_errors.Wrong_message_path {expected} in - Incremental.add_operation i op ~expect_failure:(check_proto_error error) - >>=? fun i -> - ignore i ; - return () + Incremental.add_operation + i + op + ~expect_failure: + (check_proto_error + (Tx_rollup_errors.Wrong_message_path {expected = expected_root})) + >>=? fun _ -> return_unit - (** [test_wrong_message_position] tests that rejection successfully fails - when the message position does exist in the inbox *) + (** Test that rejection successfully fails when the message position does + exist in the inbox. *) let test_wrong_message_position () = init_with_valid_commitment () >>=? fun (i, contract1, tx_rollup, level, message) -> - let proof = true in let (message, _size) = Tx_rollup_message.make_batch message in let message_hash = Tx_rollup_message.hash_uncarbonated message in let message_path = @@ -1822,6 +2347,7 @@ module Rejection = struct | Error _ -> assert false | Ok path -> path in + valid_empty_proof () >>= fun proof -> Op.tx_rollup_reject (I i) contract1 @@ -1831,12 +2357,7 @@ module Rejection = struct ~message_position:1 ~message_path ~proof - ~previous_message_result: - { - context_hash = Tx_rollup_commitment.empty_l2_context_hash; - withdrawals_merkle_root = - Tx_rollup_withdraw.empty_withdrawals_merkle_root; - } + ~previous_message_result >>=? fun op -> Incremental.add_operation i @@ -1845,38 +2366,276 @@ module Rejection = struct (check_proto_error (Tx_rollup_errors.Wrong_message_position {level; position = 1; length = 1})) + >>=? fun _ -> return () + + (** Test rejecting a commitment to a non-trivial message -- that is, + not a no-op. *) + let test_nontrivial_rejection () = + let (_, _, addr) = gen_l2_account () in + init_l2_store () >>= fun store -> + context_init1 () >>=? fun (b, account) -> + originate b account >>=? fun (b, tx_rollup) -> + Contract_helpers.originate_contract + "contracts/tx_rollup_deposit.tz" + "Unit" + account + b + (is_implicit_exn account) + >>=? fun (contract, b) -> + let parameters = print_deposit_arg (`Typed tx_rollup) (`Hash addr) in + let fee = Test_tez.of_int 10 in + Op.transaction + ~counter:(Z.of_int 2) + ~fee + (B b) + account + contract + Tez.zero + ~parameters + >>=? fun operation -> + Block.bake ~operation b >>=? fun b -> + make_unit_ticket_key (B b) ~ticketer:contract tx_rollup + >>=? fun ticket_hash -> + let (deposit_message, _size) = + Tx_rollup_message.make_deposit + (is_implicit_exn account) + (Tx_rollup_l2_address.Indexable.value addr) + ticket_hash + (Tx_rollup_l2_qty.of_int64_exn 10L) + in + let message_hash = Tx_rollup_message.hash_uncarbonated deposit_message in + let message_path = + match Tx_rollup_inbox.Merkle.(compute_path [message_hash] 0) with + | Error _ -> assert false + | Ok path -> path + in + Incremental.begin_construction b >>=? fun i -> + make_incomplete_commitment_for_batch i Tx_rollup_level.root tx_rollup [] + >>=? fun (commitment, _) -> + Op.tx_rollup_commit (I i) account tx_rollup commitment >>=? fun op -> + Incremental.add_operation i op >>=? fun i -> + Incremental.finalize_block i >>=? fun b -> + Incremental.begin_construction b >>=? fun i -> + Op.tx_rollup_reject + (I i) + account + tx_rollup + Tx_rollup_level.root + deposit_message + ~message_position:0 + ~message_path + ~proof:invalid_proof + ~previous_message_result + >>=? fun op -> + Incremental.add_operation + i + op + ~expect_failure: + (check_proto_error Tx_rollup_errors.Proof_failed_to_reject) >>=? fun i -> - ignore i ; + (* Check with a reasonable proof *) + make_proof store deposit_message >>= fun proof -> + Op.tx_rollup_reject + (I i) + account + tx_rollup + Tx_rollup_level.root + deposit_message + ~message_position:0 + ~message_path + ~proof + ~previous_message_result + >>=? fun op -> + Incremental.add_operation i op >>=? fun _ -> return_unit + + let add_store_to_ctxt ctxt store = + let open Context.Syntax in + let time = Time.Protocol.of_seconds 0L in + let* ctxt = C.add_tree ctxt [] store in + let* h = C.commit ~time ctxt in + let index = C.index ctxt in + let* ctxt = C.checkout_exn index h in + return ctxt + + let test_large_rejection size = + let (_sk, _pk, addr) = gen_l2_account () in + init_l2_store () >>= fun store -> + context_init1 ~tx_rollup_rejection_max_proof_size:size () + >>=? fun (b, account) -> + originate b account >>=? fun (b, tx_rollup) -> + Contract_helpers.originate_contract + "contracts/tx_rollup_deposit.tz" + "Unit" + account + b + (is_implicit_exn account) + >>=? fun (contract, b) -> + let parameters = print_deposit_arg (`Typed tx_rollup) (`Hash addr) in + let fee = Test_tez.of_int 10 in + Op.transaction + ~counter:(Z.of_int 2) + ~fee + (B b) + account + contract + Tez.zero + ~parameters + >>=? fun operation -> + Block.bake ~operation b >>=? fun b -> + make_unit_ticket_key (B b) ~ticketer:contract tx_rollup + >>=? fun ticket_hash -> + let (deposit, _) = + Tx_rollup_message.make_deposit + (is_implicit_exn account) + (Tx_rollup_l2_address.Indexable.value addr) + ticket_hash + (Tx_rollup_l2_qty.of_int64_exn 10L) + in + let deposit_hash = Tx_rollup_message.hash_uncarbonated deposit in + let message_path = + match Tx_rollup_inbox.Merkle.(compute_path [deposit_hash] 0) with + | Error _ -> assert false + | Ok path -> path + in + Incremental.begin_construction b >>=? fun i -> + make_valid_commitment_for_messages + ~i + ~level:Tx_rollup_level.root + ~tx_rollup + ~store + [deposit] + >>=? fun commitment -> + Op.tx_rollup_commit (I i) account tx_rollup commitment >>=? fun op -> + Incremental.add_operation i op >>=? fun i -> + Incremental.finalize_block i >>=? fun b -> + (* The previous commitment produced a valid after hash. However, the + proof required is above [size], so the rejection should succeed. *) + make_proof store deposit >>= fun proof -> + Incremental.begin_construction b >>=? fun i -> + Op.tx_rollup_reject + (I i) + account + tx_rollup + Tx_rollup_level.root + deposit + ~message_position:0 + ~message_path + ~proof + ~previous_message_result + >>=? fun op -> return (i, op) + + (** Test that a commitment which require a too-large proof can be rejected + even if the after hash is correct. *) + let test_too_large_rejection () = + (* With a limit, the commitment is rejected because the required proof + is above the limit. *) + test_large_rejection 100 >>=? fun (i, op) -> + Incremental.add_operation i op >>=? fun _ -> + (* With a high limit, the commitment can not be rejected as it is valid *) + test_large_rejection 10_000 >>=? fun (i, op) -> + Incremental.add_operation + i + ~expect_failure: + (check_proto_error Tx_rollup_errors.Proof_produced_rejected_state) + op + >>=? fun _ -> return_unit - return () + (** Drop the last element of a seq, that is, the last element of a proof *) + let rec drop x = + let open Seq in + match x with + | Cons (x, xs) -> ( + let node = xs () in + match node with Nil -> Nil | n -> Cons (x, fun () -> drop n)) + | Nil -> assert false + + let test_valid_proof_truncated () = + init_l2_store () >>= fun store -> + context_init1 ~tx_rollup_rejection_max_proof_size:100 () + >>=? fun (b, account) -> + originate b account >>=? fun (b, tx_rollup) -> + make_deposit b tx_rollup account >>=? fun (b, deposit, _, _) -> + let deposit_hash = Tx_rollup_message.hash_uncarbonated deposit in + let message_path = + match Tx_rollup_inbox.Merkle.(compute_path [deposit_hash] 0) with + | Error _ -> assert false + | Ok path -> path + in + Incremental.begin_construction b >>=? fun i -> + let level = Tx_rollup_level.root in + make_valid_commitment_for_messages ~i ~level ~store ~tx_rollup [deposit] + >>=? fun commitment -> + Op.tx_rollup_commit (I i) account tx_rollup commitment >>=? fun op -> + Incremental.add_operation i op >>=? fun i -> + Incremental.finalize_block i >>=? fun b -> + (* The previous commitment produced a valid after hash. However, the + proof required is above [size], so the rejection should succeed with + a truncated proof. *) + make_proof store deposit >>= fun proof -> + let proof_truncated = + let proof_node = proof.state () in + let truncated_node = drop proof_node in + {proof with state = (fun () -> truncated_node)} + in + (* We try to reject with the truncated proof which is already above the + size limit. *) + Incremental.begin_construction b >>=? fun i -> + Op.tx_rollup_reject + (I i) + account + tx_rollup + Tx_rollup_level.root + deposit + ~message_position:0 + ~message_path + ~proof:proof_truncated + ~previous_message_result + >>=? fun op -> + Incremental.add_operation i op >>=? fun _ -> return_unit let tests = [ - Tztest.tztest "Test rejection happy path" `Quick test_success; Tztest.tztest - "Test rejection with invalid agreed" + "regression test empty_l2_context_hash" `Quick - test_invalid_agreed; + test_empty_l2_context_hash; Tztest.tztest - "Test rejection with invalid proof" + "reject invalid commitment" `Quick - test_invalid_proof; + test_valid_proof_on_invalid_commitment; Tztest.tztest - "Test rejection with no commitment" + "reject valid commitment fails" `Quick - test_no_commitment; + test_valid_proof_on_valid_commitment; Tztest.tztest - "Test rejection with final commitment" + "proof for a hard failing message" `Quick - test_commitment_is_final; + test_proof_with_hard_fail_message; Tztest.tztest - "Test rejection with wrong message" + "empty proof for an invalid message" `Quick - test_wrong_message_hash; + test_empty_proof_on_invalid_message; Tztest.tztest - "Test rejection with wrong message position" + "reject with invalid proof" + `Quick + test_invalid_proof_on_invalid_commitment; + Tztest.tztest "reject with invalid agreed" `Quick test_invalid_agreed; + Tztest.tztest "reject with no commitment" `Quick test_no_commitment; + Tztest.tztest "reject with wrong message" `Quick test_wrong_message_hash; + Tztest.tztest + "reject with wrong message position" `Quick test_wrong_message_position; + Tztest.tztest "reject too-large proof" `Quick test_too_large_rejection; + Tztest.tztest "reject a final commitment" `Quick test_commitment_is_final; + Tztest.tztest + "test successful and unsuccessful rejection of nontrivial message" + `Quick + test_nontrivial_rejection; + Tztest.tztest + "reject with a truncated proof above the limit" + `Quick + test_valid_proof_truncated; ] end @@ -1889,6 +2648,8 @@ let test_state () = Incremental.begin_construction b >>=? fun i -> let ctxt = Incremental.alpha_ctxt i in let (message, _) = Tx_rollup_message.make_batch "bogus" in + let message_hash = Tx_rollup_message.hash_uncarbonated message in + let inbox_hash = Tx_rollup_inbox.Merkle.merklize_list [message_hash] in let state = Tx_rollup_state.initial_state in wrap (Tx_rollup_inbox.append_message ctxt tx_rollup state message) >>=? fun (ctxt, state) -> @@ -1904,7 +2665,6 @@ let test_state () = append_inbox i ctxt state >>=? fun (i, ctxt, state) -> append_inbox i ctxt state >>=? fun (i, ctxt, state) -> let level0 = Tx_rollup_level.root in - let inbox_hash = Tx_rollup_inbox.hash_inbox [message] in let add_commitment ctxt state level predecessor = let commitment = Tx_rollup_commitment. @@ -1912,7 +2672,7 @@ let test_state () = level; messages = [Tx_rollup_message_result_hash.zero]; predecessor; - inbox_hash; + inbox_merkle_root = inbox_hash; } in wrap @@ -2138,14 +2898,14 @@ module Withdraw = struct (account1, account2, tx_rollup, deposit_contract, withdraw_contract, b) (** [context_finalize_batch_with_withdrawals account tx_rollup batch withdrawals b] - submits a batch containing the message [batch] to [tx_rollup] in the block [b]. - In the following block, it adds a commitment for that block containing - [withdrawals] (same format as in [make_commitment_for_batch]). - In the third and final block, it finalizes the commitment. + submits a batch containing the message [batch] to [tx_rollup] in the block [b]. + In the following block, it adds a commitment for that block containing + [withdrawals] (same format as in [make_incomplete_commitment_for_batch]). + In the third and final block, it finalizes the commitment. - It returns the commitment and a list of dummy context hashes - that was mocked as the result of the applying the batch. - *) + It returns the commitment and a list of dummy context hashes + that was mocked as the result of the applying the batch. + *) let context_finalize_batch_with_withdrawals ~account ~tx_rollup ?(batch = "batch") ~withdrawals b = Op.tx_rollup_submit_batch (B b) account tx_rollup batch @@ -2155,7 +2915,11 @@ module Withdraw = struct list of withdrawals as per [withdrawals]. Include the commitment in an operation and bake. *) Incremental.begin_construction b >>=? fun i -> - make_commitment_for_batch i Tx_rollup_level.root tx_rollup withdrawals + make_incomplete_commitment_for_batch + i + Tx_rollup_level.root + tx_rollup + withdrawals >>=? fun (commitment, context_hash_list) -> Op.tx_rollup_commit (I i) account tx_rollup commitment >>=? fun operation -> Incremental.add_operation i operation >>=? fun i -> @@ -2383,7 +3147,7 @@ module Withdraw = struct None (** [test_invalid_withdraw_no_commitment] checks that attempting to - withdraw from a level with no commited inbox raises an error. *) + withdraw from a level with no committed inbox raises an error. *) let test_invalid_withdraw_no_commitment () = context_init1_withdraw () >>=? fun (account1, tx_rollup, deposit_contract, withdraw_contract, b) -> @@ -2939,7 +3703,11 @@ module Withdraw = struct [withdrawal]. Include the commitment in an operation and bake it. *) Incremental.begin_construction b >>=? fun i -> - make_commitment_for_batch i Tx_rollup_level.root tx_rollup [(0, [withdraw])] + make_incomplete_commitment_for_batch + i + Tx_rollup_level.root + tx_rollup + [(0, [withdraw])] >>=? fun (commitment, context_hash_list) -> Op.tx_rollup_commit (I i) account1 tx_rollup commitment >>=? fun operation -> diff --git a/src/proto_alpha/lib_protocol/tx_rollup_commitment_repr.ml b/src/proto_alpha/lib_protocol/tx_rollup_commitment_repr.ml index 0470f49448..545c1d6316 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_commitment_repr.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_commitment_repr.ml @@ -152,10 +152,9 @@ let pp : Format.formatter -> t -> unit = Tx_rollup_inbox_repr.Merkle.pp_root t.inbox_merkle_root -(* FIXME/TORU: We need a test that checks that. *) let empty_l2_context_hash = Context_hash.of_b58check_exn - "CoVdWnWTqvYLikKj8koW6zpxCvK6FzZiD31YWEpD1UNAjWn7vhch" + "CoVu7Pqp1Gh3z33mink5T5Q2kAQKtnn3GHxVhyehdKZpQMBxFBGF" let initial_message_result_hash = hash_message_result diff --git a/src/proto_alpha/lib_protocol/tx_rollup_commitment_repr.mli b/src/proto_alpha/lib_protocol/tx_rollup_commitment_repr.mli index 446361ea4e..18a0ee53bb 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_commitment_repr.mli +++ b/src/proto_alpha/lib_protocol/tx_rollup_commitment_repr.mli @@ -54,7 +54,17 @@ val hash_message_result : message_result -> Message_result_hash.t val pp_message_result_hash : Format.formatter -> Message_result_hash.t -> unit (** [empty_l2_context_hash] is the context hash of the layer-2 context - just after its origination. *) + just after its origination. + + The empty layer2 context hash is the hash of the underlying Irmin tree. + One important note is: an empty tree *must* not be hashed when it's empty. + See https://github.com/mirage/irmin/issues/1304. + + Our solution is to write data in the tree to have a non-empty one. + We write the {!Tx_rollup_l2_context.Ticket_count} default value (i.e. 0) + and the {!Tx_rollup_l2_context.Address_count} as well in the tree. Then + we hash the resulting tree to create this constant. +*) val empty_l2_context_hash : Context_hash.t (** [initial_message_result_hash] is equal to diff --git a/src/proto_alpha/lib_protocol/tx_rollup_errors_repr.ml b/src/proto_alpha/lib_protocol/tx_rollup_errors_repr.ml index d5b50ab9ea..cd9d997672 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_errors_repr.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_errors_repr.ml @@ -53,7 +53,6 @@ type error += provided : Tx_rollup_commitment_repr.Commitment_hash.t option; expected : Tx_rollup_commitment_repr.Commitment_hash.t option; } - | Invalid_proof | Internal_error of string | Wrong_message_position of { level : Tx_rollup_level_repr.t; @@ -80,6 +79,9 @@ type error += | Ticket_payload_size_limit_exceeded of {payload_size : int; limit : int} | Deposit_wrong_ticketer of Tx_rollup_repr.t | Wrong_deposit_parameters + | Proof_failed_to_reject + | Proof_produced_rejected_state + | Proof_invalid_before of {agreed : Context_hash.t; provided : Context_hash.t} let () = let open Data_encoding in @@ -168,15 +170,6 @@ let () = empty (function No_uncommitted_inbox -> Some () | _ -> None) (fun () -> No_uncommitted_inbox) ; - (* Invalid_proof *) - register_error_kind - `Temporary - ~id:"tx_rollup_invalid_proof" - ~title:"The proof submitted for a rejection is invalid" - ~description:"The proof submitted for a rejection is invalid" - empty - (function Invalid_proof -> Some () | _ -> None) - (fun () -> Invalid_proof) ; (* Tx_rollup_message_size_exceed_limit *) register_error_kind `Temporary @@ -385,7 +378,7 @@ let () = (* Wrong_message_hash *) register_error_kind `Branch - ~id:"tx_rollup_wrong_message_hash" + ~id:"tx_rollup_wrong_message_path" ~title:"Wrong message path in rejection." ~description: "This rejection has sent a message and a path that does not fit the \ @@ -545,4 +538,40 @@ let () = tx_rollup) (obj1 (req "tx_rollup" Tx_rollup_repr.encoding)) (function Deposit_wrong_ticketer tx_rollup -> Some tx_rollup | _ -> None) - (fun tx_rollup -> Deposit_wrong_ticketer tx_rollup) + (fun tx_rollup -> Deposit_wrong_ticketer tx_rollup) ; + (* Proof_failed_to_reject *) + register_error_kind + `Temporary + ~id:"tx_rollup_proof_failed_to_reject" + ~title:"Proof failed to reject the commitment" + ~description: + "The proof verification failed and was unable to reject the commitment" + empty + (function Proof_failed_to_reject -> Some () | _ -> None) + (fun () -> Proof_failed_to_reject) ; + (* Proof_produced_rejected_state *) + register_error_kind + `Temporary + ~id:"tx_rollup_proof_produced_rejected_state" + ~title:"Proof produced the rejected state" + ~description: + "The proof submitted did not refute the rejected commitment. The proof \ + produced the same committed state" + empty + (function Proof_produced_rejected_state -> Some () | _ -> None) + (fun () -> Proof_produced_rejected_state) ; + (* Proof_invalid_before *) + register_error_kind + `Temporary + ~id:"tx_rollup_proof_invalid_before" + ~title:"Proof started from an invalid hash" + ~description: + "The proof started from a hash which is not the one agreed on (i.e. in \ + the previous commitment)" + (obj2 + (req "agreed" Context_hash.encoding) + (req "provided" Context_hash.encoding)) + (function + | Proof_invalid_before {agreed; provided} -> Some (agreed, provided) + | _ -> None) + (fun (agreed, provided) -> Proof_invalid_before {agreed; provided}) diff --git a/src/proto_alpha/lib_protocol/tx_rollup_l2_proof.ml b/src/proto_alpha/lib_protocol/tx_rollup_l2_proof.ml index 6b6316dd74..3810013613 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_l2_proof.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_l2_proof.ml @@ -24,6 +24,6 @@ (* *) (*****************************************************************************) -type t = bool +type t = Context.Proof.stream Context.Proof.t -let encoding = Data_encoding.bool +let encoding = Context.Proof_encoding.V2.Tree2.stream_proof_encoding diff --git a/src/proto_alpha/lib_protocol/tx_rollup_l2_proof.mli b/src/proto_alpha/lib_protocol/tx_rollup_l2_proof.mli index 8d928bdc70..6085db8214 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_l2_proof.mli +++ b/src/proto_alpha/lib_protocol/tx_rollup_l2_proof.mli @@ -24,7 +24,7 @@ (* *) (*****************************************************************************) -(** TODO/TORU: replace with actual proof type and add a docstring *) -type t = bool +(* The type of a Merkle proof for a L2 message *) +type t = Context.Proof.stream Context.Proof.t val encoding : t Data_encoding.t diff --git a/src/proto_alpha/lib_protocol/tx_rollup_l2_verifier.ml b/src/proto_alpha/lib_protocol/tx_rollup_l2_verifier.ml index c69169ab69..9cd2b87372 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_l2_verifier.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_l2_verifier.ml @@ -24,6 +24,113 @@ (* *) (*****************************************************************************) -let verify_proof message proof ~agreed:_ ~rejected:_ = - ignore message ; - Lwt.return proof +open Tx_rollup_errors_repr + +module Verifier_storage : + Tx_rollup_l2_storage_sig.STORAGE + with type t = Context.tree + and type 'a m = ('a, error) result Lwt.t = struct + type t = Context.tree + + type 'a m = ('a, error) result Lwt.t + + module Syntax = struct + let ( let* ) = ( >>=? ) + + let ( let+ ) = ( >|=? ) + + let return = return + + let fail e = Lwt.return (Error e) + + let catch (m : 'a m) k h = m >>= function Ok x -> k x | Error e -> h e + + let list_fold_left_m = List.fold_left_es + end + + let path k = [Bytes.to_string k] + + let get store key = Context.Tree.find store (path key) >>= return + + let set store key value = Context.Tree.add store (path key) value >>= return + + let remove store key = Context.Tree.remove store (path key) >>= return +end + +module Verifier_context = Tx_rollup_l2_context.Make (Verifier_storage) +module Verifier_apply = Tx_rollup_l2_apply.Make (Verifier_context) + +let hash_message_result after withdraw = + Alpha_context.Tx_rollup_commitment.hash_message_result + {context_hash = after; withdrawals_merkle_root = withdraw} + +(** [after_hash_when_proof_failed before] produces the + {!Alpha_context.Tx_rollup_message_result_hash} expected if a proof failed. + That is, the after hash is the same as [before] and it produced zero + withdrawals. *) +let after_hash_when_proof_failed before = + let open Alpha_context in + hash_message_result before Tx_rollup_withdraw.empty_withdrawals_merkle_root + +(** [compute_proof_after_hash ~max_proof_size agreed proof message] computes the + after hash expected while verifying [proof] on [message] starting from + [agreed]. + + Note that if the proof is incorrect this function fails and the commit + can not be rejected. *) +let compute_proof_after_hash ~max_proof_size parameters agreed proof message = + let proof_length = + Data_encoding.Binary.length Tx_rollup_l2_proof.encoding proof + in + let proof_is_too_long = Compare.Int.(proof_length > max_proof_size) in + let before = match proof.before with `Node x -> x | `Value x -> x in + let agreed_is_correct = Context_hash.(before = agreed) in + fail_unless + agreed_is_correct + (Proof_invalid_before {provided = before; agreed}) + >>=? fun () -> + Context.verify_stream_proof proof (fun tree -> + Verifier_apply.apply_message tree parameters message >>= function + | Ok (tree, (_, withdrawals)) -> Lwt.return (tree, withdrawals) + | Error _ -> Lwt.return (tree, [])) + >>= fun res -> + match res with + | (Ok _ | Error (`Stream_too_short _)) when proof_is_too_long -> + (* If the proof is larger than [proof_is_too_long] we care about 2 cases: + + - The proof verification succedeed but should not be considered valid + since it is larger than the size limit + - The proof verification failed because it was truncated but was + already larger than the size limit + + In those two cases, the expected after hash is + [after_hash_when_proof_failed] because the correct commitment is + "we were not able to apply this message, so after is the same + as before" + *) + return (after_hash_when_proof_failed agreed) + | Ok (tree, withdrawals) -> + (* The proof is small enough, we compare the computed hash with the + committed one *) + let tree_hash = Context.Tree.hash tree in + return + (hash_message_result + tree_hash + (Alpha_context.Tx_rollup_withdraw.merkelize_list withdrawals)) + | Error _ -> + (* Finally, the proof verification leads to an internal Irmin error *) + fail Proof_failed_to_reject + +let verify_proof parameters message proof + ~(agreed : Alpha_context.Tx_rollup_commitment.message_result) ~rejected + ~max_proof_size = + compute_proof_after_hash + parameters + agreed.context_hash + ~max_proof_size + proof + message + >>=? fun computed_result -> + if Alpha_context.Tx_rollup_message_result_hash.(computed_result <> rejected) + then return_unit + else fail Proof_produced_rejected_state diff --git a/src/proto_alpha/lib_protocol/tx_rollup_l2_verifier.mli b/src/proto_alpha/lib_protocol/tx_rollup_l2_verifier.mli index 6216c2598e..51ee28c2af 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_l2_verifier.mli +++ b/src/proto_alpha/lib_protocol/tx_rollup_l2_verifier.mli @@ -26,14 +26,30 @@ open Alpha_context -(** [verify_proof message proof ~agreed ~rejected] verifies a Merkle - proof for a L2 message, starting from the state [agreed]. If the - [proof] is correct, and the final Merkle hash is not equal to - [rejected], then [verify_proof] returns true. -*) +module Verifier_storage : sig + include + Tx_rollup_l2_storage_sig.STORAGE + with type t = Context.tree + and type 'a m = ('a, error) result Lwt.t +end + +module Verifier_context : sig + include Tx_rollup_l2_context_sig.CONTEXT with type t = Verifier_storage.t +end + +(** [verify_proof message proof ~agreed ~rejected ~max_proof_size] verifies + a Merkle proof for a L2 message, starting from the state [agreed]. If the + [proof] is correct, and the final Merkle hash is not equal to [rejected], + then [verify_proof] passes. + Note that if the proof is larger than [max_proof_size] and the final + Merkle hash is equal to [rejected], the needed proof for the rejected + commitment is too large, thus, [verify_proof] passes and the commitment + is rejected. *) val verify_proof : + Tx_rollup_l2_apply.parameters -> Tx_rollup_message.t -> Tx_rollup_l2_proof.t -> agreed:Tx_rollup_commitment.message_result -> rejected:Tx_rollup_message_result_hash.t -> - bool Lwt.t + max_proof_size:int -> + unit tzresult Lwt.t diff --git a/tests_python/tests_alpha/test_mockup.py b/tests_python/tests_alpha/test_mockup.py index 8797d05530..db48f64ba2 100644 --- a/tests_python/tests_alpha/test_mockup.py +++ b/tests_python/tests_alpha/test_mockup.py @@ -668,6 +668,7 @@ def _test_create_mockup_init_show_roundtrip( "tx_rollup_max_finalized_levels": 60_100, "tx_rollup_cost_per_byte_ema_factor": 321, "tx_rollup_max_ticket_payload_size": 10_240, + "tx_rollup_rejection_max_proof_size": 30_000, "sc_rollup_enable": False, "sc_rollup_origination_size": 6_314, "sc_rollup_challenge_window_in_blocks": 20_160, diff --git a/tezt/_regressions/rpc/alpha.client.mempool.out b/tezt/_regressions/rpc/alpha.client.mempool.out index 1506748cf5..277c5dc3cf 100644 --- a/tezt/_regressions/rpc/alpha.client.mempool.out +++ b/tezt/_regressions/rpc/alpha.client.mempool.out @@ -2287,7 +2287,699 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' "additionalProperties": false }, "proof": { - "type": "boolean" + "type": "object", + "properties": { + "version": { + "type": "integer", + "minimum": -32768, + "maximum": 32767 + }, + "before": { + "oneOf": [ + { + "title": "Value", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "value": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "value" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "Node", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "node": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "node" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + }, + "after": { + "oneOf": [ + { + "title": "Value", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "value": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "value" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "Node", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "node": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "node" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + }, + "state": { + "type": "array", + "items": { + "oneOf": [ + { + "title": "Inode", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "inode": { + "type": "object", + "properties": { + "length": { + "oneOf": [ + { + "title": "small", + "description": "An int64 which fits within a uint8", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "integer", + "minimum": 0, + "maximum": 255 + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "medium", + "description": "An int64 which fits within a uint16", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "integer", + "minimum": 0, + "maximum": 65535 + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "biggish", + "description": "An int64 which fits within a uint32", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "integer", + "minimum": -2147483648, + "maximum": 2147483647 + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "bigger", + "description": "An int64 which doesn't fit within a uint32", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "$ref": "#/definitions/int64" + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + }, + "proofs": { + "type": "array", + "items": [ + { + "oneOf": [ + { + "title": "none", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": {} + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "some", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + }, + { + "oneOf": [ + { + "title": "none", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": {} + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "some", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + } + ], + "additionalItems": false + } + }, + "required": [ + "proofs", + "length" + ], + "additionalProperties": false + } + }, + "required": [ + "inode" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "other_elts", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "other_elts": { + "oneOf": [ + { + "title": "Node", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "node": { + "type": "array", + "items": { + "type": "array", + "items": [ + { + "type": "string", + "pattern": "^([a-zA-Z0-9][a-zA-Z0-9])*$" + }, + { + "oneOf": [ + { + "title": "Value", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "value": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "value" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "Node", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "node": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "node" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + } + ], + "additionalItems": false + } + } + }, + "required": [ + "node" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "other_elts", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "other_elts": { + "oneOf": [ + { + "title": "Value", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "value": { + "oneOf": [ + { + "title": "short_bytes", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "string", + "pattern": "^([a-zA-Z0-9][a-zA-Z0-9])*$" + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "medium_bytes", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "string", + "pattern": "^([a-zA-Z0-9][a-zA-Z0-9])*$" + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "long_bytes", + "description": "This case is void. No data is accepted.", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": {} + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "unlimited_bytes", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "string", + "pattern": "^([a-zA-Z0-9][a-zA-Z0-9])*$" + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + } + }, + "required": [ + "value" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "Inode_extender", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "inode_extender": { + "type": "object", + "properties": { + "length": { + "oneOf": [ + { + "title": "small", + "description": "An int64 which fits within a uint8", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "integer", + "minimum": 0, + "maximum": 255 + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "medium", + "description": "An int64 which fits within a uint16", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "integer", + "minimum": 0, + "maximum": 65535 + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "biggish", + "description": "An int64 which fits within a uint32", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "integer", + "minimum": -2147483648, + "maximum": 2147483647 + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "bigger", + "description": "An int64 which doesn't fit within a uint32", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "$ref": "#/definitions/int64" + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + }, + "segment": { + "type": "string", + "pattern": "^([a-zA-Z0-9][a-zA-Z0-9])*$" + }, + "proof": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "proof", + "segment", + "length" + ], + "additionalProperties": false + } + }, + "required": [ + "inode_extender" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + } + }, + "required": [ + "other_elts" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + } + }, + "required": [ + "other_elts" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + } + } + }, + "required": [ + "state", + "after", + "before", + "version" + ], + "additionalProperties": false } }, "required": [ @@ -3994,7 +4686,7 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' { "name": "parameters", "layout": { - "name": "X_13", + "name": "X_138", "kind": "Ref" }, "data_kind": { @@ -4659,7 +5351,7 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' { "name": "commitment", "layout": { - "name": "X_11", + "name": "X_136", "kind": "Ref" }, "data_kind": { @@ -5074,11 +5766,11 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' { "name": "proof", "layout": { - "kind": "Bool" + "name": "X_135", + "kind": "Ref" }, "data_kind": { - "size": 1, - "kind": "Float" + "kind": "Dynamic" }, "kind": "named" } @@ -6281,7 +6973,7 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' }, { "description": { - "title": "X_13" + "title": "X_138" }, "encoding": { "fields": [ @@ -6664,7 +7356,7 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' }, { "description": { - "title": "X_11" + "title": "X_136" }, "encoding": { "fields": [ @@ -6701,7 +7393,7 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' { "name": "predecessor", "layout": { - "name": "X_12", + "name": "X_137", "kind": "Ref" }, "data_kind": { @@ -6725,7 +7417,7 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' }, { "description": { - "title": "X_12" + "title": "X_137" }, "encoding": { "tag_size": "Uint8", @@ -6795,38 +7487,7 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' }, { "description": { - "title": "X_10" - }, - "encoding": { - "fields": [ - { - "name": "context_hash", - "layout": { - "kind": "Bytes" - }, - "data_kind": { - "size": 32, - "kind": "Float" - }, - "kind": "named" - }, - { - "name": "withdrawals_merkle_root", - "layout": { - "kind": "Bytes" - }, - "data_kind": { - "size": 32, - "kind": "Float" - }, - "kind": "named" - } - ] - } - }, - { - "description": { - "title": "X_9" + "title": "X_135" }, "encoding": { "tag_size": "Uint8", @@ -6850,121 +7511,51 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' "kind": "named" }, { - "kind": "dyn", - "num_fields": 1, - "size": "Uint30" + "layout": { + "size": "Int16", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 2, + "kind": "Float" + } }, { - "name": "batch", "layout": { - "kind": "String" + "kind": "Bytes" }, + "kind": "anon", "data_kind": { - "kind": "Variable" - }, - "kind": "named" - } - ], - "name": "Batch" - }, - { - "tag": 1, - "fields": [ + "size": 32, + "kind": "Float" + } + }, { - "name": "Tag", "layout": { - "size": "Uint8", - "kind": "Int" + "kind": "Bytes" }, + "kind": "anon", "data_kind": { - "size": 1, + "size": 32, "kind": "Float" - }, - "kind": "named" + } }, { - "name": "deposit", "layout": { - "name": "X_7", + "name": "X_11", "kind": "Ref" }, + "kind": "anon", "data_kind": { "kind": "Dynamic" - }, - "kind": "named" + } } ], - "name": "Deposit" - } - ] - } - }, - { - "description": { - "title": "X_7" - }, - "encoding": { - "fields": [ - { - "name": "sender", - "layout": { - "name": "public_key_hash", - "kind": "Ref" - }, - "data_kind": { - "size": 21, - "kind": "Float" - }, - "kind": "named" - }, - { - "name": "destination", - "layout": { - "kind": "Bytes" - }, - "data_kind": { - "size": 20, - "kind": "Float" - }, - "kind": "named" - }, - { - "name": "ticket_hash", - "layout": { - "kind": "Bytes" - }, - "data_kind": { - "size": 32, - "kind": "Float" - }, - "kind": "named" + "name": "case 0" }, { - "name": "amount", - "layout": { - "name": "X_8", - "kind": "Ref" - }, - "data_kind": { - "kind": "Dynamic" - }, - "kind": "named" - } - ] - } - }, - { - "description": { - "title": "X_8" - }, - "encoding": { - "tag_size": "Uint8", - "kind": { - "kind": "Dynamic" - }, - "cases": [ - { - "tag": 0, + "tag": 1, "fields": [ { "name": "Tag", @@ -6980,41 +7571,1678 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' }, { "layout": { - "size": "Uint8", + "size": "Int16", "kind": "Int" }, "kind": "anon", "data_kind": { - "size": 1, + "size": 2, "kind": "Float" } - } - ], - "name": "case 0" - }, - { - "tag": 1, - "fields": [ + }, { - "name": "Tag", "layout": { - "size": "Uint8", - "kind": "Int" + "kind": "Bytes" }, + "kind": "anon", "data_kind": { - "size": 1, + "size": 32, "kind": "Float" - }, - "kind": "named" + } }, { "layout": { - "size": "Uint16", - "kind": "Int" + "kind": "Bytes" }, "kind": "anon", "data_kind": { - "size": 2, + "size": 32, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_11", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "kind": "Dynamic" + } + } + ], + "name": "case 1" + }, + { + "tag": 2, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Int16", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 2, + "kind": "Float" + } + }, + { + "layout": { + "kind": "Bytes" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + }, + { + "layout": { + "kind": "Bytes" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_11", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "kind": "Dynamic" + } + } + ], + "name": "case 2" + }, + { + "tag": 3, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Int16", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 2, + "kind": "Float" + } + }, + { + "layout": { + "kind": "Bytes" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + }, + { + "layout": { + "kind": "Bytes" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_11", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "kind": "Dynamic" + } + } + ], + "name": "case 3" + } + ] + } + }, + { + "description": { + "title": "X_134" + }, + "encoding": { + "tag_size": "Uint8", + "kind": { + "kind": "Dynamic" + }, + "cases": [ + { + "tag": 0, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 1, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_133", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 0, + "kind": "Float" + } + } + ], + "name": "case 0" + }, + { + "tag": 1, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Uint16", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 2, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_133", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 0, + "kind": "Float" + } + } + ], + "name": "case 1" + }, + { + "tag": 2, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Int32", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 4, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_133", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 0, + "kind": "Float" + } + } + ], + "name": "case 2" + }, + { + "tag": 3, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Int64", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 8, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_133", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 0, + "kind": "Float" + } + } + ], + "name": "case 3" + }, + { + "tag": 4, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 1, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_129", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + } + ], + "name": "case 4" + }, + { + "tag": 5, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Uint16", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 2, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_129", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + } + ], + "name": "case 5" + }, + { + "tag": 6, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Int32", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 4, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_129", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + } + ], + "name": "case 6" + }, + { + "tag": 7, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Int64", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 8, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_129", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + } + ], + "name": "case 7" + }, + { + "tag": 8, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 1, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_129", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + } + ], + "name": "case 8" + }, + { + "tag": 9, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Uint16", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 2, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_129", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + } + ], + "name": "case 9" + }, + { + "tag": 10, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Int32", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 4, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_129", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + } + ], + "name": "case 10" + }, + { + "tag": 11, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Int64", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 8, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_129", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + } + ], + "name": "case 11" + }, + { + "tag": 12, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 1, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_121", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 64, + "kind": "Float" + } + } + ], + "name": "case 12" + }, + { + "tag": 13, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Uint16", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 2, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_121", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 64, + "kind": "Float" + } + } + ], + "name": "case 13" + }, + { + "tag": 14, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Int32", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 4, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_121", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 64, + "kind": "Float" + } + } + ], + "name": "case 14" + }, + { + "tag": 15, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Int64", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 8, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_121", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 64, + "kind": "Float" + } + } + ], + "name": "case 15" + }, + { + "tag": 128, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "kind": "Zero_width" + }, + "kind": "anon", + "data_kind": { + "size": 0, + "kind": "Float" + } + } + ], + "name": "case 128" + }, + { + "tag": 129, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "layout": { + "name": "X_16", + "kind": "Ref" + }, + "kind": "Seq", + "length_limit": { + "kind": "exactly", + "exactly": 1 + } + }, + "kind": "anon", + "data_kind": { + "kind": "Variable" + } + } + ], + "name": "case 129" + }, + { + "tag": 130, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "layout": { + "name": "X_16", + "kind": "Ref" + }, + "kind": "Seq", + "length_limit": { + "kind": "exactly", + "exactly": 2 + } + }, + "kind": "anon", + "data_kind": { + "kind": "Variable" + } + } + ], + "name": "case 130" + }, + { + "tag": 131, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "kind": "dyn", + "num_fields": 1, + "size": "Uint30" + }, + { + "layout": { + "layout": { + "name": "X_16", + "kind": "Ref" + }, + "kind": "Seq" + }, + "kind": "anon", + "data_kind": { + "kind": "Variable" + } + } + ], + "name": "case 131" + }, + { + "tag": 192, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "kind": "dyn", + "num_fields": 1, + "size": "Uint8" + }, + { + "layout": { + "kind": "Bytes" + }, + "kind": "anon", + "data_kind": { + "kind": "Variable" + } + } + ], + "name": "case 192" + }, + { + "tag": 193, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "kind": "dyn", + "num_fields": 1, + "size": "Uint16" + }, + { + "layout": { + "kind": "Bytes" + }, + "kind": "anon", + "data_kind": { + "kind": "Variable" + } + } + ], + "name": "case 193" + }, + { + "tag": 195, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "kind": "dyn", + "num_fields": 1, + "size": "Uint30" + }, + { + "layout": { + "kind": "Bytes" + }, + "kind": "anon", + "data_kind": { + "kind": "Variable" + } + } + ], + "name": "case 195" + }, + { + "tag": 224, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 1, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_116", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "kind": "Dynamic" + } + }, + { + "layout": { + "kind": "Bytes" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + } + ], + "name": "case 224" + }, + { + "tag": 225, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Uint16", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 2, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_116", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "kind": "Dynamic" + } + }, + { + "layout": { + "kind": "Bytes" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + } + ], + "name": "case 225" + }, + { + "tag": 226, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Int32", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 4, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_116", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "kind": "Dynamic" + } + }, + { + "layout": { + "kind": "Bytes" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + } + ], + "name": "case 226" + }, + { + "tag": 227, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Int64", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 8, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_116", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "kind": "Dynamic" + } + }, + { + "layout": { + "kind": "Bytes" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + } + ], + "name": "case 227" + } + ] + } + }, + { + "description": { + "title": "X_133" + }, + "encoding": { + "fields": [] + } + }, + { + "description": { + "title": "X_129" + }, + "encoding": { + "fields": [ + { + "layout": { + "kind": "Bytes" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + } + ] + } + }, + { + "description": { + "title": "X_121" + }, + "encoding": { + "fields": [ + { + "layout": { + "kind": "Bytes" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + }, + { + "layout": { + "kind": "Bytes" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + } + ] + } + }, + { + "description": { + "title": "X_117" + }, + "encoding": { + "tag_size": "Uint8", + "kind": { + "size": 33, + "kind": "Float" + }, + "cases": [ + { + "tag": 0, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "name": "Context_hash", + "layout": { + "kind": "Bytes" + }, + "data_kind": { + "size": 32, + "kind": "Float" + }, + "kind": "named" + } + ], + "name": "case 0" + }, + { + "tag": 1, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "name": "Context_hash", + "layout": { + "kind": "Bytes" + }, + "data_kind": { + "size": 32, + "kind": "Float" + }, + "kind": "named" + } + ], + "name": "case 1" + } + ] + } + }, + { + "description": { + "title": "X_116" + }, + "encoding": { + "fields": [ + { + "kind": "dyn", + "num_fields": 1, + "size": "Uint8" + }, + { + "layout": { + "kind": "Bytes" + }, + "kind": "anon", + "data_kind": { + "kind": "Variable" + } + } + ] + } + }, + { + "description": { + "title": "X_11" + }, + "encoding": { + "fields": [ + { + "kind": "dyn", + "num_fields": 1, + "size": "Uint30" + }, + { + "layout": { + "layout": { + "name": "X_134", + "kind": "Ref" + }, + "kind": "Seq" + }, + "kind": "anon", + "data_kind": { + "kind": "Variable" + } + } + ] + } + }, + { + "description": { + "title": "X_16" + }, + "encoding": { + "fields": [ + { + "layout": { + "name": "X_116", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "kind": "Dynamic" + } + }, + { + "layout": { + "name": "X_117", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 33, + "kind": "Float" + } + } + ] + } + }, + { + "description": { + "title": "X_10" + }, + "encoding": { + "fields": [ + { + "name": "context_hash", + "layout": { + "kind": "Bytes" + }, + "data_kind": { + "size": 32, + "kind": "Float" + }, + "kind": "named" + }, + { + "name": "withdrawals_merkle_root", + "layout": { + "kind": "Bytes" + }, + "data_kind": { + "size": 32, + "kind": "Float" + }, + "kind": "named" + } + ] + } + }, + { + "description": { + "title": "X_9" + }, + "encoding": { + "tag_size": "Uint8", + "kind": { + "kind": "Dynamic" + }, + "cases": [ + { + "tag": 0, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "kind": "dyn", + "num_fields": 1, + "size": "Uint30" + }, + { + "name": "batch", + "layout": { + "kind": "String" + }, + "data_kind": { + "kind": "Variable" + }, + "kind": "named" + } + ], + "name": "Batch" + }, + { + "tag": 1, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "name": "deposit", + "layout": { + "name": "X_7", + "kind": "Ref" + }, + "data_kind": { + "kind": "Dynamic" + }, + "kind": "named" + } + ], + "name": "Deposit" + } + ] + } + }, + { + "description": { + "title": "X_7" + }, + "encoding": { + "fields": [ + { + "name": "sender", + "layout": { + "name": "public_key_hash", + "kind": "Ref" + }, + "data_kind": { + "size": 21, + "kind": "Float" + }, + "kind": "named" + }, + { + "name": "destination", + "layout": { + "kind": "Bytes" + }, + "data_kind": { + "size": 20, + "kind": "Float" + }, + "kind": "named" + }, + { + "name": "ticket_hash", + "layout": { + "kind": "Bytes" + }, + "data_kind": { + "size": 32, + "kind": "Float" + }, + "kind": "named" + }, + { + "name": "amount", + "layout": { + "name": "X_8", + "kind": "Ref" + }, + "data_kind": { + "kind": "Dynamic" + }, + "kind": "named" + } + ] + } + }, + { + "description": { + "title": "X_8" + }, + "encoding": { + "tag_size": "Uint8", + "kind": { + "kind": "Dynamic" + }, + "cases": [ + { + "tag": 0, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 1, + "kind": "Float" + } + } + ], + "name": "case 0" + }, + { + "tag": 1, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Uint16", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 2, "kind": "Float" } } @@ -9612,7 +11840,699 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' "additionalProperties": false }, "proof": { - "type": "boolean" + "type": "object", + "properties": { + "version": { + "type": "integer", + "minimum": -32768, + "maximum": 32767 + }, + "before": { + "oneOf": [ + { + "title": "Value", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "value": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "value" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "Node", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "node": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "node" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + }, + "after": { + "oneOf": [ + { + "title": "Value", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "value": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "value" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "Node", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "node": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "node" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + }, + "state": { + "type": "array", + "items": { + "oneOf": [ + { + "title": "Inode", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "inode": { + "type": "object", + "properties": { + "length": { + "oneOf": [ + { + "title": "small", + "description": "An int64 which fits within a uint8", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "integer", + "minimum": 0, + "maximum": 255 + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "medium", + "description": "An int64 which fits within a uint16", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "integer", + "minimum": 0, + "maximum": 65535 + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "biggish", + "description": "An int64 which fits within a uint32", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "integer", + "minimum": -2147483648, + "maximum": 2147483647 + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "bigger", + "description": "An int64 which doesn't fit within a uint32", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "$ref": "#/definitions/int64" + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + }, + "proofs": { + "type": "array", + "items": [ + { + "oneOf": [ + { + "title": "none", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": {} + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "some", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + }, + { + "oneOf": [ + { + "title": "none", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": {} + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "some", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + } + ], + "additionalItems": false + } + }, + "required": [ + "proofs", + "length" + ], + "additionalProperties": false + } + }, + "required": [ + "inode" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "other_elts", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "other_elts": { + "oneOf": [ + { + "title": "Node", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "node": { + "type": "array", + "items": { + "type": "array", + "items": [ + { + "type": "string", + "pattern": "^([a-zA-Z0-9][a-zA-Z0-9])*$" + }, + { + "oneOf": [ + { + "title": "Value", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "value": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "value" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "Node", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "node": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "node" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + } + ], + "additionalItems": false + } + } + }, + "required": [ + "node" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "other_elts", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "other_elts": { + "oneOf": [ + { + "title": "Value", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "value": { + "oneOf": [ + { + "title": "short_bytes", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "string", + "pattern": "^([a-zA-Z0-9][a-zA-Z0-9])*$" + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "medium_bytes", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "string", + "pattern": "^([a-zA-Z0-9][a-zA-Z0-9])*$" + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "long_bytes", + "description": "This case is void. No data is accepted.", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": {} + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "unlimited_bytes", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "string", + "pattern": "^([a-zA-Z0-9][a-zA-Z0-9])*$" + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + } + }, + "required": [ + "value" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "Inode_extender", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "inode_extender": { + "type": "object", + "properties": { + "length": { + "oneOf": [ + { + "title": "small", + "description": "An int64 which fits within a uint8", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "integer", + "minimum": 0, + "maximum": 255 + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "medium", + "description": "An int64 which fits within a uint16", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "integer", + "minimum": 0, + "maximum": 65535 + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "biggish", + "description": "An int64 which fits within a uint32", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "integer", + "minimum": -2147483648, + "maximum": 2147483647 + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "bigger", + "description": "An int64 which doesn't fit within a uint32", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "$ref": "#/definitions/int64" + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + }, + "segment": { + "type": "string", + "pattern": "^([a-zA-Z0-9][a-zA-Z0-9])*$" + }, + "proof": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "proof", + "segment", + "length" + ], + "additionalProperties": false + } + }, + "required": [ + "inode_extender" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + } + }, + "required": [ + "other_elts" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + } + }, + "required": [ + "other_elts" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + } + } + }, + "required": [ + "state", + "after", + "before", + "version" + ], + "additionalProperties": false } }, "required": [ diff --git a/tezt/_regressions/rpc/alpha.client.others.out b/tezt/_regressions/rpc/alpha.client.others.out index 79289afef7..a90a80af02 100644 --- a/tezt/_regressions/rpc/alpha.client.others.out +++ b/tezt/_regressions/rpc/alpha.client.others.out @@ -39,7 +39,8 @@ tezt/_regressions/rpc/alpha.client.others.out "tx_rollup_max_messages_per_inbox": 1010, "tx_rollup_max_finalized_levels": 60100, "tx_rollup_cost_per_byte_ema_factor": 120, - "tx_rollup_max_ticket_payload_size": 10240, "sc_rollup_enable": false, + "tx_rollup_max_ticket_payload_size": 10240, + "tx_rollup_rejection_max_proof_size": 30000, "sc_rollup_enable": false, "sc_rollup_origination_size": 6314, "sc_rollup_challenge_window_in_blocks": 20160 } diff --git a/tezt/_regressions/rpc/alpha.light.others.out b/tezt/_regressions/rpc/alpha.light.others.out index 58f933c90d..38b576ea4a 100644 --- a/tezt/_regressions/rpc/alpha.light.others.out +++ b/tezt/_regressions/rpc/alpha.light.others.out @@ -39,7 +39,8 @@ tezt/_regressions/rpc/alpha.light.others.out "tx_rollup_max_messages_per_inbox": 1010, "tx_rollup_max_finalized_levels": 60100, "tx_rollup_cost_per_byte_ema_factor": 120, - "tx_rollup_max_ticket_payload_size": 10240, "sc_rollup_enable": false, + "tx_rollup_max_ticket_payload_size": 10240, + "tx_rollup_rejection_max_proof_size": 30000, "sc_rollup_enable": false, "sc_rollup_origination_size": 6314, "sc_rollup_challenge_window_in_blocks": 20160 } protocol of light mode unspecified, using the node's protocol: ProtoGenesisGenesisGenesisGenesisGenesisGenesk612im diff --git a/tezt/_regressions/rpc/alpha.proxy.mempool.out b/tezt/_regressions/rpc/alpha.proxy.mempool.out index 7d8f2a4a00..4dbb7f9e17 100644 --- a/tezt/_regressions/rpc/alpha.proxy.mempool.out +++ b/tezt/_regressions/rpc/alpha.proxy.mempool.out @@ -2308,7 +2308,699 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' "additionalProperties": false }, "proof": { - "type": "boolean" + "type": "object", + "properties": { + "version": { + "type": "integer", + "minimum": -32768, + "maximum": 32767 + }, + "before": { + "oneOf": [ + { + "title": "Value", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "value": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "value" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "Node", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "node": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "node" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + }, + "after": { + "oneOf": [ + { + "title": "Value", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "value": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "value" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "Node", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "node": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "node" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + }, + "state": { + "type": "array", + "items": { + "oneOf": [ + { + "title": "Inode", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "inode": { + "type": "object", + "properties": { + "length": { + "oneOf": [ + { + "title": "small", + "description": "An int64 which fits within a uint8", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "integer", + "minimum": 0, + "maximum": 255 + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "medium", + "description": "An int64 which fits within a uint16", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "integer", + "minimum": 0, + "maximum": 65535 + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "biggish", + "description": "An int64 which fits within a uint32", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "integer", + "minimum": -2147483648, + "maximum": 2147483647 + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "bigger", + "description": "An int64 which doesn't fit within a uint32", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "$ref": "#/definitions/int64" + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + }, + "proofs": { + "type": "array", + "items": [ + { + "oneOf": [ + { + "title": "none", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": {} + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "some", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + }, + { + "oneOf": [ + { + "title": "none", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": {} + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "some", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + } + ], + "additionalItems": false + } + }, + "required": [ + "proofs", + "length" + ], + "additionalProperties": false + } + }, + "required": [ + "inode" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "other_elts", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "other_elts": { + "oneOf": [ + { + "title": "Node", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "node": { + "type": "array", + "items": { + "type": "array", + "items": [ + { + "type": "string", + "pattern": "^([a-zA-Z0-9][a-zA-Z0-9])*$" + }, + { + "oneOf": [ + { + "title": "Value", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "value": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "value" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "Node", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "node": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "node" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + } + ], + "additionalItems": false + } + } + }, + "required": [ + "node" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "other_elts", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "other_elts": { + "oneOf": [ + { + "title": "Value", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "value": { + "oneOf": [ + { + "title": "short_bytes", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "string", + "pattern": "^([a-zA-Z0-9][a-zA-Z0-9])*$" + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "medium_bytes", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "string", + "pattern": "^([a-zA-Z0-9][a-zA-Z0-9])*$" + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "long_bytes", + "description": "This case is void. No data is accepted.", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": {} + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "unlimited_bytes", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "string", + "pattern": "^([a-zA-Z0-9][a-zA-Z0-9])*$" + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + } + }, + "required": [ + "value" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "Inode_extender", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "inode_extender": { + "type": "object", + "properties": { + "length": { + "oneOf": [ + { + "title": "small", + "description": "An int64 which fits within a uint8", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "integer", + "minimum": 0, + "maximum": 255 + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "medium", + "description": "An int64 which fits within a uint16", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "integer", + "minimum": 0, + "maximum": 65535 + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "biggish", + "description": "An int64 which fits within a uint32", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "integer", + "minimum": -2147483648, + "maximum": 2147483647 + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "bigger", + "description": "An int64 which doesn't fit within a uint32", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "$ref": "#/definitions/int64" + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + }, + "segment": { + "type": "string", + "pattern": "^([a-zA-Z0-9][a-zA-Z0-9])*$" + }, + "proof": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "proof", + "segment", + "length" + ], + "additionalProperties": false + } + }, + "required": [ + "inode_extender" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + } + }, + "required": [ + "other_elts" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + } + }, + "required": [ + "other_elts" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + } + } + }, + "required": [ + "state", + "after", + "before", + "version" + ], + "additionalProperties": false } }, "required": [ @@ -4015,7 +4707,7 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' { "name": "parameters", "layout": { - "name": "X_13", + "name": "X_138", "kind": "Ref" }, "data_kind": { @@ -4680,7 +5372,7 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' { "name": "commitment", "layout": { - "name": "X_11", + "name": "X_136", "kind": "Ref" }, "data_kind": { @@ -5095,11 +5787,11 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' { "name": "proof", "layout": { - "kind": "Bool" + "name": "X_135", + "kind": "Ref" }, "data_kind": { - "size": 1, - "kind": "Float" + "kind": "Dynamic" }, "kind": "named" } @@ -6302,7 +6994,7 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' }, { "description": { - "title": "X_13" + "title": "X_138" }, "encoding": { "fields": [ @@ -6685,7 +7377,7 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' }, { "description": { - "title": "X_11" + "title": "X_136" }, "encoding": { "fields": [ @@ -6722,7 +7414,7 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' { "name": "predecessor", "layout": { - "name": "X_12", + "name": "X_137", "kind": "Ref" }, "data_kind": { @@ -6746,7 +7438,7 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' }, { "description": { - "title": "X_12" + "title": "X_137" }, "encoding": { "tag_size": "Uint8", @@ -6816,38 +7508,7 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' }, { "description": { - "title": "X_10" - }, - "encoding": { - "fields": [ - { - "name": "context_hash", - "layout": { - "kind": "Bytes" - }, - "data_kind": { - "size": 32, - "kind": "Float" - }, - "kind": "named" - }, - { - "name": "withdrawals_merkle_root", - "layout": { - "kind": "Bytes" - }, - "data_kind": { - "size": 32, - "kind": "Float" - }, - "kind": "named" - } - ] - } - }, - { - "description": { - "title": "X_9" + "title": "X_135" }, "encoding": { "tag_size": "Uint8", @@ -6871,121 +7532,51 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' "kind": "named" }, { - "kind": "dyn", - "num_fields": 1, - "size": "Uint30" + "layout": { + "size": "Int16", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 2, + "kind": "Float" + } }, { - "name": "batch", "layout": { - "kind": "String" + "kind": "Bytes" }, + "kind": "anon", "data_kind": { - "kind": "Variable" - }, - "kind": "named" - } - ], - "name": "Batch" - }, - { - "tag": 1, - "fields": [ + "size": 32, + "kind": "Float" + } + }, { - "name": "Tag", "layout": { - "size": "Uint8", - "kind": "Int" + "kind": "Bytes" }, + "kind": "anon", "data_kind": { - "size": 1, + "size": 32, "kind": "Float" - }, - "kind": "named" + } }, { - "name": "deposit", "layout": { - "name": "X_7", + "name": "X_11", "kind": "Ref" }, + "kind": "anon", "data_kind": { "kind": "Dynamic" - }, - "kind": "named" + } } ], - "name": "Deposit" - } - ] - } - }, - { - "description": { - "title": "X_7" - }, - "encoding": { - "fields": [ - { - "name": "sender", - "layout": { - "name": "public_key_hash", - "kind": "Ref" - }, - "data_kind": { - "size": 21, - "kind": "Float" - }, - "kind": "named" - }, - { - "name": "destination", - "layout": { - "kind": "Bytes" - }, - "data_kind": { - "size": 20, - "kind": "Float" - }, - "kind": "named" - }, - { - "name": "ticket_hash", - "layout": { - "kind": "Bytes" - }, - "data_kind": { - "size": 32, - "kind": "Float" - }, - "kind": "named" + "name": "case 0" }, { - "name": "amount", - "layout": { - "name": "X_8", - "kind": "Ref" - }, - "data_kind": { - "kind": "Dynamic" - }, - "kind": "named" - } - ] - } - }, - { - "description": { - "title": "X_8" - }, - "encoding": { - "tag_size": "Uint8", - "kind": { - "kind": "Dynamic" - }, - "cases": [ - { - "tag": 0, + "tag": 1, "fields": [ { "name": "Tag", @@ -7001,41 +7592,1678 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' }, { "layout": { - "size": "Uint8", + "size": "Int16", "kind": "Int" }, "kind": "anon", "data_kind": { - "size": 1, + "size": 2, "kind": "Float" } - } - ], - "name": "case 0" - }, - { - "tag": 1, - "fields": [ + }, { - "name": "Tag", "layout": { - "size": "Uint8", - "kind": "Int" + "kind": "Bytes" }, + "kind": "anon", "data_kind": { - "size": 1, + "size": 32, "kind": "Float" - }, - "kind": "named" + } }, { "layout": { - "size": "Uint16", - "kind": "Int" + "kind": "Bytes" }, "kind": "anon", "data_kind": { - "size": 2, + "size": 32, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_11", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "kind": "Dynamic" + } + } + ], + "name": "case 1" + }, + { + "tag": 2, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Int16", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 2, + "kind": "Float" + } + }, + { + "layout": { + "kind": "Bytes" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + }, + { + "layout": { + "kind": "Bytes" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_11", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "kind": "Dynamic" + } + } + ], + "name": "case 2" + }, + { + "tag": 3, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Int16", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 2, + "kind": "Float" + } + }, + { + "layout": { + "kind": "Bytes" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + }, + { + "layout": { + "kind": "Bytes" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_11", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "kind": "Dynamic" + } + } + ], + "name": "case 3" + } + ] + } + }, + { + "description": { + "title": "X_134" + }, + "encoding": { + "tag_size": "Uint8", + "kind": { + "kind": "Dynamic" + }, + "cases": [ + { + "tag": 0, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 1, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_133", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 0, + "kind": "Float" + } + } + ], + "name": "case 0" + }, + { + "tag": 1, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Uint16", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 2, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_133", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 0, + "kind": "Float" + } + } + ], + "name": "case 1" + }, + { + "tag": 2, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Int32", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 4, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_133", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 0, + "kind": "Float" + } + } + ], + "name": "case 2" + }, + { + "tag": 3, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Int64", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 8, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_133", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 0, + "kind": "Float" + } + } + ], + "name": "case 3" + }, + { + "tag": 4, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 1, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_129", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + } + ], + "name": "case 4" + }, + { + "tag": 5, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Uint16", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 2, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_129", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + } + ], + "name": "case 5" + }, + { + "tag": 6, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Int32", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 4, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_129", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + } + ], + "name": "case 6" + }, + { + "tag": 7, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Int64", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 8, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_129", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + } + ], + "name": "case 7" + }, + { + "tag": 8, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 1, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_129", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + } + ], + "name": "case 8" + }, + { + "tag": 9, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Uint16", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 2, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_129", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + } + ], + "name": "case 9" + }, + { + "tag": 10, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Int32", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 4, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_129", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + } + ], + "name": "case 10" + }, + { + "tag": 11, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Int64", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 8, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_129", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + } + ], + "name": "case 11" + }, + { + "tag": 12, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 1, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_121", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 64, + "kind": "Float" + } + } + ], + "name": "case 12" + }, + { + "tag": 13, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Uint16", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 2, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_121", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 64, + "kind": "Float" + } + } + ], + "name": "case 13" + }, + { + "tag": 14, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Int32", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 4, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_121", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 64, + "kind": "Float" + } + } + ], + "name": "case 14" + }, + { + "tag": 15, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Int64", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 8, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_121", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 64, + "kind": "Float" + } + } + ], + "name": "case 15" + }, + { + "tag": 128, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "kind": "Zero_width" + }, + "kind": "anon", + "data_kind": { + "size": 0, + "kind": "Float" + } + } + ], + "name": "case 128" + }, + { + "tag": 129, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "layout": { + "name": "X_16", + "kind": "Ref" + }, + "kind": "Seq", + "length_limit": { + "kind": "exactly", + "exactly": 1 + } + }, + "kind": "anon", + "data_kind": { + "kind": "Variable" + } + } + ], + "name": "case 129" + }, + { + "tag": 130, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "layout": { + "name": "X_16", + "kind": "Ref" + }, + "kind": "Seq", + "length_limit": { + "kind": "exactly", + "exactly": 2 + } + }, + "kind": "anon", + "data_kind": { + "kind": "Variable" + } + } + ], + "name": "case 130" + }, + { + "tag": 131, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "kind": "dyn", + "num_fields": 1, + "size": "Uint30" + }, + { + "layout": { + "layout": { + "name": "X_16", + "kind": "Ref" + }, + "kind": "Seq" + }, + "kind": "anon", + "data_kind": { + "kind": "Variable" + } + } + ], + "name": "case 131" + }, + { + "tag": 192, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "kind": "dyn", + "num_fields": 1, + "size": "Uint8" + }, + { + "layout": { + "kind": "Bytes" + }, + "kind": "anon", + "data_kind": { + "kind": "Variable" + } + } + ], + "name": "case 192" + }, + { + "tag": 193, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "kind": "dyn", + "num_fields": 1, + "size": "Uint16" + }, + { + "layout": { + "kind": "Bytes" + }, + "kind": "anon", + "data_kind": { + "kind": "Variable" + } + } + ], + "name": "case 193" + }, + { + "tag": 195, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "kind": "dyn", + "num_fields": 1, + "size": "Uint30" + }, + { + "layout": { + "kind": "Bytes" + }, + "kind": "anon", + "data_kind": { + "kind": "Variable" + } + } + ], + "name": "case 195" + }, + { + "tag": 224, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 1, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_116", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "kind": "Dynamic" + } + }, + { + "layout": { + "kind": "Bytes" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + } + ], + "name": "case 224" + }, + { + "tag": 225, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Uint16", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 2, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_116", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "kind": "Dynamic" + } + }, + { + "layout": { + "kind": "Bytes" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + } + ], + "name": "case 225" + }, + { + "tag": 226, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Int32", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 4, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_116", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "kind": "Dynamic" + } + }, + { + "layout": { + "kind": "Bytes" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + } + ], + "name": "case 226" + }, + { + "tag": 227, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Int64", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 8, + "kind": "Float" + } + }, + { + "layout": { + "name": "X_116", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "kind": "Dynamic" + } + }, + { + "layout": { + "kind": "Bytes" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + } + ], + "name": "case 227" + } + ] + } + }, + { + "description": { + "title": "X_133" + }, + "encoding": { + "fields": [] + } + }, + { + "description": { + "title": "X_129" + }, + "encoding": { + "fields": [ + { + "layout": { + "kind": "Bytes" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + } + ] + } + }, + { + "description": { + "title": "X_121" + }, + "encoding": { + "fields": [ + { + "layout": { + "kind": "Bytes" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + }, + { + "layout": { + "kind": "Bytes" + }, + "kind": "anon", + "data_kind": { + "size": 32, + "kind": "Float" + } + } + ] + } + }, + { + "description": { + "title": "X_117" + }, + "encoding": { + "tag_size": "Uint8", + "kind": { + "size": 33, + "kind": "Float" + }, + "cases": [ + { + "tag": 0, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "name": "Context_hash", + "layout": { + "kind": "Bytes" + }, + "data_kind": { + "size": 32, + "kind": "Float" + }, + "kind": "named" + } + ], + "name": "case 0" + }, + { + "tag": 1, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "name": "Context_hash", + "layout": { + "kind": "Bytes" + }, + "data_kind": { + "size": 32, + "kind": "Float" + }, + "kind": "named" + } + ], + "name": "case 1" + } + ] + } + }, + { + "description": { + "title": "X_116" + }, + "encoding": { + "fields": [ + { + "kind": "dyn", + "num_fields": 1, + "size": "Uint8" + }, + { + "layout": { + "kind": "Bytes" + }, + "kind": "anon", + "data_kind": { + "kind": "Variable" + } + } + ] + } + }, + { + "description": { + "title": "X_11" + }, + "encoding": { + "fields": [ + { + "kind": "dyn", + "num_fields": 1, + "size": "Uint30" + }, + { + "layout": { + "layout": { + "name": "X_134", + "kind": "Ref" + }, + "kind": "Seq" + }, + "kind": "anon", + "data_kind": { + "kind": "Variable" + } + } + ] + } + }, + { + "description": { + "title": "X_16" + }, + "encoding": { + "fields": [ + { + "layout": { + "name": "X_116", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "kind": "Dynamic" + } + }, + { + "layout": { + "name": "X_117", + "kind": "Ref" + }, + "kind": "anon", + "data_kind": { + "size": 33, + "kind": "Float" + } + } + ] + } + }, + { + "description": { + "title": "X_10" + }, + "encoding": { + "fields": [ + { + "name": "context_hash", + "layout": { + "kind": "Bytes" + }, + "data_kind": { + "size": 32, + "kind": "Float" + }, + "kind": "named" + }, + { + "name": "withdrawals_merkle_root", + "layout": { + "kind": "Bytes" + }, + "data_kind": { + "size": 32, + "kind": "Float" + }, + "kind": "named" + } + ] + } + }, + { + "description": { + "title": "X_9" + }, + "encoding": { + "tag_size": "Uint8", + "kind": { + "kind": "Dynamic" + }, + "cases": [ + { + "tag": 0, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "kind": "dyn", + "num_fields": 1, + "size": "Uint30" + }, + { + "name": "batch", + "layout": { + "kind": "String" + }, + "data_kind": { + "kind": "Variable" + }, + "kind": "named" + } + ], + "name": "Batch" + }, + { + "tag": 1, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "name": "deposit", + "layout": { + "name": "X_7", + "kind": "Ref" + }, + "data_kind": { + "kind": "Dynamic" + }, + "kind": "named" + } + ], + "name": "Deposit" + } + ] + } + }, + { + "description": { + "title": "X_7" + }, + "encoding": { + "fields": [ + { + "name": "sender", + "layout": { + "name": "public_key_hash", + "kind": "Ref" + }, + "data_kind": { + "size": 21, + "kind": "Float" + }, + "kind": "named" + }, + { + "name": "destination", + "layout": { + "kind": "Bytes" + }, + "data_kind": { + "size": 20, + "kind": "Float" + }, + "kind": "named" + }, + { + "name": "ticket_hash", + "layout": { + "kind": "Bytes" + }, + "data_kind": { + "size": 32, + "kind": "Float" + }, + "kind": "named" + }, + { + "name": "amount", + "layout": { + "name": "X_8", + "kind": "Ref" + }, + "data_kind": { + "kind": "Dynamic" + }, + "kind": "named" + } + ] + } + }, + { + "description": { + "title": "X_8" + }, + "encoding": { + "tag_size": "Uint8", + "kind": { + "kind": "Dynamic" + }, + "cases": [ + { + "tag": 0, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 1, + "kind": "Float" + } + } + ], + "name": "case 0" + }, + { + "tag": 1, + "fields": [ + { + "name": "Tag", + "layout": { + "size": "Uint8", + "kind": "Int" + }, + "data_kind": { + "size": 1, + "kind": "Float" + }, + "kind": "named" + }, + { + "layout": { + "size": "Uint16", + "kind": "Int" + }, + "kind": "anon", + "data_kind": { + "size": 2, "kind": "Float" } } @@ -9633,7 +11861,699 @@ curl -s 'http://localhost:[PORT]/describe/chains/main/mempool?recurse=yes' "additionalProperties": false }, "proof": { - "type": "boolean" + "type": "object", + "properties": { + "version": { + "type": "integer", + "minimum": -32768, + "maximum": 32767 + }, + "before": { + "oneOf": [ + { + "title": "Value", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "value": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "value" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "Node", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "node": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "node" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + }, + "after": { + "oneOf": [ + { + "title": "Value", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "value": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "value" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "Node", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "node": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "node" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + }, + "state": { + "type": "array", + "items": { + "oneOf": [ + { + "title": "Inode", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "inode": { + "type": "object", + "properties": { + "length": { + "oneOf": [ + { + "title": "small", + "description": "An int64 which fits within a uint8", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "integer", + "minimum": 0, + "maximum": 255 + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "medium", + "description": "An int64 which fits within a uint16", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "integer", + "minimum": 0, + "maximum": 65535 + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "biggish", + "description": "An int64 which fits within a uint32", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "integer", + "minimum": -2147483648, + "maximum": 2147483647 + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "bigger", + "description": "An int64 which doesn't fit within a uint32", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "$ref": "#/definitions/int64" + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + }, + "proofs": { + "type": "array", + "items": [ + { + "oneOf": [ + { + "title": "none", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": {} + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "some", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + }, + { + "oneOf": [ + { + "title": "none", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": {} + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "some", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + } + ], + "additionalItems": false + } + }, + "required": [ + "proofs", + "length" + ], + "additionalProperties": false + } + }, + "required": [ + "inode" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "other_elts", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "other_elts": { + "oneOf": [ + { + "title": "Node", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "node": { + "type": "array", + "items": { + "type": "array", + "items": [ + { + "type": "string", + "pattern": "^([a-zA-Z0-9][a-zA-Z0-9])*$" + }, + { + "oneOf": [ + { + "title": "Value", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "value": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "value" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "Node", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "node": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "node" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + } + ], + "additionalItems": false + } + } + }, + "required": [ + "node" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "other_elts", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "other_elts": { + "oneOf": [ + { + "title": "Value", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "value": { + "oneOf": [ + { + "title": "short_bytes", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "string", + "pattern": "^([a-zA-Z0-9][a-zA-Z0-9])*$" + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "medium_bytes", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "string", + "pattern": "^([a-zA-Z0-9][a-zA-Z0-9])*$" + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "long_bytes", + "description": "This case is void. No data is accepted.", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": {} + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "unlimited_bytes", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "string", + "pattern": "^([a-zA-Z0-9][a-zA-Z0-9])*$" + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + } + }, + "required": [ + "value" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "Inode_extender", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "object", + "properties": { + "inode_extender": { + "type": "object", + "properties": { + "length": { + "oneOf": [ + { + "title": "small", + "description": "An int64 which fits within a uint8", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "integer", + "minimum": 0, + "maximum": 255 + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "medium", + "description": "An int64 which fits within a uint16", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "integer", + "minimum": 0, + "maximum": 65535 + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "biggish", + "description": "An int64 which fits within a uint32", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "type": "integer", + "minimum": -2147483648, + "maximum": 2147483647 + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + }, + { + "title": "bigger", + "description": "An int64 which doesn't fit within a uint32", + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/unistring" + }, + "value": { + "$ref": "#/definitions/int64" + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + }, + "segment": { + "type": "string", + "pattern": "^([a-zA-Z0-9][a-zA-Z0-9])*$" + }, + "proof": { + "$ref": "#/definitions/Context_hash" + } + }, + "required": [ + "proof", + "segment", + "length" + ], + "additionalProperties": false + } + }, + "required": [ + "inode_extender" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + } + }, + "required": [ + "other_elts" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + } + }, + "required": [ + "other_elts" + ], + "additionalProperties": false + } + }, + "required": [ + "value", + "kind" + ], + "additionalProperties": false + } + ] + } + } + }, + "required": [ + "state", + "after", + "before", + "version" + ], + "additionalProperties": false } }, "required": [ diff --git a/tezt/_regressions/rpc/alpha.proxy.others.out b/tezt/_regressions/rpc/alpha.proxy.others.out index d581518fc2..881eeb26ab 100644 --- a/tezt/_regressions/rpc/alpha.proxy.others.out +++ b/tezt/_regressions/rpc/alpha.proxy.others.out @@ -39,7 +39,8 @@ tezt/_regressions/rpc/alpha.proxy.others.out "tx_rollup_max_messages_per_inbox": 1010, "tx_rollup_max_finalized_levels": 60100, "tx_rollup_cost_per_byte_ema_factor": 120, - "tx_rollup_max_ticket_payload_size": 10240, "sc_rollup_enable": false, + "tx_rollup_max_ticket_payload_size": 10240, + "tx_rollup_rejection_max_proof_size": 30000, "sc_rollup_enable": false, "sc_rollup_origination_size": 6314, "sc_rollup_challenge_window_in_blocks": 20160 } protocol of proxy unspecified, using the node's protocol: ProtoGenesisGenesisGenesisGenesisGenesisGenesk612im diff --git a/tezt/_regressions/rpc/alpha.proxy_server.others.out b/tezt/_regressions/rpc/alpha.proxy_server.others.out index 3434898536..588848ce1f 100644 --- a/tezt/_regressions/rpc/alpha.proxy_server.others.out +++ b/tezt/_regressions/rpc/alpha.proxy_server.others.out @@ -39,7 +39,8 @@ tezt/_regressions/rpc/alpha.proxy_server.others.out "tx_rollup_max_messages_per_inbox": 1010, "tx_rollup_max_finalized_levels": 60100, "tx_rollup_cost_per_byte_ema_factor": 120, - "tx_rollup_max_ticket_payload_size": 10240, "sc_rollup_enable": false, + "tx_rollup_max_ticket_payload_size": 10240, + "tx_rollup_rejection_max_proof_size": 30000, "sc_rollup_enable": false, "sc_rollup_origination_size": 6314, "sc_rollup_challenge_window_in_blocks": 20160 } diff --git a/tezt/lib_tezos/client.ml b/tezt/lib_tezos/client.ml index c7ac0b7bfa..f9c0b62f60 100644 --- a/tezt/lib_tezos/client.ml +++ b/tezt/lib_tezos/client.ml @@ -1327,8 +1327,7 @@ module Tx_rollup = struct @ ["at"; "level"; string_of_int level] @ ["message"; message] @ ["at"; "position"; string_of_int position] - @ ["and"; "path"; path] - @ ["with"; "proof"; string_of_bool proof] + @ ["and"; "path"; path] @ ["with"; "proof"; proof] @ ["with"; "agreed"; "context"; "hash"; context_hash] @ ["and"; "withdraw"; "list"; withdraw_list_hash] @ ["to"; rollup] @ ["from"; src] diff --git a/tezt/lib_tezos/client.mli b/tezt/lib_tezos/client.mli index 27004b61cf..ca21797e0c 100644 --- a/tezt/lib_tezos/client.mli +++ b/tezt/lib_tezos/client.mli @@ -971,7 +971,7 @@ module Tx_rollup : sig message:string -> position:int -> path:string -> - proof:bool -> + proof:string -> context_hash:string -> withdraw_list_hash:string -> rollup:string -> diff --git a/tezt/lib_tezos/constant.ml b/tezt/lib_tezos/constant.ml index 5a55714a0c..4b7c4dd145 100644 --- a/tezt/lib_tezos/constant.ml +++ b/tezt/lib_tezos/constant.ml @@ -117,10 +117,23 @@ let max_op_ttl = 120 let tx_rollup_l2_address = "tz4MSfZsn6kMDczShy8PMeB628TNukn9hi2K" let tx_rollup_empty_l2_context = - "CoVdWnWTqvYLikKj8koW6zpxCvK6FzZiD31YWEpD1UNAjWn7vhch" + "CoVu7Pqp1Gh3z33mink5T5Q2kAQKtnn3GHxVhyehdKZpQMBxFBGF" let tx_rollup_empty_withdraw_list = "txw1qi5zqv2cizWX3XYSGtj5aDpdft5V4er7SK44TNpW5usEi5im7" let tx_rollup_initial_message_result = "txmr2RQL6pMQMkjZwL28kEeyAGpmaorNx2nT6G9JpQj81ER4XqDpD7" + +(** A valid rejection proof for the initial layer2 state. *) +let tx_rollup_proof_initial_state = + {|{ "version": 3, + "before": + { "kind": "Node", + "value": + { "node": "CoVu7Pqp1Gh3z33mink5T5Q2kAQKtnn3GHxVhyehdKZpQMBxFBGF" } }, + "after": + { "kind": "Node", + "value": + { "node": "CoVu7Pqp1Gh3z33mink5T5Q2kAQKtnn3GHxVhyehdKZpQMBxFBGF" } }, + "state": [] }|} diff --git a/tezt/lib_tezos/operation.ml b/tezt/lib_tezos/operation.ml index bda00c8fcd..0c87d35e99 100644 --- a/tezt/lib_tezos/operation.ml +++ b/tezt/lib_tezos/operation.ml @@ -45,7 +45,7 @@ type manager_op_kind = | Reveal of string (* public key *) | Origination of {code : micheline; storage : micheline; balance : int} | Rejection of { - proof : bool; + proof : string; tx_rollup : string; level : int; message : [`Batch of string]; @@ -222,7 +222,7 @@ let manager_op_content_to_json_string previous_message_result; } -> let rollup = `String tx_rollup in - let proof = `Bool proof in + let proof = Ezjsonm.value_from_string proof in let level = `Float (float_of_int level) in let message = match message with `Batch str -> `O [("batch", `String str)] diff --git a/tezt/lib_tezos/operation.mli b/tezt/lib_tezos/operation.mli index 6373ddb7d7..8b9c5f591c 100644 --- a/tezt/lib_tezos/operation.mli +++ b/tezt/lib_tezos/operation.mli @@ -104,7 +104,7 @@ val mk_rejection : ?gas_limit:int -> ?storage_limit:int -> tx_rollup:string -> - proof:bool -> + proof:string -> level:int -> message:[`Batch of string] -> message_position:int -> @@ -375,7 +375,7 @@ val inject_rejection : ?gas_limit:int -> ?storage_limit:int -> tx_rollup:string -> - proof:bool -> + proof:string -> level:int -> message:[`Batch of string] -> message_position:int -> diff --git a/tezt/tests/tx_rollup.ml b/tezt/tests/tx_rollup.ml index 9716060f33..f5e03d17eb 100644 --- a/tezt/tests/tx_rollup.ml +++ b/tezt/tests/tx_rollup.ml @@ -869,7 +869,7 @@ let test_rollup_last_commitment_is_rejected = ~message ~position:0 ~path:(path |> JSON.encode) - ~proof:true + ~proof:Constant.tx_rollup_proof_initial_state ~context_hash:Constant.tx_rollup_empty_l2_context ~withdraw_list_hash:Constant.tx_rollup_empty_withdraw_list state @@ -915,11 +915,23 @@ let test_rollup_wrong_rejection = client in let message_path = List.map (fun x -> JSON.as_string x) (JSON.as_list path) in + (* The proof is invalid, as the submitted batch is stupid, the after + hash should be the same as before. *) let* (`OpHash _op) = Operation.inject_rejection ~source:Constant.bootstrap1 ~tx_rollup:state.rollup - ~proof:false + ~proof: + {|{ "version": 3, + "before": + { "kind": "Node", + "value": + { "node": "CoVu7Pqp1Gh3z33mink5T5Q2kAQKtnn3GHxVhyehdKZpQMBxFBGF" } }, + "after": + { "kind": "Node", + "value": + { "node": "CoUeJrcPBj3T3iJL3PY4jZHnmZa5rRZ87VQPdSBNBcwZRMWJGh9j" } }, + "state": [] }|} ~level:0 ~message ~message_position:0 @@ -944,7 +956,7 @@ let test_rollup_wrong_rejection = let error_id = JSON.(operation_result |-> "errors" |=> 0 |-> "id" |> as_string) in - Check.(error_id = "proto.alpha.tx_rollup_invalid_proof") + Check.(error_id = "proto.alpha.tx_rollup_proof_failed_to_reject") Check.string ~error_msg:"Expected error id: %R. Got %L" ; match state.unfinalized_commitments with From e42ef652e1839e3e277b2ed0e2d41ebeb9d2765b Mon Sep 17 00:00:00 2001 From: Valentin Chaboche <valentin.chaboche@nomadic-labs.com> Date: Fri, 18 Mar 2022 16:01:28 +0100 Subject: [PATCH 093/100] Doc: temporary: make warnings don't make the job fail --- docs/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/Makefile b/docs/Makefile index 4308abfbe3..0d0c9d0fcf 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -1,5 +1,7 @@ # You can set these variables from the command line. -SPHINXOPTS = -j auto -aE -n -W --keep-going +# FIXME: https://gitlab.com/tezos/tezos/-/issues/2680 +# The [-W] flag is temporary disabled +SPHINXOPTS = -j auto -aE -n --keep-going SPHINXBUILD = poetry run sphinx-build SPHINXPROJ = Tezos SOURCEDIR = . From 7c4727ddda1caf98218db1aef0325d806d6fa577 Mon Sep 17 00:00:00 2001 From: David Turner <novalis@novalis.org> Date: Mon, 28 Feb 2022 15:43:23 -0500 Subject: [PATCH 094/100] Proto: remove unused function --- src/lib_protocol_environment/environment_V5.ml | 2 -- src/lib_protocol_environment/sigs/v5/context.mli | 3 --- 2 files changed, 5 deletions(-) diff --git a/src/lib_protocol_environment/environment_V5.ml b/src/lib_protocol_environment/environment_V5.ml index 900aa7c69e..14490fb5ef 100644 --- a/src/lib_protocol_environment/environment_V5.ml +++ b/src/lib_protocol_environment/environment_V5.ml @@ -1091,8 +1091,6 @@ struct module Proof_encoding = Tezos_context_helpers.Context.Proof_encoding - let register_resolver = Base58.register_resolver - let complete ctxt s = Base58.complete ctxt s end diff --git a/src/lib_protocol_environment/sigs/v5/context.mli b/src/lib_protocol_environment/sigs/v5/context.mli index 01d6844fb9..4d7ccd466b 100644 --- a/src/lib_protocol_environment/sigs/v5/context.mli +++ b/src/lib_protocol_environment/sigs/v5/context.mli @@ -493,9 +493,6 @@ module Proof_encoding : sig end end -val register_resolver : - 'a Base58.encoding -> (t -> string -> 'a list Lwt.t) -> unit - val complete : t -> string -> string list Lwt.t (** Get the hash version used for the context *) From 2c9a6cc7d8a7659f0c0e7f22d4222d284b068fe5 Mon Sep 17 00:00:00 2001 From: Valentin Chaboche <valentin.chaboche@nomadic-labs.com> Date: Mon, 21 Mar 2022 12:30:41 +0100 Subject: [PATCH 095/100] Tx_rollup,Proto: fix expected field for [Counter_mismatch] --- .../lib_protocol/test/unit/test_tx_rollup_l2_apply.ml | 2 +- src/proto_alpha/lib_protocol/tx_rollup_l2_apply.ml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml b/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml index afa0144e7f..9e603406bc 100644 --- a/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml +++ b/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml @@ -1383,7 +1383,7 @@ let test_invalid_counter () = expect_error_status ~msg:"the invalid counter must be detected" (Tx_rollup_l2_apply.Counter_mismatch - {account = addr1; expected = 0L; provided = counter}) + {account = addr1; expected = 1L; provided = counter}) status return_unit in diff --git a/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.ml b/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.ml index 802df653f7..c8e1207cf1 100644 --- a/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.ml +++ b/src/proto_alpha/lib_protocol/tx_rollup_l2_apply.ml @@ -59,8 +59,8 @@ let () = counter" (obj3 (req "account" Tx_rollup_l2_address.encoding) - (req "requested" int64) - (req "actual" int64)) + (req "expected" int64) + (req "provided" int64)) (function | Counter_mismatch {account; expected; provided} -> Some (account, expected, provided) @@ -683,7 +683,7 @@ module Make (Context : CONTEXT) = struct (Counter_mismatch { account = Tx_rollup_l2_address.of_bls_pk metadata.public_key; - expected = metadata.counter; + expected = Int64.succ metadata.counter; provided = counter; }) From d23b86bb225625126141ee8906c7a006ee83e5da Mon Sep 17 00:00:00 2001 From: Danny Willems <be.danny.willems@gmail.com> Date: Tue, 22 Feb 2022 14:42:23 +0100 Subject: [PATCH 096/100] Env v5: use Bls12_381.MinSig instead of Bls12_381.MinPk --- src/lib_protocol_environment/environment_V5.ml | 6 +++--- src/lib_protocol_environment/environment_V5.mli | 4 ++-- src/proto_alpha/lib_benchmark/michelson_samplers.ml | 2 +- .../lib_protocol/test/helpers/tx_rollup_l2_helpers.ml | 4 ++-- .../test/integration/operations/test_tx_rollup.ml | 2 +- .../lib_protocol/test/pbt/test_tx_rollup_l2_encoding.ml | 4 ++-- .../lib_protocol/test/unit/test_tx_rollup_l2_apply.ml | 2 +- tezt/tests/tx_rollup_node.ml | 8 ++++---- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/lib_protocol_environment/environment_V5.ml b/src/lib_protocol_environment/environment_V5.ml index 14490fb5ef..cc4d1f2235 100644 --- a/src/lib_protocol_environment/environment_V5.ml +++ b/src/lib_protocol_environment/environment_V5.ml @@ -96,8 +96,8 @@ module type V5 = sig and type Timelock.chest_key = Timelock.chest_key and type Timelock.opening_result = Timelock.opening_result and module Sapling = Tezos_sapling.Core.Validator - and type Bls_signature.pk = Bls12_381.Signature.MinPk.pk - and type Bls_signature.signature = Bls12_381.Signature.MinPk.signature + and type Bls_signature.pk = Bls12_381.Signature.MinSig.pk + and type Bls_signature.signature = Bls12_381.Signature.MinSig.signature and type ('a, 'b) Either.t = ('a, 'b) Stdlib.Either.t type error += Ecoproto_error of Error_monad.error @@ -269,7 +269,7 @@ struct end module Bls_signature = struct - include Bls12_381.Signature.MinPk + include Bls12_381.Signature.MinSig let verify = Aug.verify diff --git a/src/lib_protocol_environment/environment_V5.mli b/src/lib_protocol_environment/environment_V5.mli index a744f565a2..6edfcab12e 100644 --- a/src/lib_protocol_environment/environment_V5.mli +++ b/src/lib_protocol_environment/environment_V5.mli @@ -97,8 +97,8 @@ module type V5 = sig and type Timelock.chest_key = Timelock.chest_key and type Timelock.opening_result = Timelock.opening_result and module Sapling = Tezos_sapling.Core.Validator - and type Bls_signature.pk = Bls12_381.Signature.MinPk.pk - and type Bls_signature.signature = Bls12_381.Signature.MinPk.signature + and type Bls_signature.pk = Bls12_381.Signature.MinSig.pk + and type Bls_signature.signature = Bls12_381.Signature.MinSig.signature and type ('a, 'b) Either.t = ('a, 'b) Stdlib.Either.t (** An [Ecoproto_error e] is a shell error that carry a protocol error. diff --git a/src/proto_alpha/lib_benchmark/michelson_samplers.ml b/src/proto_alpha/lib_benchmark/michelson_samplers.ml index ad311af130..e1cbd69148 100644 --- a/src/proto_alpha/lib_benchmark/michelson_samplers.ml +++ b/src/proto_alpha/lib_benchmark/michelson_samplers.ml @@ -529,7 +529,7 @@ end) let secret_key = Bls12_381.Signature.generate_sk seed in Tx_rollup_l2_address.Indexable.value (Tx_rollup_l2_address.of_bls_pk - @@ Bls12_381.Signature.MinPk.derive_pk secret_key) + @@ Bls12_381.Signature.MinSig.derive_pk secret_key) let chain_id rng_state = let string = Base_samplers.uniform_string ~nbytes:4 rng_state in diff --git a/src/proto_alpha/lib_protocol/test/helpers/tx_rollup_l2_helpers.ml b/src/proto_alpha/lib_protocol/test/helpers/tx_rollup_l2_helpers.ml index 611a99257e..83fb215e36 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/tx_rollup_l2_helpers.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/tx_rollup_l2_helpers.ml @@ -101,7 +101,7 @@ let gen_l2_address () = Bytes.init 32 (fun _ -> char_of_int @@ Random.State.int rng_state 255) in let secret_key = Bls12_381.Signature.generate_sk seed in - let public_key = Bls12_381.Signature.MinPk.derive_pk secret_key in + let public_key = Bls12_381.Signature.MinSig.derive_pk secret_key in (secret_key, public_key, Tx_rollup_l2_address.of_bls_pk public_key) (** [make_unit_ticket_key ctxt ticketer tx_rollup] computes the key hash of @@ -168,7 +168,7 @@ let sign_transaction : transaction in - List.map (fun sk -> Bls12_381.Signature.MinPk.Aug.sign sk buf) sks + List.map (fun sk -> Bls12_381.Signature.MinSig.Aug.sign sk buf) sks type Environment.Error_monad.error += Test_error of string diff --git a/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml b/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml index 661356b058..00879549eb 100644 --- a/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml +++ b/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml @@ -252,7 +252,7 @@ let gen_l2_account () = Bytes.init 32 (fun _ -> char_of_int @@ Random.State.int rng_state 255) in let secret_key = Bls12_381.Signature.generate_sk seed in - let public_key = Bls12_381.Signature.MinPk.derive_pk secret_key in + let public_key = Bls12_381.Signature.MinSig.derive_pk secret_key in (secret_key, public_key, Tx_rollup_l2_address.of_bls_pk public_key) (** [make_ticket_key ty contents ticketer tx_rollup] computes the ticket hash diff --git a/src/proto_alpha/lib_protocol/test/pbt/test_tx_rollup_l2_encoding.ml b/src/proto_alpha/lib_protocol/test/pbt/test_tx_rollup_l2_encoding.ml index 82b32a3461..b3bffaa379 100644 --- a/src/proto_alpha/lib_protocol/test/pbt/test_tx_rollup_l2_encoding.ml +++ b/src/proto_alpha/lib_protocol/test/pbt/test_tx_rollup_l2_encoding.ml @@ -47,7 +47,7 @@ let bls_pk_gen = let open QCheck2.Gen in let+ seed = seed_gen in let secret_key = Bls12_381.Signature.generate_sk seed in - Bls12_381.Signature.MinPk.derive_pk secret_key + Bls12_381.Signature.MinSig.derive_pk secret_key let l2_address_gen = let open QCheck2.Gen in @@ -152,7 +152,7 @@ let v1_batch = valid bytes since the signature encoding is "safe" and accept only valid signatures. However, it should not impact the tests here as the bytes length stays the same. *) - let bytes = Bls12_381.G2.(to_compressed_bytes (random ())) in + let bytes = Bls12_381.G1.(to_compressed_bytes (random ())) in let aggregated_signature = Protocol.Environment.Bls_signature.unsafe_signature_of_bytes bytes in diff --git a/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml b/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml index 9e603406bc..b2c19ba291 100644 --- a/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml +++ b/src/proto_alpha/lib_protocol/test/unit/test_tx_rollup_l2_apply.ml @@ -84,7 +84,7 @@ let expect_error_status ~msg error status cont = let aggregate_signature_exn : signature list -> signature = fun signatures -> - match Bls12_381.Signature.MinPk.aggregate_signature_opt signatures with + match Bls12_381.Signature.MinSig.aggregate_signature_opt signatures with | Some res -> res | None -> raise (Invalid_argument "aggregate_signature_exn") diff --git a/tezt/tests/tx_rollup_node.ml b/tezt/tests/tx_rollup_node.ml index d837aaf557..767b4672e1 100644 --- a/tezt/tests/tx_rollup_node.ml +++ b/tezt/tests/tx_rollup_node.ml @@ -317,9 +317,9 @@ let generate_bls_addr ?alias:_ _client = Bytes.init 32 (fun _ -> char_of_int @@ Random.State.int rng_state 255) in let sk = Bls12_381.Signature.generate_sk seed in - let pk = Bls12_381.Signature.MinPk.derive_pk sk in + let pk = Bls12_381.Signature.MinSig.derive_pk sk in let pkh = - Bls_public_key_hash.hash_bytes [Bls12_381.Signature.MinPk.pk_to_bytes pk] + Bls_public_key_hash.hash_bytes [Bls12_381.Signature.MinSig.pk_to_bytes pk] in Log.info "A new BLS key was generated: %s" @@ -420,7 +420,7 @@ let sign_transaction sks txs = Tx_rollup_l2_batch.V1.transaction_encoding txs in - List.map (fun sk -> Bls12_381.Signature.MinPk.Aug.sign sk buf) sks + List.map (fun sk -> Bls12_381.Signature.MinSig.Aug.sign sk buf) sks let craft_tx ~counter ~signer ~dest ~ticket qty = let open Tezos_protocol_alpha.Protocol in @@ -439,7 +439,7 @@ let craft_tx ~counter ~signer ~dest ~ticket qty = Tx_rollup_l2_batch.V1.{signer; counter; contents = [content]} let aggregate_signature_exn signatures = - match Bls12_381.Signature.MinPk.aggregate_signature_opt signatures with + match Bls12_381.Signature.MinSig.aggregate_signature_opt signatures with | Some res -> res | None -> invalid_arg "aggregate_signature_exn" From 79134b1b00e19e889a764ece0f711ccb5ec0f459 Mon Sep 17 00:00:00 2001 From: icristescu <ioana@tarides.com> Date: Mon, 21 Mar 2022 21:45:46 +0100 Subject: [PATCH 097/100] lib_context: update to irmin.3.2.0 --- src/lib_context/encoding/context.ml | 10 +++++++++ src/lib_context/encoding/context_binary.ml | 2 ++ src/lib_context/helpers/context.ml | 26 ++-------------------- 3 files changed, 14 insertions(+), 24 deletions(-) diff --git a/src/lib_context/encoding/context.ml b/src/lib_context/encoding/context.ml index 0649bbf2f7..9463ecf428 100644 --- a/src/lib_context/encoding/context.ml +++ b/src/lib_context/encoding/context.ml @@ -35,6 +35,8 @@ module Conf = struct let contents_length_header = Some `Varint let inode_child_order = `Seeded_hash + + let forbid_empty_dir_persistence = true end module Hash : sig @@ -54,6 +56,8 @@ end = struct let to_raw_string = H.to_raw_string + let unsafe_of_raw_string s = H.of_raw_string s + let of_context_hash s = H.of_raw_string (Context_hash.to_string s) let to_context_hash h = Context_hash.of_string_exn (H.to_raw_string h) @@ -75,6 +79,12 @@ end = struct let short_hash ?seed t = short_hash_string ?seed (H.to_raw_string t) + let hash_size = H.digest_size + + let short_hash_substring t ~off = + let str = Bigstringaf.substring t ~off ~len:hash_size in + short_hash_string str + let t : t Irmin.Type.t = Irmin.Type.map ~pp diff --git a/src/lib_context/encoding/context_binary.ml b/src/lib_context/encoding/context_binary.ml index ef76582cb1..d91777bbc4 100644 --- a/src/lib_context/encoding/context_binary.ml +++ b/src/lib_context/encoding/context_binary.ml @@ -35,4 +35,6 @@ module Conf = struct let inode_child_order = `Hash_bits let contents_length_header = Some `Varint + + let forbid_empty_dir_persistence = true end diff --git a/src/lib_context/helpers/context.ml b/src/lib_context/helpers/context.ml index 74a6a6b629..73e1b3cbc4 100644 --- a/src/lib_context/helpers/context.ml +++ b/src/lib_context/helpers/context.ml @@ -360,29 +360,9 @@ struct let+ (p, r) = Store.Tree.produce_proof repo key f in (Proof.to_tree p, r) - (* This is temporary until the release of irmin.3.2.0, see - https://github.com/mirage/irmin/issues/1790. *) - let specialise_error = function - | Ok r -> Lwt.return_ok r - | Error (`Msg error) -> - if - String.equal - error - "Bad_stream verify_stream: did not consume the full stream" - then Lwt.return_error (`Stream_too_long error) - else - let x = String.split ' ' error in - if - List.exists (String.equal "empty") x - && List.exists (String.equal "Bad_stream") x - then Lwt.return_error (`Stream_too_short error) - else Lwt.return_error (`Proof_mismatch error) - let verify_tree_proof proof f = - let open Lwt_syntax in let proof = Proof.of_tree proof in - let* result = Store.Tree.verify_proof proof f in - specialise_error result + Store.Tree.verify_proof proof f let produce_stream_proof repo key f = let open Lwt_syntax in @@ -393,10 +373,8 @@ struct (Proof.to_stream p, r) let verify_stream_proof proof f = - let open Lwt_syntax in let proof = Proof.of_stream proof in - let* result = Store.Tree.verify_stream proof f in - specialise_error result + Store.Tree.verify_stream proof f end type error += Unsupported_context_hash_version of Context_hash.Version.t From 66d9a6c7f452866e828e483c98a094d4d536f9ee Mon Sep 17 00:00:00 2001 From: icristescu <ioana@tarides.com> Date: Mon, 21 Mar 2022 21:46:12 +0100 Subject: [PATCH 098/100] proto_alpha: update to irmin.3.2.0 --- src/proto_alpha/bin_tx_rollup_node/stores.ml | 2 ++ .../lib_protocol/test/helpers/tx_rollup_l2_helpers.ml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/proto_alpha/bin_tx_rollup_node/stores.ml b/src/proto_alpha/bin_tx_rollup_node/stores.ml index 6bce0f34c6..c18739dc0b 100644 --- a/src/proto_alpha/bin_tx_rollup_node/stores.ml +++ b/src/proto_alpha/bin_tx_rollup_node/stores.ml @@ -36,6 +36,8 @@ module Conf = struct let inode_child_order = `Seeded_hash let contents_length_header = Some `Varint + + let forbid_empty_dir_persistence = true end module Kv = struct diff --git a/src/proto_alpha/lib_protocol/test/helpers/tx_rollup_l2_helpers.ml b/src/proto_alpha/lib_protocol/test/helpers/tx_rollup_l2_helpers.ml index 83fb215e36..3b04fc8acf 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/tx_rollup_l2_helpers.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/tx_rollup_l2_helpers.ml @@ -38,6 +38,8 @@ module Store = struct let inode_child_order = `Seeded_hash let contents_length_header = None + + let forbid_empty_dir_persistence = true end open Irmin_pack_mem.Maker (Conf) From 81adcd37d98a55f110d7d347f40f78e0c5de491d Mon Sep 17 00:00:00 2001 From: icristescu <ioana@tarides.com> Date: Wed, 2 Mar 2022 15:58:59 +0100 Subject: [PATCH 099/100] Expose inodes in the snapshot format --- src/bin_node/node_snapshot_command.ml | 6 + src/lib_context/context.ml | 199 ++++++++------ src/lib_context/context.mli | 1 + src/lib_context/context_dump.ml | 375 +++++++++++++++++--------- src/lib_context/context_dump_intf.ml | 57 +++- src/lib_store/snapshots.ml | 37 ++- src/lib_store/snapshots.mli | 1 + 7 files changed, 443 insertions(+), 233 deletions(-) diff --git a/src/bin_node/node_snapshot_command.ml b/src/bin_node/node_snapshot_command.ml index b6e3757254..ef056ff397 100644 --- a/src/bin_node/node_snapshot_command.ml +++ b/src/bin_node/node_snapshot_command.ml @@ -170,6 +170,11 @@ module Term = struct node_config.blockchain_network in let* snapshot_path = check_snapshot_path snapshot_path in + let* snapshot_header = + Snapshots.read_snapshot_header ~snapshot_path + in + let version = Snapshots.version snapshot_header in + Fmt.epr "XXX snapshot_version %d \n%!" version ; let dir_cleaner () = let*! () = Event.(emit cleaning_up_after_failure) data_dir in if existing_data_dir then @@ -226,6 +231,7 @@ module Term = struct let check_consistency = not disable_check in let configured_history_mode = node_config.shell.history_mode in Snapshots.import + ~version ~snapshot_path ~patch_context ?block diff --git a/src/lib_context/context.ml b/src/lib_context/context.ml index 98d9045ee6..58888e3a27 100644 --- a/src/lib_context/context.ml +++ b/src/lib_context/context.ml @@ -164,6 +164,8 @@ end = struct let to_irmin = function `Always -> I.always | `Minimal -> I.minimal end +let on_disk_index = ref `No + let () = let verbose_info () = Logs.set_level (Some Logs.Info) ; @@ -184,6 +186,7 @@ let () = "Invalid value for TEZOS_CONTEXT environment variable: %s" msg in + let on_disk_index n = on_disk_index := n in match Unix.getenv "TEZOS_CONTEXT" with | exception Not_found -> () | v -> @@ -198,6 +201,7 @@ let () = | ["auto-flush"; n] -> auto_flush n | ["lru-size"; n] -> lru_size n | ["indexing-strategy"; x] -> indexing_strategy x + | ["on-disk-index"; path] -> on_disk_index (`Yes path) | _ -> ())) args @@ -832,89 +836,115 @@ module Make (Encoding : module type of Tezos_context_encoding.Context) = struct let context_tree ctxt = ctxt.tree - type binding = { - key : string; - value : tree; - value_kind : [`Node | `Contents]; - value_hash : hash; - } + module Snapshot = struct + include Store.Snapshot - (** Unpack the bindings in a tree node (in lexicographic order) and clear its - internal cache. *) - let bindings tree : binding list Lwt.t = - let open Lwt_syntax in - let* keys = Store.Tree.list tree [] in - let+ bindings = - keys - |> List.sort (fun (a, _) (b, _) -> String.compare a b) - |> List.map_s (fun (key, value) -> - let+ o = Store.Tree.kind value [] in - match o with - | None -> - (* The value must exist in the tree, because we're - iterating over existing keys *) - assert false - | Some value_kind -> - let value_hash = Store.Tree.hash value in - {key; value; value_kind; value_hash}) - in - Store.Tree.clear tree ; - bindings + let kinded_hash_encoding : kinded_hash Data_encoding.t = + let open Data_encoding in + let kind_encoding = + string_enum [("node", `Node); ("contents", `Contents)] + in + conv + (function + | Contents (h, ()) -> + (`Contents, Context_hash.to_bytes (Hash.to_context_hash h)) + | Node h -> (`Node, Context_hash.to_bytes (Hash.to_context_hash h))) + (function + | (`Contents, h) -> + let h = Hash.of_context_hash (Context_hash.of_bytes_exn h) in + Contents (h, ()) + | (`Node, h) -> + Node (Hash.of_context_hash (Context_hash.of_bytes_exn h))) + (obj2 (req "kind" kind_encoding) (req "value" bytes)) - module Hashset = struct - module String_set = Utils.String_set + let hash_encoding : hash Data_encoding.t = + let open Data_encoding in + conv + (fun h -> Context_hash.to_bytes (Hash.to_context_hash h)) + (fun h -> Hash.of_context_hash (Context_hash.of_bytes_exn h)) + bytes - let create () = - String_set.create ~elt_length:Hash.hash_size ~initial_capacity:100_000 + let entry_encoding : entry Data_encoding.t = + let open Data_encoding in + conv + (fun {step; hash} -> (step, hash)) + (fun (step, hash) -> {step; hash}) + (obj2 (req "name" string) (req "hash" kinded_hash_encoding)) - let mem t h = String_set.mem t (Hash.to_raw_string h) + let inode_tree_encoding : inode_tree Data_encoding.t = + let open Data_encoding in + let pair_encoding = + obj2 (req "index" uint16) (req "hash" hash_encoding) + in + conv + (fun {depth; length; pointers} -> + (Int32.of_int depth, Int32.of_int length, pointers)) + (fun (depth, length, pointers) -> + {depth = Int32.to_int depth; length = Int32.to_int length; pointers}) + (obj3 + (req "depth" int32) + (req "length" int32) + (req "pointers" (list pair_encoding))) + + let v_encoding : v Data_encoding.t = + let open Data_encoding in + let inode_tree_case = + case + ~title:"tree" + (Tag (Char.code 't')) + inode_tree_encoding + (function Inode_tree t -> Some t | _ -> None) + (fun t -> Inode_tree t) + in + let inode_value_case = + case + ~title:"value" + (Tag (Char.code 'v')) + (list entry_encoding) + (function Inode_value t -> Some t | _ -> None) + (fun t -> Inode_value t) + in + Data_encoding.union ~tag_size:`Uint8 [inode_tree_case; inode_value_case] - let add t h = String_set.add t (Hash.to_raw_string h) + let encoding : inode Data_encoding.t = + let open Data_encoding in + conv + (fun {v; root} -> (v, root)) + (fun (v, root) -> {v; root}) + (obj2 (req "v" v_encoding) (req "root" bool)) end - let tree_iteri_unique f tree = - let open Lwt_syntax in - let total_visited = ref 0 in - (* Noting the visited hashes *) - let visited_hash = Hashset.create () in - let visited h = Hashset.mem visited_hash h in - let set_visit h = - incr total_visited ; - Hashset.add visited_hash h + let tree_iteri_unique index f tree = + let root_key = + match Store.Tree.key tree with None -> assert false | Some key -> key in - let rec aux : type a. tree -> (unit -> a) -> a Lwt.t = - fun tree k -> - let* bs = bindings tree in - let* sub_keys = - List.map_s - (fun {key; value; value_hash; value_kind} -> - let kinded_value_hash = - match value_kind with - | `Node -> `Node value_hash - | `Contents -> `Blob value_hash - in - let kv = (key, kinded_value_hash) in - if visited value_hash then Lwt.return kv - else - match value_kind with - | `Node -> - (* Visit children first, in left-to-right order. *) - (aux [@ocaml.tailcall]) value (fun () -> - (* There cannot be a cycle. *) - set_visit value_hash ; - kv) - | `Contents -> - let* data = Store.Tree.get value [] in - let+ () = f (`Leaf data) in - set_visit value_hash ; - kv) - bs - in - let+ v = f (`Branch sub_keys) in - k v + let on_disk = + match !on_disk_index with `No -> None | `Yes path -> Some (`Path path) in - let* () = aux tree Fun.id in - Lwt.return !total_visited + Snapshot.export ?on_disk index.repo f ~root_key + + type import = Snapshot.Import.process + + let v_import idx = + let indexing_strategy = Indexing_strategy.get () in + let on_disk = + match indexing_strategy with + | `Always -> + Some `Reuse + (* reuse index when importing a snaphot with the always indexing + strategy. *) + | `Minimal -> ( + match !on_disk_index with + | `No -> None + | `Yes path -> Some (`Path path)) + in + Snapshot.Import.v ?on_disk idx.repo + + let save_inode idx import snapshot = + Snapshot.Import.save_elt import snapshot >>= fun key -> + Store.Tree.of_key idx.repo (`Node key) + + let close_import import = Snapshot.Import.close import let make_context index = empty index @@ -1028,6 +1058,7 @@ module Make (Encoding : module type of Tezos_context_encoding.Context) = struct (* Context dumper *) module Context_dumper = Context_dump.Make (Dumpable_context) + module Context_dumper_legacy = Context_dump.Make_legacy (Dumpable_context) (* provides functions dump_context and restore_context *) let dump_context idx data ~fd = @@ -1036,10 +1067,18 @@ module Make (Encoding : module type of Tezos_context_encoding.Context) = struct let* () = Lwt_unix.fsync fd in Lwt.return res - let restore_context idx ~expected_context_hash ~nb_context_elements ~fd = - Context_dumper.restore_context_fd - idx - ~expected_context_hash - ~fd - ~nb_context_elements + let restore_context idx ~expected_context_hash ~nb_context_elements ~fd + ~legacy = + if legacy then + Context_dumper_legacy.restore_context_fd + idx + ~expected_context_hash + ~fd + ~nb_context_elements + else + Context_dumper.restore_context_fd + idx + ~expected_context_hash + ~fd + ~nb_context_elements end diff --git a/src/lib_context/context.mli b/src/lib_context/context.mli index 1e6862baca..73fc8e8ad3 100644 --- a/src/lib_context/context.mli +++ b/src/lib_context/context.mli @@ -183,6 +183,7 @@ module Make (Encoding : module type of Tezos_context_encoding.Context) : sig expected_context_hash:Context_hash.t -> nb_context_elements:int -> fd:Lwt_unix.file_descr -> + legacy:bool -> unit tzresult Lwt.t val retrieve_commit_info : diff --git a/src/lib_context/context_dump.ml b/src/lib_context/context_dump.ml index cc921e7bf8..9900f93275 100644 --- a/src/lib_context/context_dump.ml +++ b/src/lib_context/context_dump.ml @@ -92,10 +92,60 @@ let () = (function Restore_context_failure -> Some () | _ -> None) (fun () -> Restore_context_failure) -module Make (I : Dump_interface) = struct +(* IO toolkit. *) + +let rec read_string rbuf ~len = + let open Lwt_tzresult_syntax in + let (fd, buf, ofs, total) = !rbuf in + if Bytes.length buf - ofs < len then ( + let blen = Bytes.length buf - ofs in + let neu = Bytes.create (blen + 1_000_000) in + Bytes.blit buf ofs neu 0 blen ; + let*! bread = Lwt_unix.read fd neu blen 1_000_000 in + total := !total + bread ; + if bread = 0 then fail Inconsistent_context_dump + else + let neu = + if bread <> 1_000_000 then Bytes.sub neu 0 (blen + bread) else neu + in + rbuf := (fd, neu, 0, total) ; + read_string rbuf ~len) + else + let res = Bytes.sub_string buf ofs len in + rbuf := (fd, buf, ofs + len, total) ; + return res + +let read_mbytes rbuf b = + let open Lwt_result_syntax in + let* string = read_string rbuf ~len:(Bytes.length b) in + Bytes.blit_string string 0 b 0 (Bytes.length b) ; + return () + +let set_int64 buf i = + let b = Bytes.create 8 in + EndianBytes.BigEndian.set_int64 b 0 i ; + Buffer.add_bytes buf b + +let get_int64 rbuf = + let open Lwt_result_syntax in + let* s = read_string ~len:8 rbuf in + return @@ EndianString.BigEndian.get_int64 s 0 + +let flush written context_fd buf = + let contents = Buffer.contents buf in + Buffer.clear buf ; + written := !written + String.length contents ; + Lwt_utils_unix.write_string context_fd contents + +let set_mbytes written context_fd buf b = + set_int64 buf (Int64.of_int (Bytes.length b)) ; + Buffer.add_bytes buf b ; + if Buffer.length buf > 1_000_000 then flush written context_fd buf + else Lwt.return_unit + +module Make_legacy (I : Dump_interface) = struct type command = | Root - | Node of (string * I.Kinded_hash.t) list | Node_seq of (string * I.Kinded_hash.t, error trace) Seq_es.t | Blob of bytes | Eoc of {info : I.commit_info; parents : I.Commit_hash.t list} @@ -103,97 +153,6 @@ module Make (I : Dump_interface) = struct (* Command encoding. *) - let blob_encoding = - let open Data_encoding in - case - ~title:"blob" - (Tag (Char.code 'b')) - bytes - (function Blob b -> Some b | _ -> None) - (function b -> Blob b) - - let node_encoding = - let open Data_encoding in - case - ~title:"node" - (Tag (Char.code 'n')) - (list (obj2 (req "name" string) (req "hash" I.Kinded_hash.encoding))) - (function Node x -> Some x | _ -> None) - (function x -> Node x) - - let eof_encoding = - let open Data_encoding in - case - ~title:"eof" - (Tag (Char.code 'e')) - empty - (function Eof -> Some () | _ -> None) - (fun () -> Eof) - - let root_encoding = - let open Data_encoding in - case - ~title:"root" - (Tag (Char.code 'r')) - empty - (function Root -> Some () | _ -> None) - (fun () -> Root) - - let eoc_encoding = - let open Data_encoding in - case - ~title:"eoc" - (Tag (Char.code 'c')) - (obj2 - (req "info" I.commit_info_encoding) - (req "parents" (list I.Commit_hash.encoding))) - (function Eoc {info; parents} -> Some (info, parents) | _ -> None) - (fun (info, parents) -> Eoc {info; parents}) - - let command_encoding = - Data_encoding.union - ~tag_size:`Uint8 - [blob_encoding; node_encoding; eoc_encoding; root_encoding; eof_encoding] - - (* IO toolkit. *) - - let rec read_string rbuf ~len = - let open Lwt_tzresult_syntax in - let (fd, buf, ofs, total) = !rbuf in - if Bytes.length buf - ofs < len then ( - let blen = Bytes.length buf - ofs in - let neu = Bytes.create (blen + 1_000_000) in - Bytes.blit buf ofs neu 0 blen ; - let*! bread = Lwt_unix.read fd neu blen 1_000_000 in - total := !total + bread ; - if bread = 0 then fail Inconsistent_context_dump - else - let neu = - if bread <> 1_000_000 then Bytes.sub neu 0 (blen + bread) else neu - in - rbuf := (fd, neu, 0, total) ; - read_string rbuf ~len) - else - let res = Bytes.sub_string buf ofs len in - rbuf := (fd, buf, ofs + len, total) ; - return res - - let read_mbytes rbuf b = - let open Lwt_result_syntax in - let* string = read_string rbuf ~len:(Bytes.length b) in - Bytes.blit_string string 0 b 0 (Bytes.length b) ; - return () - - let set_int64 buf i = - let b = Bytes.create 8 in - EndianBytes.BigEndian.set_int64 b 0 i ; - Buffer.add_bytes buf b - - let get_int64 rbuf = - let open Lwt_result_syntax in - let* s = read_string ~len:8 rbuf in - return @@ EndianString.BigEndian.get_int64 s 0 - let get_char rbuf = let open Lwt_result_syntax in let* s = read_string ~len:1 rbuf in @@ -204,10 +163,6 @@ module Make (I : Dump_interface) = struct let* s = read_string ~len:4 rbuf in return @@ EndianString.BigEndian.get_int32 s 0 - let set_mbytes buf b = - set_int64 buf (Int64.of_int (Bytes.length b)) ; - Buffer.add_bytes buf b - (* To decode a variable size string we need to: 1/ read the length of the string, encoded on 4 bytes; 2/ reset the offset to the beginning of the string encoding. *) @@ -294,48 +249,194 @@ module Make (I : Dump_interface) = struct Lwt.return_ok (Node_seq data) | _ -> fail Restore_context_failure + (* Restoring *) + + let restore_context_fd index ~expected_context_hash ~fd ~nb_context_elements = + let open Lwt_tzresult_syntax in + let read = ref 0 in + let rbuf = ref (fd, Bytes.empty, 0, read) in + (* Editing the repository *) + let add_blob t blob = + let*! tree = I.add_bytes t blob in + return tree + in + let add_dir t keys = + I.add_dir t keys >>=? function + | None -> fail Restore_context_failure + | Some tree -> return tree + in + let restore () = + let first_pass () = + let* r = get_command rbuf in + match r with Root -> return_unit | _ -> fail Inconsistent_context_dump + in + let rec second_pass batch ctxt context_hash notify = + let*! () = notify () in + let* c = get_command rbuf in + match c with + | Node_seq contents -> + let* tree = add_dir batch contents in + second_pass batch (I.update_context ctxt tree) context_hash notify + | Blob data -> + let* tree = add_blob batch data in + second_pass batch (I.update_context ctxt tree) context_hash notify + | Eoc {info; parents} -> ( + let*! b = I.set_context ~info ~parents ctxt context_hash in + match b with + | false -> fail Inconsistent_context_dump + | true -> return_unit) + | _ -> fail Inconsistent_context_dump + in + let check_eof () = + let* e = get_command rbuf in + match e with Eof -> return_unit | _ -> fail Inconsistent_context_dump + in + let* block_data = first_pass () in + let* () = + Animation.display_progress + ~every:1000 + ~pp_print_step:(fun fmt i -> + Format.fprintf + fmt + "Writing context: %dK/%dK (%d%%) elements, %s read" + (i / 1_000) + (nb_context_elements / 1_000) + (100 * i / nb_context_elements) + (if !read > 1_048_576 then + Format.asprintf "%dMiB" (!read / 1_048_576) + else Format.asprintf "%dKiB" (!read / 1_024))) + (fun notify -> + I.batch index (fun batch -> + second_pass + batch + (I.make_context index) + expected_context_hash + notify)) + in + let* () = check_eof () in + return block_data + in + Lwt.catch + (fun () -> restore ()) + (function + | Unix.Unix_error (e, _, _) -> + fail @@ System_read_error (Unix.error_message e) + | err -> Lwt.fail err) +end + +module Make (I : Dump_interface) = struct + type command = + | Root + | Blob of bytes + | Inode of I.Snapshot.inode + | Eoc of {info : I.commit_info; parents : I.Commit_hash.t list} + | Eof + + (* Command encoding. *) + + let blob_encoding = + let open Data_encoding in + case + ~title:"blob" + (Tag (Char.code 'b')) + bytes + (function Blob b -> Some b | _ -> None) + (function b -> Blob b) + + let inode_encoding = + let open Data_encoding in + case + ~title:"inode" + (Tag (Char.code 'i')) + I.Snapshot.encoding + (function Inode b -> Some b | _ -> None) + (function b -> Inode b) + + let eof_encoding = + let open Data_encoding in + case + ~title:"eof" + (Tag (Char.code 'e')) + empty + (function Eof -> Some () | _ -> None) + (fun () -> Eof) + + let root_encoding = + let open Data_encoding in + case + ~title:"root" + (Tag (Char.code 'r')) + empty + (function Root -> Some () | _ -> None) + (fun () -> Root) + + let eoc_encoding = + let open Data_encoding in + case + ~title:"eoc" + (Tag (Char.code 'c')) + (obj2 + (req "info" I.commit_info_encoding) + (req "parents" (list I.Commit_hash.encoding))) + (function Eoc {info; parents} -> Some (info, parents) | _ -> None) + (fun (info, parents) -> Eoc {info; parents}) + + let command_encoding = + Data_encoding.union + ~tag_size:`Uint8 + [blob_encoding; eoc_encoding; root_encoding; eof_encoding; inode_encoding] + + let get_mbytes rbuf = + get_int64 rbuf >|=? Int64.to_int >>=? fun l -> + let b = Bytes.create l in + read_mbytes rbuf b >>=? fun () -> return b + + let get_command rbuf = + get_mbytes rbuf >|=? fun bytes -> + Data_encoding.Binary.of_bytes_exn command_encoding bytes + (* Getter and setters *) - let set_root buf = + let set_root written context_fd buf = let root = Root in let bytes = Data_encoding.Binary.to_bytes_exn command_encoding root in - set_mbytes buf bytes + set_mbytes written context_fd buf bytes - let set_tree buf tree = - (match tree with `Branch node -> Node node | `Leaf blob -> Blob blob) - |> Data_encoding.Binary.to_bytes_exn command_encoding - |> set_mbytes buf + let set_tree written context_fd ~notify buf (tree : I.Snapshot.t) = + let x = + match tree with Inode node -> Inode node | Blob blob -> Blob blob + in + let s = + match Data_encoding.Binary.to_bytes command_encoding x with + | Ok s -> s + | Error error -> + Fmt.failwith + "error write %a" + Data_encoding.Binary.pp_write_error + error + in + set_mbytes written context_fd buf s >>= fun () -> notify () - let set_eoc buf info parents = + let set_eoc written context_fd buf info parents = let eoc = Eoc {info; parents} in let bytes = Data_encoding.Binary.to_bytes_exn command_encoding eoc in - set_mbytes buf bytes + set_mbytes written context_fd buf bytes - let set_end buf = + let set_end written context_fd buf = let bytes = Data_encoding.Binary.to_bytes_exn command_encoding Eof in - set_mbytes buf bytes + set_mbytes written context_fd buf bytes - let serialize_tree ~notify ~maybe_flush buf = - let open Lwt_syntax in - I.tree_iteri_unique (fun sub_tree -> - set_tree buf sub_tree ; - let* () = maybe_flush () in - notify ()) + let serialize_tree written context_fd ~notify buf tree idx = + I.tree_iteri_unique + idx + (fun sub_tree -> set_tree written context_fd ~notify buf sub_tree) + tree let dump_context_fd idx context_hash ~context_fd = let open Lwt_syntax in (* Dumping *) let buf = Buffer.create 1_000_000 in let written = ref 0 in - let flush () = - let contents = Buffer.contents buf in - Buffer.clear buf ; - written := !written + String.length contents ; - Lwt_utils_unix.write_string context_fd contents - in - let maybe_flush () = - if Buffer.length buf > 1_000_000 then flush () else Lwt.return_unit - in Lwt.catch (fun () -> let* o = I.checkout idx context_hash in @@ -355,14 +456,17 @@ module Make (I : Dump_interface) = struct Format.asprintf "%dMiB" (!written / 1_048_576) else Format.asprintf "%dKiB" (!written / 1_024))) (fun notify -> - set_root buf ; + let* () = set_root written context_fd buf in + let tree = I.context_tree ctxt in let* elements = - I.context_tree ctxt |> serialize_tree ~notify ~maybe_flush buf + serialize_tree written context_fd ~notify buf tree idx in let parents = I.context_parents ctxt in - set_eoc buf (I.context_info ctxt) parents ; - set_end buf ; - let* () = flush () in + let* () = + set_eoc written context_fd buf (I.context_info ctxt) parents + in + let* () = set_end written context_fd buf in + let* () = flush written context_fd buf in return_ok elements)) (function | Unix.Unix_error (e, _, _) -> @@ -380,9 +484,10 @@ module Make (I : Dump_interface) = struct let*! tree = I.add_bytes t blob in return tree in - let add_dir t keys = - let* o = I.add_dir t keys in - match o with + let import_t = I.v_import index in + let save_inode = I.save_inode index import_t in + let add_inode i = + save_inode i >>= function | None -> fail Restore_context_failure | Some tree -> return tree in @@ -395,8 +500,8 @@ module Make (I : Dump_interface) = struct let*! () = notify () in let* c = get_command rbuf in match c with - | Node_seq contents -> - let* tree = add_dir batch contents in + | Inode i -> + add_inode (Inode i) >>=? fun tree -> second_pass batch (I.update_context ctxt tree) context_hash notify | Blob data -> let* tree = add_blob batch data in @@ -410,7 +515,11 @@ module Make (I : Dump_interface) = struct in let check_eof () = let* e = get_command rbuf in - match e with Eof -> return_unit | _ -> fail Inconsistent_context_dump + match e with + | Eof -> + I.close_import import_t ; + return_unit + | _ -> fail Inconsistent_context_dump in let* block_data = first_pass () in let* () = diff --git a/src/lib_context/context_dump_intf.ml b/src/lib_context/context_dump_intf.ml index 0fdcb4a20e..987973bb55 100644 --- a/src/lib_context/context_dump_intf.ml +++ b/src/lib_context/context_dump_intf.ml @@ -113,14 +113,6 @@ module type Dump_interface = sig (* for dumping *) val context_tree : context -> tree - (** Visit each branch and leaf of the given tree {i exactly once}, in - depth-first post-order traversal. Branch children are visited in ascending - key order. Memory usage is linear in the size of the tree. *) - val tree_iteri_unique : - ([`Branch of (step * Kinded_hash.t) list | `Leaf of contents] -> unit Lwt.t) -> - tree -> - int Lwt.t - (* for restoring *) val make_context : index -> context @@ -132,6 +124,33 @@ module type Dump_interface = sig batch -> (step * Kinded_hash.t, error trace) Seq_es.t -> (tree option, error trace) result Lwt.t + + module Snapshot : sig + type kinded_hash = Contents of hash * unit | Node of hash + + type entry = {step : string; hash : kinded_hash} + + type inode_tree = {depth : int; length : int; pointers : (int * hash) list} + + type v = Inode_tree of inode_tree | Inode_value of entry list + + type inode = {v : v; root : bool} + + type t = Inode of inode | Blob of contents + + val encoding : inode Data_encoding.t + end + + val tree_iteri_unique : + index -> (Snapshot.t -> unit Lwt.t) -> tree -> int Lwt.t + + type import + + val v_import : index -> import + + val save_inode : index -> import -> Snapshot.t -> tree option Lwt.t + + val close_import : import -> unit end module type S = sig @@ -169,6 +188,28 @@ module type Context_dump = sig and type context := I.context and type block_header := I.Block_header.t and type context_hash := I.Commit_hash.t + + (* Preserve a legacy importer for now. *) + module Make_legacy (I : Dump_interface) : sig + type index + + type context + + type block_header + + type context_hash + + val restore_context_fd : + index -> + expected_context_hash:context_hash -> + fd:Lwt_unix.file_descr -> + nb_context_elements:int -> + unit tzresult Lwt.t + end + with type index := I.index + and type context := I.context + and type block_header := I.Block_header.t + and type context_hash := I.Commit_hash.t end (* Legacy *) diff --git a/src/lib_store/snapshots.ml b/src/lib_store/snapshots.ml index 813560b688..4dbb059e00 100644 --- a/src/lib_store/snapshots.ml +++ b/src/lib_store/snapshots.ml @@ -36,8 +36,12 @@ module Version = struct (* Current version of the snapshots, since 0.0.5. * Previous versions are: - * - 1: snapshot exported with storage 0.0.1 to 0.0.4 *) - let current_version = 2 + * - 1: snapshot exported with storage 0.0.1 to 0.0.4 + * - 2: snapshot exported with storage 0.0.4 to 0.x.x *) + let current_version = 3 + + (* Legacy snapshots are fixed to a single version *) + let legacy_version = 2 end let current_version = Version.current_version @@ -2662,6 +2666,7 @@ module type IMPORTER = sig Context.index -> expected_context_hash:Context_hash.t -> nb_context_elements:int -> + legacy:bool -> unit tzresult Lwt.t val load_protocol_table : @@ -2732,7 +2737,7 @@ module Raw_importer : IMPORTER = struct | None -> fail (Cannot_read {kind = `Block_data; path = file}) let restore_context t context_index ~expected_context_hash - ~nb_context_elements = + ~nb_context_elements ~legacy = let open Lwt_tzresult_syntax in let context_file_path = Naming.(snapshot_context_file t.snapshot_dir |> file_path) @@ -2761,6 +2766,7 @@ module Raw_importer : IMPORTER = struct ~expected_context_hash ~fd ~nb_context_elements + ~legacy in (* FIXME: Is this test really usefull? *) let*! current = Lwt_unix.lseek fd 0 Lwt_unix.SEEK_CUR in @@ -3009,7 +3015,7 @@ module Tar_importer : IMPORTER = struct | None -> fail (Cannot_read {kind = `Block_data; path = filename}) let restore_context t context_index ~expected_context_hash - ~nb_context_elements = + ~nb_context_elements ~legacy = let open Lwt_tzresult_syntax in let filename = Naming.(snapshot_context_file t.snapshot_tar |> file_path) in let* header = @@ -3024,6 +3030,7 @@ module Tar_importer : IMPORTER = struct ~expected_context_hash ~nb_context_elements ~fd + ~legacy let load_protocol_table t = let open Lwt_tzresult_syntax in @@ -3244,6 +3251,7 @@ module type Snapshot_importer = sig configured_history_mode:History_mode.t option -> user_activated_upgrades:User_activated.upgrades -> user_activated_protocol_overrides:User_activated.protocol_overrides -> + version:int -> Genesis.t -> (unit, error trace) result Lwt.t end @@ -3389,7 +3397,7 @@ module Make_snapshot_importer (Importer : IMPORTER) : Snapshot_importer = struct let restore_and_apply_context snapshot_importer ?user_expected_block ~context_index ~user_activated_upgrades ~user_activated_protocol_overrides - snapshot_metadata genesis chain_id = + snapshot_metadata genesis chain_id ~legacy = let open Lwt_tzresult_syntax in (* Start by committing genesis *) let* genesis_ctxt_hash = @@ -3434,6 +3442,7 @@ module Make_snapshot_importer (Importer : IMPORTER) : Snapshot_importer = struct context_index ~expected_context_hash:predecessor_header.Block_header.shell.context ~nb_context_elements:snapshot_metadata.context_elements + ~legacy in let pred_context_hash = predecessor_header.shell.context in let* predecessor_context = @@ -3487,7 +3496,7 @@ module Make_snapshot_importer (Importer : IMPORTER) : Snapshot_importer = struct let import ~snapshot_path ?patch_context ?block:user_expected_block ?(check_consistency = true) ~dst_store_dir ~dst_context_dir ~chain_name ~configured_history_mode ~user_activated_upgrades - ~user_activated_protocol_overrides (genesis : Genesis.t) = + ~user_activated_protocol_overrides ~version (genesis : Genesis.t) = let open Lwt_tzresult_syntax in let chain_id = Chain_id.of_block_hash genesis.Genesis.block in let*! snapshot_importer = init ~snapshot_path ~dst_store_dir chain_id in @@ -3544,11 +3553,12 @@ module Make_snapshot_importer (Importer : IMPORTER) : Snapshot_importer = struct user_expected_block in let*! context_index = - Context.init - ~readonly:false - ~indexing_strategy:`Always - ?patch_context - dst_context_dir + Context.init ~readonly:false ?patch_context dst_context_dir + in + let* legacy = + if version = Version.legacy_version then Lwt.return_ok true + else if version = Version.current_version then Lwt.return_ok false + else fail (Cannot_read {kind = `Version; path = snapshot_path}) in (* Restore context *) let* (block_data, genesis_context_hash, block_validation_result) = @@ -3561,6 +3571,7 @@ module Make_snapshot_importer (Importer : IMPORTER) : Snapshot_importer = struct snapshot_metadata genesis chain_id + ~legacy in (* Restore store *) (* Restore protocols *) @@ -3714,7 +3725,8 @@ let read_snapshot_header ~snapshot_path = let import ~snapshot_path ?patch_context ?block ?check_consistency ~dst_store_dir ~dst_context_dir ~chain_name ~configured_history_mode - ~user_activated_upgrades ~user_activated_protocol_overrides genesis = + ~user_activated_upgrades ~user_activated_protocol_overrides ~version genesis + = let open Lwt_tzresult_syntax in let* kind = snapshot_file_kind ~snapshot_path in let (module Importer) = @@ -3734,4 +3746,5 @@ let import ~snapshot_path ?patch_context ?block ?check_consistency ~configured_history_mode ~user_activated_upgrades ~user_activated_protocol_overrides + ~version genesis diff --git a/src/lib_store/snapshots.mli b/src/lib_store/snapshots.mli index 1ae41d644d..404f2cbd7a 100644 --- a/src/lib_store/snapshots.mli +++ b/src/lib_store/snapshots.mli @@ -202,6 +202,7 @@ val import : configured_history_mode:History_mode.t option -> user_activated_upgrades:User_activated.upgrades -> user_activated_protocol_overrides:User_activated.protocol_overrides -> + version:int -> Genesis.t -> unit tzresult Lwt.t From 173f6929de79c9c82f37bacde5d1361a2cdf3f38 Mon Sep 17 00:00:00 2001 From: icristescu <ioana@tarides.com> Date: Mon, 21 Mar 2022 21:44:20 +0100 Subject: [PATCH 100/100] wip --- src/lib_context/context.ml | 9 +++++++-- src/lib_context/context_dump.ml | 6 ++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/lib_context/context.ml b/src/lib_context/context.ml index 58888e3a27..a28c6070b9 100644 --- a/src/lib_context/context.ml +++ b/src/lib_context/context.ml @@ -972,13 +972,18 @@ module Make (Encoding : module type of Tezos_context_encoding.Context) = struct let open Lwt_tzresult_syntax in let add sub_tree (step, hash) = match sub_tree with - | None -> Lwt.return_some (Store.Tree.empty ()) - | Some sub_tree -> add_hash batch sub_tree [step] hash + | None -> + Fmt.epr "XXX add_dir subtree 1 \n%!" ; + Lwt.return_some (Store.Tree.empty ()) + | Some sub_tree -> + Fmt.epr "XXX add_dir subtree 2 step %s \n%!" step ; + add_hash batch sub_tree [step] hash in let* o = Seq_es.fold_left_s add (Some (Store.Tree.empty ())) l in match o with | None -> return_none | Some tree -> + Fmt.epr "XXX add_dir save tree 2 \n%!" ; let (Batch (repo, x, y)) = batch in (* Save the node in the store ... *) let*! _ = Store.save_tree ~clear:true repo x y tree in diff --git a/src/lib_context/context_dump.ml b/src/lib_context/context_dump.ml index 9900f93275..ad8b210170 100644 --- a/src/lib_context/context_dump.ml +++ b/src/lib_context/context_dump.ml @@ -245,6 +245,7 @@ module Make_legacy (I : Dump_interface) = struct | 'n' -> let* s = get_int4 rbuf in let list_size = Int32.to_int s in + Fmt.epr "XXX list_size %d \n%!" list_size ; let data = read_seq rbuf list_size in Lwt.return_ok (Node_seq data) | _ -> fail Restore_context_failure @@ -252,11 +253,13 @@ module Make_legacy (I : Dump_interface) = struct (* Restoring *) let restore_context_fd index ~expected_context_hash ~fd ~nb_context_elements = + Fmt.epr "XXX restore legacy\n%!" ; let open Lwt_tzresult_syntax in let read = ref 0 in let rbuf = ref (fd, Bytes.empty, 0, read) in (* Editing the repository *) let add_blob t blob = + Fmt.epr "XXX add blob %S\n%!" (Bytes.to_string blob) ; let*! tree = I.add_bytes t blob in return tree in @@ -267,10 +270,12 @@ module Make_legacy (I : Dump_interface) = struct in let restore () = let first_pass () = + Fmt.epr "XXX first pass \n%!" ; let* r = get_command rbuf in match r with Root -> return_unit | _ -> fail Inconsistent_context_dump in let rec second_pass batch ctxt context_hash notify = + Fmt.epr "XXX second_pass \n%!" ; let*! () = notify () in let* c = get_command rbuf in match c with @@ -476,6 +481,7 @@ module Make (I : Dump_interface) = struct (* Restoring *) let restore_context_fd index ~expected_context_hash ~fd ~nb_context_elements = + Fmt.epr "XXX restore current\n%!" ; let open Lwt_tzresult_syntax in let read = ref 0 in let rbuf = ref (fd, Bytes.empty, 0, read) in