diff --git a/src/proto_alpha/bin_sc_rollup_node/commitment.ml b/src/proto_alpha/bin_sc_rollup_node/commitment.ml index f8a7ae4766f1b972791562bac29560427227949a..df12f12decc6371fad9f84c720c48073a4b62c07 100644 --- a/src/proto_alpha/bin_sc_rollup_node/commitment.ml +++ b/src/proto_alpha/bin_sc_rollup_node/commitment.ml @@ -121,7 +121,7 @@ let last_commitment_hash (module Last_commitment_level : Mutable_level_store) let+ last_commitment = last_commitment (module Last_commitment_level) store in match last_commitment with | Some commitment -> Sc_rollup.Commitment.hash commitment - | None -> Sc_rollup.Commitment_hash.zero + | None -> Sc_rollup.Commitment.Hash.zero let must_store_commitment ~origination_level current_level store = let open Lwt_result_syntax in @@ -306,7 +306,7 @@ module Make (PVM : Pvm.S) : S with module PVM = PVM = struct if check_lcc_hash then let open Lwt_syntax in let* lcc_hash = Store.Last_cemented_commitment_hash.get store in - if Sc_rollup.Commitment_hash.equal lcc_hash commitment.predecessor + if Sc_rollup.Commitment.Hash.equal lcc_hash commitment.predecessor then return () else let+ () = diff --git a/src/proto_alpha/bin_sc_rollup_node/commitment.mli b/src/proto_alpha/bin_sc_rollup_node/commitment.mli index 5bc76990bf682e841c5e92b6aa1430cc61f7ba5d..d90ce876b486947ca50b99e6d72a869ce720215f 100644 --- a/src/proto_alpha/bin_sc_rollup_node/commitment.mli +++ b/src/proto_alpha/bin_sc_rollup_node/commitment.mli @@ -57,7 +57,7 @@ module type Mutable_level_store = val last_commitment_with_hash : (module Mutable_level_store) -> Store.t -> - (Sc_rollup.Commitment.t * Sc_rollup.Commitment_hash.t) option Lwt.t + (Sc_rollup.Commitment.t * Sc_rollup.Commitment.Hash.t) option Lwt.t module type S = sig module PVM : Pvm.S diff --git a/src/proto_alpha/bin_sc_rollup_node/commitment_event.ml b/src/proto_alpha/bin_sc_rollup_node/commitment_event.ml index edb8daa915a0b6114be699b1aaf355b4db821f32..a73fe2390322b7657376fc6628c1be6fdaba42ff 100644 --- a/src/proto_alpha/bin_sc_rollup_node/commitment_event.ml +++ b/src/proto_alpha/bin_sc_rollup_node/commitment_event.ml @@ -87,7 +87,7 @@ module Simple = struct ~name ~msg ~level:Notice - ("predecessor", Sc_rollup.Commitment_hash.encoding) + ("predecessor", Sc_rollup.Commitment.Hash.encoding) ("inbox_level", Raw_level.encoding) ("compressed_state", Sc_rollup.State_hash.encoding) ("number_of_messages", Sc_rollup.Number_of_messages.encoding) @@ -121,7 +121,7 @@ module Simple = struct number_of_ticks: {number_of_ticks}" ~level:Notice ("lcc_level", Raw_level.encoding) - ("predecessor", Sc_rollup.Commitment_hash.encoding) + ("predecessor", Sc_rollup.Commitment.Hash.encoding) ("inbox_level", Raw_level.encoding) ("compressed_state", Sc_rollup.State_hash.encoding) ("number_of_messages", Sc_rollup.Number_of_messages.encoding) @@ -135,7 +135,7 @@ module Simple = struct "Last cemented commitment was updated to hash {hash} at inbox level \ {level}" ~level:Notice - ("hash", Sc_rollup.Commitment_hash.encoding) + ("hash", Sc_rollup.Commitment.Hash.encoding) ("level", Raw_level.encoding) let compute_commitment = @@ -160,8 +160,8 @@ module Simple = struct terminated." ~level:Fatal ("level", Raw_level.encoding) - ("predecessor_hash", Sc_rollup.Commitment_hash.encoding) - ("lcc_hash", Sc_rollup.Commitment_hash.encoding) + ("predecessor_hash", Sc_rollup.Commitment.Hash.encoding) + ("lcc_hash", Sc_rollup.Commitment.Hash.encoding) let commitment_stored = commitment_event `Store diff --git a/src/proto_alpha/bin_sc_rollup_node/store.ml b/src/proto_alpha/bin_sc_rollup_node/store.ml index 733bf2b3c1c781c5bb4a57111f309f33de779049..e49a8b3d31e57615da1d07e679813e6e1662bb0d 100644 --- a/src/proto_alpha/bin_sc_rollup_node/store.ml +++ b/src/proto_alpha/bin_sc_rollup_node/store.ml @@ -297,13 +297,13 @@ module Commitments = Make_append_only_map (struct let string_of_key l = Int32.to_string @@ Raw_level.to_int32 l - type value = Sc_rollup.Commitment.t * Sc_rollup.Commitment_hash.t + type value = Sc_rollup.Commitment.t * Sc_rollup.Commitment.Hash.t let value_encoding = Data_encoding.( obj2 (req "commitment" Sc_rollup.Commitment.encoding) - (req "hash" Sc_rollup.Commitment_hash.encoding)) + (req "hash" Sc_rollup.Commitment.Hash.encoding)) end) module Last_stored_commitment_level = Make_mutable_value (struct @@ -333,9 +333,9 @@ end) module Last_cemented_commitment_hash = Make_mutable_value (struct let path = ["commitments"; "last_cemented_commitment"; "hash"] - type value = Sc_rollup.Commitment_hash.t + type value = Sc_rollup.Commitment.Hash.t - let value_encoding = Sc_rollup.Commitment_hash.encoding + let value_encoding = Sc_rollup.Commitment.Hash.encoding end) module Commitments_published_at_level = Make_append_only_map (struct @@ -343,9 +343,9 @@ module Commitments_published_at_level = Make_append_only_map (struct let keep_last_n_entries_in_memory = 10 - type key = Sc_rollup.Commitment_hash.t + type key = Sc_rollup.Commitment.Hash.t - let string_of_key = Sc_rollup.Commitment_hash.to_b58check + let string_of_key = Sc_rollup.Commitment.Hash.to_b58check type value = Raw_level.t diff --git a/src/proto_alpha/lib_benchmarks_proto/sc_rollup_benchmarks.ml b/src/proto_alpha/lib_benchmarks_proto/sc_rollup_benchmarks.ml index ffe9c75e8d4f85c0ee3dac5831573f9f111ac49d..ef87fd2612e821388097257619c03ac0005c7872 100644 --- a/src/proto_alpha/lib_benchmarks_proto/sc_rollup_benchmarks.ml +++ b/src/proto_alpha/lib_benchmarks_proto/sc_rollup_benchmarks.ml @@ -105,7 +105,8 @@ module Sc_rollup_update_num_and_size_of_messages_benchmark = struct let workload = () in let closure () = ignore - (Sc_rollup_storage.Internal.update_num_and_size_of_messages + (Sc_rollup_inbox_storage.Internal_for_tests + .update_num_and_size_of_messages ~num_messages ~total_messages_size new_message) @@ -217,7 +218,7 @@ module Sc_rollup_add_messages_benchmark = struct let open Lwt_result_syntax in let+ inbox, _, ctxt = Lwt.map Environment.wrap_tzresult - @@ Sc_rollup_storage.add_messages ctxt rollup ["CAFEBABE"] + @@ Sc_rollup_inbox_storage.add_messages ctxt rollup ["CAFEBABE"] in let ctxt = Raw_context.Internal_for_tests.add_level ctxt 1 in (inbox, ctxt) diff --git a/src/proto_alpha/lib_client/client_proto_context.mli b/src/proto_alpha/lib_client/client_proto_context.mli index 3d877d23cf0c7602539f03dc6be63547a8fb4536..ebdc18a4b067bd69fcc1cb84ae4097ccaf401da5 100644 --- a/src/proto_alpha/lib_client/client_proto_context.mli +++ b/src/proto_alpha/lib_client/client_proto_context.mli @@ -727,7 +727,7 @@ val sc_rollup_cement : ?counter:counter -> source:public_key_hash -> rollup:Alpha_context.Sc_rollup.t -> - commitment:Alpha_context.Sc_rollup.Commitment_hash.t -> + commitment:Alpha_context.Sc_rollup.Commitment.Hash.t -> src_pk:public_key -> src_sk:Client_keys.sk_uri -> fee_parameter:Injection.fee_parameter -> diff --git a/src/proto_alpha/lib_client/operation_result.ml b/src/proto_alpha/lib_client/operation_result.ml index 010cc7807b9849c0777633b2860dbe7a71a9d812..63a9ce79e43e6ee48c0f6503d9520c46a3af863c 100644 --- a/src/proto_alpha/lib_client/operation_result.ml +++ b/src/proto_alpha/lib_client/operation_result.ml @@ -286,7 +286,7 @@ let pp_manager_operation_content (type kind) source pp_result ppf Format.fprintf ppf "Cement the commitment %a in the smart contract rollup at address %a" - Sc_rollup.Commitment_hash.pp + Sc_rollup.Commitment.Hash.pp commitment Sc_rollup.Address.pp rollup @@ -672,7 +672,7 @@ let pp_manager_operation_contents_and_result ppf Format.fprintf ppf "@,Hash of commit: %a" - Sc_rollup.Commitment_hash.pp + Sc_rollup.Commitment.Hash.pp staked_hash ; Format.fprintf ppf 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 0eb0a727a19805a96129e66c396790a17276ebd6..8cd350191465b2c0d797c64d9df14e9d583f807e 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 @@ -119,7 +119,7 @@ let messages_param = let commitment_hash_param = Clic.parameter (fun _ commitment_hash -> - match Sc_rollup.Commitment_hash.of_b58check_opt commitment_hash with + match Sc_rollup.Commitment.Hash.of_b58check_opt commitment_hash with | None -> failwith "Parameter '%s' is not a valid B58-encoded rollup commitment hash" diff --git a/src/proto_alpha/lib_plugin/plugin.ml b/src/proto_alpha/lib_plugin/plugin.ml index bdf3405ff4c166276fb063fd6931e669426a224c..fdcd7aa054a486a2051b3639c3f6fd6f5ad6ebd8 100644 --- a/src/proto_alpha/lib_plugin/plugin.ml +++ b/src/proto_alpha/lib_plugin/plugin.ml @@ -3374,7 +3374,7 @@ module RPC = struct ~query:RPC_query.empty ~output: (obj2 - (req "hash" Sc_rollup.Commitment_hash.encoding) + (req "hash" Sc_rollup.Commitment.Hash.encoding) (req "level" Raw_level.encoding)) RPC_path.( path /: Sc_rollup.Address.rpc_arg @@ -3387,7 +3387,7 @@ module RPC = struct ~output:Sc_rollup.Commitment.encoding RPC_path.( path /: Sc_rollup.Address.rpc_arg / "commitment" - /: Sc_rollup.Commitment_hash.rpc_arg) + /: Sc_rollup.Commitment.Hash.rpc_arg) let root = RPC_service.get_service @@ -3406,7 +3406,8 @@ module RPC = struct "@[Context level at RPC time at %a@]@." Level.pp (Level.current ctxt) ; - Sc_rollup.inbox ctxt rollup >>=? fun (inbox, _ctxt) -> return inbox) + Sc_rollup.Inbox.inbox ctxt rollup >>=? fun (inbox, _ctxt) -> + return inbox) let register_kind () = Registration.opt_register1 ~chunked:true S.kind @@ -3430,7 +3431,8 @@ module RPC = struct @@ fun ctxt address () () -> let open Lwt_tzresult_syntax in let+ last_cemented_commitment, level, _ctxt = - Alpha_context.Sc_rollup.last_cemented_commitment_hash_with_level + Alpha_context.Sc_rollup.Commitment + .last_cemented_commitment_hash_with_level ctxt address in @@ -3441,7 +3443,10 @@ module RPC = struct @@ fun ctxt address commitment_hash () () -> let open Lwt_result_syntax in let+ commitment, _ = - Alpha_context.Sc_rollup.get_commitment ctxt address commitment_hash + Alpha_context.Sc_rollup.Commitment.get_commitment + ctxt + address + commitment_hash in commitment diff --git a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL index e7a9039bfa71930afdcc24d78c8bb79a4fe023f6..6d543cc1a6c0e8d5f8cb3261bd6ca9eb7aacc2f5 100644 --- a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL +++ b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL @@ -38,6 +38,7 @@ "Skip_list_repr", "Sc_rollup_inbox_repr", "Sc_rollup_tick_repr", + "Sc_rollup_commitment_repr", "Sc_rollup_game_repr", "Seed_repr", "Sampler", @@ -132,6 +133,11 @@ "Tx_rollup_commitment_storage", "Tx_rollup_storage", "Sc_rollup_costs", + "Sc_rollup_errors", + "Sc_rollup_commitment_storage", + "Sc_rollup_inbox_storage", + "Sc_rollup_stake_storage", + "Sc_rollup_refutation_storage", "Sc_rollup_storage", "Alpha_context", diff --git a/src/proto_alpha/lib_protocol/alpha_context.ml b/src/proto_alpha/lib_protocol/alpha_context.ml index b963576c8f14f8a3541fa82182dd2817e05d1bc4..a8171c397beb50802e8474285286da5a928c09cf 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.ml +++ b/src/proto_alpha/lib_protocol/alpha_context.ml @@ -55,8 +55,21 @@ module Slot = Slot_repr module Sc_rollup = struct module Tick = Sc_rollup_tick_repr include Sc_rollup_repr - module Inbox = Sc_rollup_inbox_repr + + module Inbox = struct + include Sc_rollup_inbox_repr + include Sc_rollup_inbox_storage + end + module Game = Sc_rollup_game_repr + + module Commitment = struct + include Sc_rollup_commitment_repr + include Sc_rollup_commitment_storage + end + + module Stake_storage = Sc_rollup_stake_storage + module Refutation_storage = Sc_rollup_refutation_storage include Sc_rollup_storage end diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index acf779d9bf9dbf08955091d61b97639697c2c2ef..6e8973dd89270586321734df44f764a60016a127 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -2474,6 +2474,8 @@ module Sc_rollup : sig type t = Address.t + type rollup := t + module Kind : sig type t = Example_arith @@ -2483,8 +2485,6 @@ module Sc_rollup : sig module Staker : S.SIGNATURE_PUBLIC_KEY_HASH with type t = Signature.Public_key_hash.t - module Commitment_hash : S.HASH - module State_hash : S.HASH module Number_of_messages : Bounded.Int32.S @@ -2492,10 +2492,12 @@ module Sc_rollup : sig module Number_of_ticks : Bounded.Int32.S module Commitment : sig + module Hash : S.HASH + type t = { compressed_state : State_hash.t; inbox_level : Raw_level.t; - predecessor : Commitment_hash.t; + predecessor : Hash.t; number_of_messages : Number_of_messages.t; number_of_ticks : Number_of_ticks.t; } @@ -2504,7 +2506,13 @@ module Sc_rollup : sig val pp : Format.formatter -> t -> unit - val hash : t -> Commitment_hash.t + val hash : t -> Hash.t + + val get_commitment : + context -> rollup -> Hash.t -> (t * context) tzresult Lwt.t + + val last_cemented_commitment_hash_with_level : + context -> rollup -> (Hash.t * Raw_level.t * context) tzresult Lwt.t end val originate : @@ -2599,6 +2607,11 @@ module Sc_rollup : sig module MakeHashingScheme (Tree : TREE) : MerkelizedOperations with type tree = Tree.tree + + val add_messages : + context -> rollup -> string list -> (t * Z.t * context) tzresult Lwt.t + + val inbox : context -> rollup -> (t * context) tzresult Lwt.t end module Game : sig @@ -2655,47 +2668,44 @@ module Sc_rollup : sig val outcome_encoding : outcome Data_encoding.t end - val rpc_arg : t RPC_arg.t - - val add_messages : - context -> t -> string list -> (Inbox.t * Z.t * context) tzresult Lwt.t - - val inbox : context -> t -> (Inbox.t * context) tzresult Lwt.t - - val deposit_stake : context -> t -> Staker.t -> context tzresult Lwt.t - - val withdraw_stake : context -> t -> Staker.t -> context tzresult Lwt.t - - val refine_stake : - context -> - t -> - Staker.t -> - Commitment.t -> - (Commitment_hash.t * Raw_level.t * context) tzresult Lwt.t + module Stake_storage : sig + val publish_commitment : + context -> + t -> + Staker.t -> + Commitment.t -> + (Commitment.Hash.t * Raw_level.t * context) tzresult Lwt.t - val publish_commitment : - context -> - t -> - Staker.t -> - Commitment.t -> - (Commitment_hash.t * Raw_level.t * context) tzresult Lwt.t + val cement_commitment : + context -> t -> Commitment.Hash.t -> context tzresult Lwt.t + end - val cement_commitment : - context -> t -> Commitment_hash.t -> context tzresult Lwt.t + module Refutation_storage : sig + type conflict_point = Commitment.Hash.t * Commitment.Hash.t - type conflict_point = Commitment_hash.t * Commitment_hash.t + val update_game : + context -> + t -> + player:Staker.t -> + opponent:Staker.t -> + Game.refutation -> + (Game.outcome option * context) tzresult Lwt.t - val get_conflict_point : - context -> - t -> - Staker.t -> - Staker.t -> - (conflict_point * context) tzresult Lwt.t + val timeout : + context -> + t -> + Staker.t * Staker.t -> + (Game.outcome * context) tzresult Lwt.t - val get_commitment : - context -> t -> Commitment_hash.t -> (Commitment.t * context) tzresult Lwt.t + val apply_outcome : + context -> + t -> + Staker.t * Staker.t -> + Game.outcome -> + (Game.status * context) tzresult Lwt.t + end - val remove_staker : context -> t -> Staker.t -> context tzresult Lwt.t + val rpc_arg : t RPC_arg.t val list : context -> t list tzresult Lwt.t @@ -2703,37 +2713,6 @@ module Sc_rollup : sig val get_boot_sector : context -> t -> string tzresult Lwt.t - val last_cemented_commitment_hash_with_level : - context -> t -> (Commitment_hash.t * Raw_level.t * context) tzresult Lwt.t - - val get_or_init_game : - context -> - t -> - refuter:Staker.t -> - defender:Staker.t -> - (Game.t * context) tzresult Lwt.t - - val update_game : - context -> - t -> - player:Staker.t -> - opponent:Staker.t -> - Game.refutation -> - (Game.outcome option * context) tzresult Lwt.t - - val timeout : - context -> - t -> - Staker.t * Staker.t -> - (Game.outcome * context) tzresult Lwt.t - - val apply_outcome : - context -> - t -> - Staker.t * Staker.t -> - Game.outcome -> - (Game.status * context) tzresult Lwt.t - module Outbox : sig val record_applied_message : context -> @@ -3143,7 +3122,7 @@ and _ manager_operation = -> Kind.sc_rollup_add_messages manager_operation | Sc_rollup_cement : { rollup : Sc_rollup.t; - commitment : Sc_rollup.Commitment_hash.t; + commitment : Sc_rollup.Commitment.Hash.t; } -> Kind.sc_rollup_cement manager_operation | Sc_rollup_publish : { diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index f0109168a3f403767bbc20e30009ccfd8431e087..133c64727254c34cecd981f830d1c92dadb03758 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -1743,18 +1743,19 @@ let apply_external_manager_operation_content : in return (ctxt, result, []) | Sc_rollup_add_messages {rollup; messages} -> - Sc_rollup.add_messages ctxt rollup messages + Sc_rollup.Inbox.add_messages ctxt rollup messages >>=? fun (inbox_after, _size, ctxt) -> let consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt in let result = Sc_rollup_add_messages_result {consumed_gas; inbox_after} in return (ctxt, result, []) | Sc_rollup_cement {rollup; commitment} -> - Sc_rollup.cement_commitment ctxt rollup commitment >>=? fun ctxt -> + Sc_rollup.Stake_storage.cement_commitment ctxt rollup commitment + >>=? fun ctxt -> let consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt in let result = Sc_rollup_cement_result {consumed_gas} in return (ctxt, result, []) | Sc_rollup_publish {rollup; commitment} -> - Sc_rollup.publish_commitment ctxt rollup source commitment + Sc_rollup.Stake_storage.publish_commitment ctxt rollup source commitment >>=? fun (staked_hash, published_at_level, ctxt) -> let consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt in let result = @@ -1762,18 +1763,29 @@ let apply_external_manager_operation_content : in return (ctxt, result, []) | Sc_rollup_refute {rollup; opponent; refutation} -> - Sc_rollup.update_game ctxt rollup ~player:source ~opponent refutation + Sc_rollup.Refutation_storage.update_game + ctxt + rollup + ~player:source + ~opponent + refutation >>=? fun (outcome, ctxt) -> (match outcome with | None -> return (Sc_rollup.Game.Ongoing, ctxt) - | Some o -> Sc_rollup.apply_outcome ctxt rollup (source, opponent) o) + | Some o -> + Sc_rollup.Refutation_storage.apply_outcome + ctxt + rollup + (source, opponent) + o) >>=? fun (status, ctxt) -> let consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt in let result = Sc_rollup_refute_result {status; consumed_gas} in return (ctxt, result, []) | Sc_rollup_timeout {rollup; stakers} -> - Sc_rollup.timeout ctxt rollup stakers >>=? fun (outcome, ctxt) -> - Sc_rollup.apply_outcome ctxt rollup stakers outcome + Sc_rollup.Refutation_storage.timeout ctxt rollup stakers + >>=? fun (outcome, ctxt) -> + Sc_rollup.Refutation_storage.apply_outcome ctxt rollup stakers outcome >>=? fun (status, ctxt) -> let consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt in let result = Sc_rollup_timeout_result {status; consumed_gas} in diff --git a/src/proto_alpha/lib_protocol/apply_results.ml b/src/proto_alpha/lib_protocol/apply_results.ml index 558bbbc9a2049725a868af79152085f99b3d45e3..bd9911b11ee510bd1f704edac24bc829994e093c 100644 --- a/src/proto_alpha/lib_protocol/apply_results.ml +++ b/src/proto_alpha/lib_protocol/apply_results.ml @@ -227,7 +227,7 @@ type _ successful_manager_operation_result = -> Kind.sc_rollup_cement successful_manager_operation_result | Sc_rollup_publish_result : { consumed_gas : Gas.Arith.fp; - staked_hash : Sc_rollup.Commitment_hash.t; + staked_hash : Sc_rollup.Commitment.Hash.t; published_at_level : Raw_level.t; } -> Kind.sc_rollup_publish successful_manager_operation_result @@ -951,7 +951,7 @@ module Manager_result = struct (obj4 (req "consumed_gas" Gas.Arith.n_integral_encoding) (dft "consumed_milligas" Gas.Arith.n_fp_encoding Gas.Arith.zero) - (req "staked_hash" Sc_rollup.Commitment_hash.encoding) + (req "staked_hash" Sc_rollup.Commitment.Hash.encoding) (req "published_at_level" Raw_level.encoding)) ~select:(function | Successful_manager_result (Sc_rollup_publish_result _ as op) -> diff --git a/src/proto_alpha/lib_protocol/apply_results.mli b/src/proto_alpha/lib_protocol/apply_results.mli index 4b07cd755660d9be556153cc8402cbc6a7705d1c..bf62d799c485c2cceeedfb3a54a6b36ccc527c77 100644 --- a/src/proto_alpha/lib_protocol/apply_results.mli +++ b/src/proto_alpha/lib_protocol/apply_results.mli @@ -269,7 +269,7 @@ and _ successful_manager_operation_result = -> Kind.sc_rollup_cement successful_manager_operation_result | Sc_rollup_publish_result : { consumed_gas : Gas.Arith.fp; - staked_hash : Sc_rollup.Commitment_hash.t; + staked_hash : Sc_rollup.Commitment.Hash.t; published_at_level : Raw_level.t; } -> Kind.sc_rollup_publish successful_manager_operation_result diff --git a/src/proto_alpha/lib_protocol/dune b/src/proto_alpha/lib_protocol/dune index 9adad91359a23d8c02696c9d0e405c9973e986bc..77b107fe2f600ec087b1f9ace0b260321e1e4e86 100644 --- a/src/proto_alpha/lib_protocol/dune +++ b/src/proto_alpha/lib_protocol/dune @@ -69,6 +69,7 @@ Skip_list_repr Sc_rollup_inbox_repr Sc_rollup_tick_repr + Sc_rollup_commitment_repr Sc_rollup_game_repr Seed_repr Sampler @@ -156,6 +157,11 @@ Tx_rollup_commitment_storage Tx_rollup_storage Sc_rollup_costs + Sc_rollup_errors + Sc_rollup_commitment_storage + Sc_rollup_inbox_storage + Sc_rollup_stake_storage + Sc_rollup_refutation_storage Sc_rollup_storage Alpha_context Script_string @@ -275,6 +281,7 @@ skip_list_repr.ml skip_list_repr.mli sc_rollup_inbox_repr.ml sc_rollup_inbox_repr.mli sc_rollup_tick_repr.ml sc_rollup_tick_repr.mli + sc_rollup_commitment_repr.ml sc_rollup_commitment_repr.mli sc_rollup_game_repr.ml sc_rollup_game_repr.mli seed_repr.ml seed_repr.mli sampler.ml sampler.mli @@ -363,6 +370,11 @@ tx_rollup_commitment_storage.ml tx_rollup_commitment_storage.mli tx_rollup_storage.ml tx_rollup_storage.mli sc_rollup_costs.ml sc_rollup_costs.mli + sc_rollup_errors.ml + sc_rollup_commitment_storage.ml sc_rollup_commitment_storage.mli + sc_rollup_inbox_storage.ml sc_rollup_inbox_storage.mli + sc_rollup_stake_storage.ml sc_rollup_stake_storage.mli + sc_rollup_refutation_storage.ml sc_rollup_refutation_storage.mli sc_rollup_storage.ml sc_rollup_storage.mli alpha_context.ml alpha_context.mli script_string.ml script_string.mli @@ -468,6 +480,7 @@ skip_list_repr.ml skip_list_repr.mli sc_rollup_inbox_repr.ml sc_rollup_inbox_repr.mli sc_rollup_tick_repr.ml sc_rollup_tick_repr.mli + sc_rollup_commitment_repr.ml sc_rollup_commitment_repr.mli sc_rollup_game_repr.ml sc_rollup_game_repr.mli seed_repr.ml seed_repr.mli sampler.ml sampler.mli @@ -556,6 +569,11 @@ tx_rollup_commitment_storage.ml tx_rollup_commitment_storage.mli tx_rollup_storage.ml tx_rollup_storage.mli sc_rollup_costs.ml sc_rollup_costs.mli + sc_rollup_errors.ml + sc_rollup_commitment_storage.ml sc_rollup_commitment_storage.mli + sc_rollup_inbox_storage.ml sc_rollup_inbox_storage.mli + sc_rollup_stake_storage.ml sc_rollup_stake_storage.mli + sc_rollup_refutation_storage.ml sc_rollup_refutation_storage.mli sc_rollup_storage.ml sc_rollup_storage.mli alpha_context.ml alpha_context.mli script_string.ml script_string.mli @@ -682,6 +700,7 @@ skip_list_repr.ml skip_list_repr.mli sc_rollup_inbox_repr.ml sc_rollup_inbox_repr.mli sc_rollup_tick_repr.ml sc_rollup_tick_repr.mli + sc_rollup_commitment_repr.ml sc_rollup_commitment_repr.mli sc_rollup_game_repr.ml sc_rollup_game_repr.mli seed_repr.ml seed_repr.mli sampler.ml sampler.mli @@ -770,6 +789,11 @@ tx_rollup_commitment_storage.ml tx_rollup_commitment_storage.mli tx_rollup_storage.ml tx_rollup_storage.mli sc_rollup_costs.ml sc_rollup_costs.mli + sc_rollup_errors.ml + sc_rollup_commitment_storage.ml sc_rollup_commitment_storage.mli + sc_rollup_inbox_storage.ml sc_rollup_inbox_storage.mli + sc_rollup_stake_storage.ml sc_rollup_stake_storage.mli + sc_rollup_refutation_storage.ml sc_rollup_refutation_storage.mli sc_rollup_storage.ml sc_rollup_storage.mli alpha_context.ml alpha_context.mli script_string.ml script_string.mli @@ -891,6 +915,7 @@ skip_list_repr.ml skip_list_repr.mli sc_rollup_inbox_repr.ml sc_rollup_inbox_repr.mli sc_rollup_tick_repr.ml sc_rollup_tick_repr.mli + sc_rollup_commitment_repr.ml sc_rollup_commitment_repr.mli sc_rollup_game_repr.ml sc_rollup_game_repr.mli seed_repr.ml seed_repr.mli sampler.ml sampler.mli @@ -979,6 +1004,11 @@ tx_rollup_commitment_storage.ml tx_rollup_commitment_storage.mli tx_rollup_storage.ml tx_rollup_storage.mli sc_rollup_costs.ml sc_rollup_costs.mli + sc_rollup_errors.ml + sc_rollup_commitment_storage.ml sc_rollup_commitment_storage.mli + sc_rollup_inbox_storage.ml sc_rollup_inbox_storage.mli + sc_rollup_stake_storage.ml sc_rollup_stake_storage.mli + sc_rollup_refutation_storage.ml sc_rollup_refutation_storage.mli sc_rollup_storage.ml sc_rollup_storage.mli alpha_context.ml alpha_context.mli script_string.ml script_string.mli diff --git a/src/proto_alpha/lib_protocol/operation_repr.ml b/src/proto_alpha/lib_protocol/operation_repr.ml index 8ef16e43aa490ffaed7e6814aa5650980539b362..13f51ca5cfd444d31645486dd39069f49595728d 100644 --- a/src/proto_alpha/lib_protocol/operation_repr.ml +++ b/src/proto_alpha/lib_protocol/operation_repr.ml @@ -370,12 +370,12 @@ and _ manager_operation = -> Kind.sc_rollup_add_messages manager_operation | Sc_rollup_cement : { rollup : Sc_rollup_repr.t; - commitment : Sc_rollup_repr.Commitment_hash.t; + commitment : Sc_rollup_commitment_repr.Hash.t; } -> Kind.sc_rollup_cement manager_operation | Sc_rollup_publish : { rollup : Sc_rollup_repr.t; - commitment : Sc_rollup_repr.Commitment.t; + commitment : Sc_rollup_commitment_repr.t; } -> Kind.sc_rollup_publish manager_operation | Sc_rollup_refute : { @@ -954,7 +954,7 @@ module Encoding = struct encoding = obj2 (req "rollup" Sc_rollup_repr.encoding) - (req "commitment" Sc_rollup_repr.Commitment_hash.encoding); + (req "commitment" Sc_rollup_commitment_repr.Hash.encoding); select = (function | Manager (Sc_rollup_cement _ as op) -> Some op | _ -> None); @@ -973,7 +973,7 @@ module Encoding = struct encoding = obj2 (req "rollup" Sc_rollup_repr.encoding) - (req "commitment" Sc_rollup_repr.Commitment.encoding); + (req "commitment" Sc_rollup_commitment_repr.encoding); select = (function | Manager (Sc_rollup_publish _ 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 ea7364d46c75ed816f3646b4b342be10649ad708..8ea799d96b510e80bc95010eb852b35316298910 100644 --- a/src/proto_alpha/lib_protocol/operation_repr.mli +++ b/src/proto_alpha/lib_protocol/operation_repr.mli @@ -439,12 +439,12 @@ and _ manager_operation = -> Kind.sc_rollup_add_messages manager_operation | Sc_rollup_cement : { rollup : Sc_rollup_repr.t; - commitment : Sc_rollup_repr.Commitment_hash.t; + commitment : Sc_rollup_commitment_repr.Hash.t; } -> Kind.sc_rollup_cement manager_operation | Sc_rollup_publish : { rollup : Sc_rollup_repr.t; - commitment : Sc_rollup_repr.Commitment.t; + commitment : Sc_rollup_commitment_repr.t; } -> Kind.sc_rollup_publish manager_operation | Sc_rollup_refute : { diff --git a/src/proto_alpha/lib_protocol/sc_rollup_commitment_repr.ml b/src/proto_alpha/lib_protocol/sc_rollup_commitment_repr.ml new file mode 100644 index 0000000000000000000000000000000000000000..b48a0f308d4df79345f3fb6f42b32f1b9db34a02 --- /dev/null +++ b/src/proto_alpha/lib_protocol/sc_rollup_commitment_repr.ml @@ -0,0 +1,129 @@ +(*****************************************************************************) +(* *) +(* 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. *) +(* *) +(*****************************************************************************) + +open Sc_rollup_repr + +(* 32 *) +let hash_prefix = "\017\144\021\100" (* scc1(54) *) + +module Hash = struct + let prefix = "scc1" + + let encoded_size = 54 + + module H = + Blake2B.Make + (Base58) + (struct + let name = "commitment_hash" + + let title = "The hash of a commitment of a smart contract rollup" + + let b58check_prefix = hash_prefix + + (* defaults to 32 *) + let size = None + end) + + include H + + let () = Base58.check_encoded_prefix b58check_encoding prefix encoded_size + + include Path_encoding.Make_hex (H) +end + +module Hash_index = struct + include Hash +end + +type t = { + compressed_state : State_hash.t; + inbox_level : Raw_level_repr.t; + predecessor : Hash.t; + number_of_messages : Number_of_messages.t; + number_of_ticks : Number_of_ticks.t; +} + +let pp fmt + { + compressed_state; + inbox_level; + predecessor; + number_of_messages; + number_of_ticks; + } = + Format.fprintf + fmt + "@[SCORU Commitment:@ compressed_state: %a@ inbox_level: %a@ \ + predecessor: %a@ number_of_messages: %ld@ number_of_ticks: %ld@]" + State_hash.pp + compressed_state + Raw_level_repr.pp + inbox_level + Hash.pp + predecessor + (Number_of_messages.to_int32 number_of_messages) + (Number_of_ticks.to_int32 number_of_ticks) + +let encoding = + let open Data_encoding in + conv + (fun { + compressed_state; + inbox_level; + predecessor; + number_of_messages; + number_of_ticks; + } -> + ( compressed_state, + inbox_level, + predecessor, + number_of_messages, + number_of_ticks )) + (fun ( compressed_state, + inbox_level, + predecessor, + number_of_messages, + number_of_ticks ) -> + { + compressed_state; + inbox_level; + predecessor; + number_of_messages; + number_of_ticks; + }) + (obj5 + (req "compressed_state" State_hash.encoding) + (req "inbox_level" Raw_level_repr.encoding) + (req "predecessor" Hash.encoding) + (req "number_of_messages" Number_of_messages.encoding) + (req "number_of_ticks" Number_of_ticks.encoding)) + +let hash commitment = + let commitment_bytes = + Data_encoding.Binary.to_bytes_exn encoding commitment + in + Hash.hash_bytes [commitment_bytes] diff --git a/src/proto_alpha/lib_protocol/sc_rollup_commitment_repr.mli b/src/proto_alpha/lib_protocol/sc_rollup_commitment_repr.mli new file mode 100644 index 0000000000000000000000000000000000000000..bc2e848489e3491d47409f9f46e7c1cf81a6814b --- /dev/null +++ b/src/proto_alpha/lib_protocol/sc_rollup_commitment_repr.mli @@ -0,0 +1,69 @@ +(*****************************************************************************) +(* *) +(* 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. *) +(* *) +(*****************************************************************************) + +(** A commitment represents a claim about the state of the Inbox and PVM at + some Inbox level. + + More formally, a commitment is a claim that: + + {ul + {li assuming the PVM and Inbox are in a state implied by [predecessor]} + {li the PVM consumes [number_of_messages] messages tagged with + [inbox_level] from the Inbox} + {li the PVM advances to the state [compressed_state] over + [number_of_ticks] ticks } + } + + Commitments are disjoint. The next correct commitment is a function of the + previous machine state and Inbox. + + [number_of_messages] and [inbox_level] can be proven/disproven by Merkle + proofs on the Inbox state. + + [compressed_state] and [number_of_ticks] can be proven/disproven by PVM + execution, or equivalently, by an interactive proof game between + conflicting parties, such that a correct executor always wins the game. + *) + +open Sc_rollup_repr + +module Hash : S.HASH + +module Hash_index : Storage_description.INDEX with type t = Hash.t + +type t = { + compressed_state : State_hash.t; + inbox_level : Raw_level_repr.t; + predecessor : Hash.t; + number_of_messages : Number_of_messages.t; + number_of_ticks : Number_of_ticks.t; +} + +val pp : Format.formatter -> t -> unit + +val encoding : t Data_encoding.t + +val hash : t -> Hash.t diff --git a/src/proto_alpha/lib_protocol/sc_rollup_commitment_storage.ml b/src/proto_alpha/lib_protocol/sc_rollup_commitment_storage.ml new file mode 100644 index 0000000000000000000000000000000000000000..6d883a86f19ce79cd7566f981942023774663098 --- /dev/null +++ b/src/proto_alpha/lib_protocol/sc_rollup_commitment_storage.ml @@ -0,0 +1,80 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* Copyright (c) 2022 TriliTech *) +(* *) +(* 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. *) +(* *) +(*****************************************************************************) + +open Sc_rollup_errors +module Store = Storage.Sc_rollup +module Commitment = Sc_rollup_commitment_repr +module Commitment_hash = Commitment.Hash + +let get_commitment_unsafe ctxt rollup commitment = + let open Lwt_tzresult_syntax in + let* ctxt, res = Store.Commitments.find (ctxt, rollup) commitment in + match res with + | None -> fail (Sc_rollup_unknown_commitment commitment) + | Some commitment -> return (commitment, ctxt) + +let last_cemented_commitment ctxt rollup = + let open Lwt_tzresult_syntax in + let* ctxt, res = Store.Last_cemented_commitment.find ctxt rollup in + match res with + | None -> fail (Sc_rollup_does_not_exist rollup) + | Some lcc -> return (lcc, ctxt) + +let get_commitment ctxt rollup commitment = + let open Lwt_tzresult_syntax in + (* Assert that a last cemented commitment exists. *) + let* _lcc, ctxt = last_cemented_commitment ctxt rollup in + get_commitment_unsafe ctxt rollup commitment + +let last_cemented_commitment_hash_with_level ctxt rollup = + let open Lwt_tzresult_syntax in + let* commitment_hash, ctxt = last_cemented_commitment ctxt rollup in + if Commitment_hash.(commitment_hash = zero) then + let+ initial_level = Storage.Sc_rollup.Initial_level.get ctxt rollup in + (commitment_hash, initial_level, ctxt) + else + let+ {inbox_level; _}, ctxt = + get_commitment_unsafe ctxt rollup commitment_hash + in + (commitment_hash, inbox_level, ctxt) + +let set_commitment_added ctxt rollup node new_value = + let open Lwt_tzresult_syntax in + let* ctxt, res = Store.Commitment_added.find (ctxt, rollup) node in + match res with + | Some old_value -> + (* No need to re-add the read value *) + return (0, old_value, ctxt) + | None -> + let* ctxt, size_diff, _was_bound = + Store.Commitment_added.add (ctxt, rollup) node new_value + in + return (size_diff, new_value, ctxt) + +let get_predecessor_unsafe ctxt rollup node = + let open Lwt_tzresult_syntax in + let* commitment, ctxt = get_commitment_unsafe ctxt rollup node in + return (commitment.predecessor, ctxt) diff --git a/src/proto_alpha/lib_protocol/sc_rollup_commitment_storage.mli b/src/proto_alpha/lib_protocol/sc_rollup_commitment_storage.mli new file mode 100644 index 0000000000000000000000000000000000000000..39e713e3b6221cbed5510d1fe6e3a406dae08804 --- /dev/null +++ b/src/proto_alpha/lib_protocol/sc_rollup_commitment_storage.mli @@ -0,0 +1,197 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* Copyright (c) 2022 TriliTech *) +(* *) +(* 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. *) +(* *) +(*****************************************************************************) + +(** Defines storage for Smart Contract Optimistic Rollups. + + {2 Commitments} + + [Commitment]s are stored directly in the L1 context. Commitments are + immutable and content-addressed, and can be indexed by a [Commitment_hash]. + + A commitment represents a claim about the state of a PVM. + + We also keep auxiliary state about each commitment, namely: + + {ul + {li When it was first added.} + {li Its current number of stakers.} + } + + This auxiliary data is not part of the commitment itself. They represent + information that the L1 knows about the claim, not the claim itself. + + {3 Predecessors and Boot state} + Each commitment contains the hash of its {i predecessor}. Multiple + commitments can have the same predecessor. Therefore, commitments form + a Merkle tree. + + Conceptually the root of this tree is the [Commitment_hash.zero]. This + commitment claims that the PVM (Proof-generating Virtual Machine) is in a + pre-boot state and waiting to start booting by interpreting the boot sector with + respect to the Machine semantics. + + {3 Cemented and Disputable commitments} + Commitments accepted as true by the protocol are referred to as Cemented. + + {3 Stakers} + The Stakers table maps Stakers (implicit accounts) to commitments hashes. + + Let [Stakers(S)] mean "looking up the key S in [Stakers]". + + A staker [S] is directly staked on [C] if [Stakers(S) = C]. A staker [S] + is indirectly staked on [C] if [C] is an ancestor of [Stakers(S)] in the commitment tree. + + {3 Dispute} + Commitments that have at least one sibling are referred to as Disputed. + More formally, a commitment C is disputed if at least one staker is not + (directly or indirectly) staked on C. + + {3 Dispute resolution} + The rollup protocol ensures that all disputes are resolved before cementing + a commitment. Therefore, cemented commitments form a list rather than a tree. + + In the context we only store the Last Cemented Commitment (LCC), which is + by definition a descendant of [zero]. We also store all Disputable + commitments that have at least one Staker. + + For example, assuming the full set of commitments for a rollup + looks like this: + + {[ + LCC staker1 staker2 + | | | + | V | + V --c3 | + zero--c1 --c2--/ | + \ V + --c4------ c5 + ]} + then commitments [c2..c5] will be stored in the context. + + {3 Conflicts} + + Let Commitments(S) be the set of commitments directly staked on by staker S. + + Two stakers A and B are: + + {ul + {li In total agreement iff Commitments(A) = Commitments(B).} + {li In partial agreement iff either Commitments(A) ⊂ Commitments(B), or + Commitments(B) ⊂ Commitments(A).} + {li In conflict iff they are neither in total or partial agreement.}} + + We can further refine a conflict to note what they are in conflict about, + e.g. they may be in conflict about the inbox, about execution, or both. We + can resolve conflicts by first resolving the conflict about inbox, then + about execution (since execution is irrelevant if the inbox is not + correct). + *) + +module Commitment = Sc_rollup_commitment_repr +module Commitment_hash = Commitment.Hash + +(** [last_cemented_commitment context rollup] returns the last cemented + commitment of the rollup. + + If no commitments have been cemented, the rollup is said to be in a + pre-boot state, and [last_cemented_commitment = Commitment_hash.zero]. + + May fail with: + {ul + {li [Sc_rollup_does_not_exist] if [rollup] does not exist}} *) +val last_cemented_commitment : + Raw_context.t -> + Sc_rollup_repr.t -> + (Commitment_hash.t * Raw_context.t) tzresult Lwt.t + +(** [last_cemented_commitment_hash_with_level ctxt sc_rollup] returns the hash + and level of the last cemented commitment (lcc) for [sc_rollup]. If the + rollup exists but no lcc exists, the initial commitment + [Sc_rollup.Commitment.zero] together with the rollup origination level is + returned. + + May fail with: + {ul + {li [Sc_rollup_does_not_exist] if [rollup] does not exist}} +*) +val last_cemented_commitment_hash_with_level : + Raw_context.t -> + Sc_rollup_repr.t -> + (Commitment_hash.t * Raw_level_repr.t * Raw_context.t) tzresult Lwt.t + +(** [get_commitment context rollup commitment_hash] returns the commitment with + the given hash. + + May fail with: + {ul + {li [Sc_rollup_does_not_exist] if [rollup] does not exist} + {li [Sc_rollup_unknown_commitment] if [commitment] does not exist} + } +*) +val get_commitment : + Raw_context.t -> + Sc_rollup_repr.t -> + Commitment_hash.t -> + (Commitment.t * Raw_context.t) tzresult Lwt.t + +(** [get_commitment_unsafe context rollup commitment_hash] returns the commitment + with the given hash. + This function *must* be called only after they have checked for the existence + of the rollup, and therefore it is not ncessary for it to check for the + existence of the rollup again. Otherwise, use the safe function + {!get_commitment}. + + May fail with: + {ul + {li [Sc_rollup_unknown_commitment] if [commitment] does not exist} + } +*) +val get_commitment_unsafe : + Raw_context.t -> + Sc_rollup_repr.t -> + Commitment_hash.t -> + (Commitment.t * Raw_context.t) tzresult Lwt.t + +(** [set_commitment_added ctxt rollup node current] sets the commitment + addition time of [node] to [current] iff the commitment time was + not previously set, and leaves it unchanged otherwise. + *) +val set_commitment_added : + Raw_context.t -> + Sc_rollup_repr.t -> + Commitment_hash.t -> + Raw_level_repr.t -> + (int * Raw_level_repr.t * Raw_context.t) tzresult Lwt.t + +(** [get_predecessor_unsafe ctxt rollup commitment_hash] returns the [rollup] + commitment predecessor of [commitment_hash] in the [ctxt]. It is unsafe + as the current commitment is retrived using {!get_commitment_unsafe}. + It does not check for the existence of the [rollup]. *) +val get_predecessor_unsafe : + Raw_context.t -> + Sc_rollup_repr.t -> + Commitment_hash.t -> + (Commitment_hash.t * Raw_context.t) tzresult Lwt.t diff --git a/src/proto_alpha/lib_protocol/sc_rollup_errors.ml b/src/proto_alpha/lib_protocol/sc_rollup_errors.ml new file mode 100644 index 0000000000000000000000000000000000000000..16e43e641ae0d6e21049f6c99a8853f8d67c4e6d --- /dev/null +++ b/src/proto_alpha/lib_protocol/sc_rollup_errors.ml @@ -0,0 +1,292 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* Copyright (c) 2022 TriliTech *) +(* *) +(* 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 += + | (* `Temporary *) Sc_rollup_already_staked + | (* `Temporary *) Sc_rollup_disputed + | (* `Temporary *) Sc_rollup_does_not_exist of Sc_rollup_repr.t + | (* `Temporary *) Sc_rollup_no_conflict + | (* `Temporary *) Sc_rollup_no_stakers + | (* `Temporary *) Sc_rollup_not_staked + | (* `Temporary *) Sc_rollup_not_staked_on_lcc + | (* `Temporary *) Sc_rollup_parent_not_lcc + | (* `Temporary *) Sc_rollup_remove_lcc + | (* `Temporary *) Sc_rollup_staker_backtracked + | (* `Temporary *) Sc_rollup_too_far_ahead + | (* `Temporary *) Sc_rollup_too_recent + | (* `Temporary *) + Sc_rollup_unknown_commitment of + Sc_rollup_commitment_repr.Hash.t + | (* `Temporary *) Sc_rollup_bad_inbox_level + | (* `Temporary *) Sc_rollup_max_number_of_available_messages_reached + | (* `Temporary *) Sc_rollup_wrong_turn + | (* `Temporary *) Sc_rollup_no_game + | (* `Temporary *) Sc_rollup_staker_in_game + | (* `Temporary *) Sc_rollup_timeout_level_not_reached + | (* `Temporary *) + Sc_rollup_max_number_of_messages_reached_for_commitment_period + | (* `Temporary *) Sc_rollup_invalid_outbox_message_index + | (* `Temporary *) Sc_rollup_outbox_level_expired + | (* `Temporary *) Sc_rollup_outbox_message_already_applied + +let () = + register_error_kind + `Temporary + ~id:"Sc_rollup_max_number_of_available_messages_reached" + ~title:"Maximum number of available messages reached" + ~description:"Maximum number of available messages reached" + Data_encoding.unit + (function + | Sc_rollup_max_number_of_available_messages_reached -> Some () + | _ -> None) + (fun () -> Sc_rollup_max_number_of_available_messages_reached) ; + register_error_kind + `Temporary + ~id:"Sc_rollup_staker_in_game" + ~title:"Staker is already playing a game" + ~description:"Attempt to start a game where one staker is already busy" + Data_encoding.unit + (function Sc_rollup_staker_in_game -> Some () | _ -> None) + (fun () -> Sc_rollup_staker_in_game) ; + register_error_kind + `Temporary + ~id:"Sc_rollup_timeout_level_not_reached" + ~title:"Attempt to timeout game too early" + ~description:"Attempt to timeout game too early" + Data_encoding.unit + (function Sc_rollup_timeout_level_not_reached -> Some () | _ -> None) + (fun () -> Sc_rollup_timeout_level_not_reached) ; + register_error_kind + `Temporary + ~id:"Sc_rollup_no_game" + ~title:"Refutation game does not exist" + ~description:"Refutation game does not exist" + Data_encoding.unit + (function Sc_rollup_no_game -> Some () | _ -> None) + (fun () -> Sc_rollup_no_game) ; + register_error_kind + `Temporary + ~id:"Sc_rollup_wrong_turn" + ~title:"Attempt to play move but not staker's turn" + ~description:"Attempt to play move but not staker's turn" + Data_encoding.unit + (function Sc_rollup_wrong_turn -> Some () | _ -> None) + (fun () -> Sc_rollup_wrong_turn) ; + register_error_kind + `Temporary + ~id:"Sc_rollup_max_number_of_messages_reached_for_commitment_period" + ~title:"Maximum number of messages reached for commitment period" + ~description:"Maximum number of messages reached for commitment period" + Data_encoding.unit + (function + | Sc_rollup_max_number_of_messages_reached_for_commitment_period -> + Some () + | _ -> None) + (fun () -> Sc_rollup_max_number_of_messages_reached_for_commitment_period) ; + let description = "Already staked." in + register_error_kind + `Temporary + ~id:"Sc_rollup_already_staked" + ~title:"Already staked" + ~description + ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) + Data_encoding.empty + (function Sc_rollup_already_staked -> Some () | _ -> None) + (fun () -> Sc_rollup_already_staked) ; + let description = "Attempted to cement a disputed commitment." in + register_error_kind + `Temporary + ~id:"Sc_rollup_disputed" + ~title:"Commitment disputed" + ~description + ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) + Data_encoding.empty + (function Sc_rollup_disputed -> Some () | _ -> None) + (fun () -> Sc_rollup_disputed) ; + let description = "Attempted to use a rollup that has not been originated." in + register_error_kind + `Temporary + ~id:"Sc_rollup_does_not_exist" + ~title:"Rollup does not exist" + ~description + ~pp:(fun ppf x -> + Format.fprintf ppf "Rollup %a does not exist" Sc_rollup_repr.pp x) + Data_encoding.(obj1 (req "rollup" Sc_rollup_repr.encoding)) + (function Sc_rollup_does_not_exist x -> Some x | _ -> None) + (fun x -> Sc_rollup_does_not_exist x) ; + let description = "No conflict." in + register_error_kind + `Temporary + ~id:"Sc_rollup_no_conflict" + ~title:"No conflict" + ~description + ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) + Data_encoding.empty + (function Sc_rollup_no_conflict -> Some () | _ -> None) + (fun () -> Sc_rollup_no_conflict) ; + let description = "No stakers." in + register_error_kind + `Temporary + ~id:"Sc_rollup_no_stakers" + ~title:"No stakers" + ~description + ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) + Data_encoding.empty + (function Sc_rollup_no_stakers -> Some () | _ -> None) + (fun () -> Sc_rollup_no_stakers) ; + let description = "Unknown staker." in + register_error_kind + `Temporary + ~id:"Sc_rollup_not_staked" + ~title:"Unknown staker" + ~description + ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) + Data_encoding.empty + (function Sc_rollup_not_staked -> Some () | _ -> None) + (fun () -> Sc_rollup_not_staked) ; + let description = + "Attempted to withdraw while not staked on the last cemented commitment." + in + register_error_kind + `Temporary + ~id:"Sc_rollup_not_staked_on_lcc" + ~title:"Rollup not staked on LCC" + ~description + ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) + Data_encoding.empty + (function Sc_rollup_not_staked_on_lcc -> Some () | _ -> None) + (fun () -> Sc_rollup_not_staked_on_lcc) ; + let description = "Parent is not cemented." in + register_error_kind + `Temporary + ~id:"Sc_rollup_parent_not_lcc" + ~title:"Parent not cemented" + ~description + ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) + Data_encoding.empty + (function Sc_rollup_parent_not_lcc -> Some () | _ -> None) + (fun () -> Sc_rollup_parent_not_lcc) ; + let description = "Can not remove a cemented commitment." in + register_error_kind + `Temporary + ~id:"Sc_rollup_remove_lcc" + ~title:"Can not remove cemented" + ~description + ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) + Data_encoding.empty + (function Sc_rollup_remove_lcc -> Some () | _ -> None) + (fun () -> Sc_rollup_remove_lcc) ; + let description = "Staker backtracked." in + register_error_kind + `Temporary + ~id:"Sc_rollup_staker_backtracked" + ~title:"Staker backtracked" + ~description + ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) + Data_encoding.empty + (function Sc_rollup_staker_backtracked -> Some () | _ -> None) + (fun () -> Sc_rollup_staker_backtracked) ; + let description = + "Commitment is too far ahead of the last cemented commitment." + in + register_error_kind + `Temporary + ~id:"Sc_rollup_too_far_ahead" + ~title:"Commitment too far ahead" + ~description + ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) + Data_encoding.empty + (function Sc_rollup_too_far_ahead -> Some () | _ -> None) + (fun () -> Sc_rollup_too_far_ahead) ; + let description = + "Attempted to cement a commitment before its refutation deadline." + in + register_error_kind + `Temporary + ~id:"Sc_rollup_too_recent" + ~title:"Commitment too recent" + ~description + ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) + Data_encoding.empty + (function Sc_rollup_too_recent -> Some () | _ -> None) + (fun () -> Sc_rollup_too_recent) ; + let description = "Unknown commitment." in + register_error_kind + `Temporary + ~id:"Sc_rollup_unknown_commitment" + ~title:"Unknown commitment" + ~description + ~pp:(fun ppf x -> + Format.fprintf + ppf + "Commitment %a does not exist" + Sc_rollup_commitment_repr.Hash.pp + x) + Data_encoding.( + obj1 (req "commitment" Sc_rollup_commitment_repr.Hash.encoding)) + (function Sc_rollup_unknown_commitment x -> Some x | _ -> None) + (fun x -> Sc_rollup_unknown_commitment x) ; + let description = "Attempted to commit to a bad inbox level." in + register_error_kind + `Temporary + ~id:"Sc_rollup_bad_inbox_level" + ~title:"Committing to a bad inbox level" + ~description + ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) + Data_encoding.empty + (function Sc_rollup_bad_inbox_level -> Some () | _ -> None) + (fun () -> Sc_rollup_bad_inbox_level) ; + let description = "Invalid rollup outbox message index" in + register_error_kind + `Temporary + ~id:"Sc_rollup_invalid_outbox_message_index" + ~title:"Invalid rollup outbox message index" + ~description + ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) + Data_encoding.empty + (function Sc_rollup_invalid_outbox_message_index -> Some () | _ -> None) + (fun () -> Sc_rollup_invalid_outbox_message_index) ; + let description = "Outbox level expired" in + register_error_kind + `Temporary + ~id:"Sc_rollup_outbox_level_expired" + ~title:description + ~description + ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) + Data_encoding.empty + (function Sc_rollup_outbox_level_expired -> Some () | _ -> None) + (fun () -> Sc_rollup_outbox_level_expired) ; + let description = "Outbox message already applied" in + register_error_kind + `Temporary + ~id:"Sc_rollup_outbox_message_already_applied" + ~title:description + ~description + ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) + Data_encoding.empty + (function Sc_rollup_outbox_message_already_applied -> Some () | _ -> None) + (fun () -> Sc_rollup_outbox_message_already_applied) ; + () diff --git a/src/proto_alpha/lib_protocol/sc_rollup_game_repr.ml b/src/proto_alpha/lib_protocol/sc_rollup_game_repr.ml index a19767ff32aeeed6b3dc24275aa34afaf1a2c182..17070cd415fe814b2e0e0e6c51869a4b9d6a784c 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_game_repr.ml +++ b/src/proto_alpha/lib_protocol/sc_rollup_game_repr.ml @@ -216,8 +216,8 @@ module Index = struct match player with Alice -> alice | Bob -> bob end -let initial inbox ~(parent : Commitment.t) ~(child : Commitment.t) ~refuter - ~defender = +let initial inbox ~(parent : Sc_rollup_commitment_repr.t) + ~(child : Sc_rollup_commitment_repr.t) ~refuter ~defender = let alice, _ = Index.normalize (refuter, defender) in let alice_to_play = Staker.equal alice refuter in let tick = Sc_rollup_tick_repr.of_number_of_ticks child.number_of_ticks in diff --git a/src/proto_alpha/lib_protocol/sc_rollup_game_repr.mli b/src/proto_alpha/lib_protocol/sc_rollup_game_repr.mli index 4c2d81dcbc5b8161a8c92285c218e27afc2f5cd5..1addd9bc529ec841f724257d2b2c66e6d3ea56b8 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_game_repr.mli +++ b/src/proto_alpha/lib_protocol/sc_rollup_game_repr.mli @@ -266,8 +266,8 @@ end increment from that state to its successor. *) val initial : Sc_rollup_inbox_repr.t -> - parent:Commitment.t -> - child:Commitment.t -> + parent:Sc_rollup_commitment_repr.t -> + child:Sc_rollup_commitment_repr.t -> refuter:Staker.t -> defender:Staker.t -> t diff --git a/src/proto_alpha/lib_protocol/sc_rollup_inbox_storage.ml b/src/proto_alpha/lib_protocol/sc_rollup_inbox_storage.ml new file mode 100644 index 0000000000000000000000000000000000000000..9649492b9f139233609f9aaf047dd5effe485878 --- /dev/null +++ b/src/proto_alpha/lib_protocol/sc_rollup_inbox_storage.ml @@ -0,0 +1,140 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* Copyright (c) 2022 TriliTech *) +(* *) +(* 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. *) +(* *) +(*****************************************************************************) + +open Sc_rollup_errors +module Store = Storage.Sc_rollup + +let update_num_and_size_of_messages ~num_messages ~total_messages_size message = + (num_messages + 1, total_messages_size + String.length message) + +let inbox ctxt rollup = + let open Lwt_tzresult_syntax in + let* ctxt, res = Store.Inbox.find ctxt rollup in + match res with + | None -> fail (Sc_rollup_does_not_exist rollup) + | Some inbox -> return (inbox, ctxt) + +let assert_inbox_size_ok ctxt inbox extra_num_messages = + let next_size = + Z.add + (Sc_rollup_inbox_repr.number_of_available_messages inbox) + (Z.of_int extra_num_messages) + in + let max_size = Constants_storage.sc_rollup_max_available_messages ctxt in + fail_unless + Compare.Z.(next_size <= Z.of_int max_size) + Sc_rollup_max_number_of_available_messages_reached + +let assert_inbox_nb_messages_in_commitment_period inbox extra_messages = + let nb_messages_in_commitment_period = + Int64.add + (Sc_rollup_inbox_repr.number_of_messages_during_commitment_period inbox) + (Int64.of_int extra_messages) + in + let limit = Int64.of_int32 Sc_rollup_repr.Number_of_messages.max_int in + fail_when + Compare.Int64.(nb_messages_in_commitment_period > limit) + Sc_rollup_max_number_of_messages_reached_for_commitment_period + +let add_messages ctxt rollup messages = + let {Level_repr.level; _} = Raw_context.current_level ctxt in + let open Lwt_tzresult_syntax in + let open Raw_context in + let commitment_period = + Constants_storage.sc_rollup_commitment_period_in_blocks ctxt |> Int32.of_int + in + let* inbox, ctxt = inbox ctxt rollup in + let* num_messages, total_messages_size, ctxt = + List.fold_left_es + (fun (num_messages, total_messages_size, ctxt) message -> + let*? ctxt = + Raw_context.consume_gas + ctxt + Sc_rollup_costs.Constants.cost_update_num_and_size_of_messages + in + let num_messages, total_messages_size = + update_num_and_size_of_messages + ~num_messages + ~total_messages_size + message + in + return (num_messages, total_messages_size, ctxt)) + (0, 0, ctxt) + messages + in + let* () = assert_inbox_size_ok ctxt inbox num_messages in + let start = + Sc_rollup_inbox_repr.starting_level_of_current_commitment_period inbox + in + let freshness = Raw_level_repr.diff level start in + let inbox = + let open Int32 in + let open Compare.Int32 in + if freshness >= commitment_period then ( + let nb_periods = + to_int ((mul (div freshness commitment_period)) commitment_period) + in + let new_starting_level = Raw_level_repr.(add start nb_periods) in + assert (Raw_level_repr.(new_starting_level <= level)) ; + assert ( + rem (Raw_level_repr.diff new_starting_level start) commitment_period + = 0l) ; + Sc_rollup_inbox_repr.start_new_commitment_period inbox new_starting_level) + else inbox + in + let* () = assert_inbox_nb_messages_in_commitment_period inbox num_messages in + let inbox_level = Sc_rollup_inbox_repr.inbox_level inbox in + let* origination_level = Storage.Sc_rollup.Initial_level.get ctxt rollup in + let levels = + Int32.sub + (Raw_level_repr.to_int32 inbox_level) + (Raw_level_repr.to_int32 origination_level) + in + let*? current_messages, ctxt = + Sc_rollup_in_memory_inbox.current_messages ctxt rollup + in + let gas_cost_add_messages = + Sc_rollup_costs.cost_add_messages ~num_messages ~total_messages_size levels + in + let*? ctxt = Raw_context.consume_gas ctxt gas_cost_add_messages in + (* + Notice that the protocol is forgetful: it throws away the inbox + history. On the contrary, the history is stored by the rollup + node to produce inclusion proofs when needed. + *) + let* current_messages, inbox = + Sc_rollup_inbox_repr.( + add_messages_no_history inbox level messages current_messages) + in + let*? ctxt = + Sc_rollup_in_memory_inbox.set_current_messages ctxt rollup current_messages + in + let* ctxt, size = Store.Inbox.update ctxt rollup inbox in + return (inbox, Z.of_int size, ctxt) + +module Internal_for_tests = struct + let update_num_and_size_of_messages = update_num_and_size_of_messages +end diff --git a/src/proto_alpha/lib_protocol/sc_rollup_inbox_storage.mli b/src/proto_alpha/lib_protocol/sc_rollup_inbox_storage.mli new file mode 100644 index 0000000000000000000000000000000000000000..607bf8540626122cf6c5af6f74d8aa48ee06302f --- /dev/null +++ b/src/proto_alpha/lib_protocol/sc_rollup_inbox_storage.mli @@ -0,0 +1,58 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* Copyright (c) 2022 TriliTech *) +(* *) +(* 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. *) +(* *) +(*****************************************************************************) + +(** [inbox context rollup] returns the current state of the inbox. *) +val inbox : + Raw_context.t -> + Sc_rollup_repr.t -> + (Sc_rollup_inbox_repr.t * Raw_context.t) tzresult Lwt.t + +(** [add_messages context rollup msg] adds [msg] to [rollup]'s inbox. + + This function returns the updated context as well as the size diff. + + May fail with: + {ul + {li [Sc_rollup_max_number_of_available_messages] if [inbox] is full} + {li [Sc_rollup_max_number_of_messages_reached_for_commitment_period] if + the number of messages pushed during commitment period is too high} + } +*) +val add_messages : + Raw_context.t -> + Sc_rollup_repr.t -> + string list -> + (Sc_rollup_inbox_repr.t * Z.t * Raw_context.t) tzresult Lwt.t + +(**/**) + +module Internal_for_tests : sig + (** [update_num_and_size_of_messages ~num_messages ~total_messages_size + message] returns the length and total messages size + [messages]. *) + val update_num_and_size_of_messages : + num_messages:int -> total_messages_size:int -> string -> int * int +end diff --git a/src/proto_alpha/lib_protocol/sc_rollup_refutation_storage.ml b/src/proto_alpha/lib_protocol/sc_rollup_refutation_storage.ml new file mode 100644 index 0000000000000000000000000000000000000000..59b9467c77acac929cdfd35a8183972d84709d82 --- /dev/null +++ b/src/proto_alpha/lib_protocol/sc_rollup_refutation_storage.ml @@ -0,0 +1,255 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* Copyright (c) 2022 TriliTech *) +(* *) +(* 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. *) +(* *) +(*****************************************************************************) + +open Sc_rollup_errors +module Store = Storage.Sc_rollup +module Commitment = Sc_rollup_commitment_repr +module Commitment_storage = Sc_rollup_commitment_storage +module Commitment_hash = Commitment.Hash +module Stake_storage = Sc_rollup_stake_storage + +type conflict_point = Commitment_hash.t * Commitment_hash.t + +(** TODO: #2902 replace with protocol constant and consider good value. *) +let timeout_period_in_blocks = 500 + +let timeout_level ctxt = + let level = Raw_context.current_level ctxt in + Raw_level_repr.add level.level timeout_period_in_blocks + +(** [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 = + Commitment_storage.get_commitment_unsafe 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 + (* Ensure the LCC is set. *) + let* lcc, ctxt = Commitment_storage.last_cemented_commitment ctxt rollup in + (* Find out on which commitments the competitors are staked. *) + let* commit1, ctxt = Stake_storage.find_staker ctxt rollup staker1 in + let* commit2, ctxt = Stake_storage.find_staker ctxt rollup staker2 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 = + Commitment_storage.get_commitment_unsafe ctxt rollup commit1 + in + let* commit2_info, ctxt = + Commitment_storage.get_commitment_unsafe 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 + 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 = + (* We know that commit1 <> commit2 at the first call and during recursive calls + as well. *) + let* commit1_info, ctxt = + Commitment_storage.get_commitment_unsafe ctxt rollup commit1 + in + let* commit2_info, ctxt = + Commitment_storage.get_commitment_unsafe ctxt rollup commit2 + in + (* This assert should hold because: + - We call function [traverse_in_parallel] with two initial commitments + whose levels are equal to [target_inbox_level], + - In recursive calls, the commitments are replaced by their respective + predecessors, and we know that successive commitments in a branch are + spaced by [sc_rollup_commitment_period_in_blocks] *) + 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 + (* Different predecessors means they run in parallel. *) + (traverse_in_parallel [@ocaml.tailcall]) + ctxt + commit1_info.predecessor + commit2_info.predecessor + in + 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 traverse_in_parallel ctxt commit1 commit2 + +(** [get_or_init_game ctxt rollup refuter defender] returns the current + game between the two stakers [refuter] and [defender] if it exists. + + If it does not already exist, it creates one with [refuter] as the + first player to move. The initial state of the game will be obtained + from the commitment pair belonging to [defender] at the conflict + point. See [Sc_rollup_game_repr.initial] for documentation on how a + pair of commitments is turned into an initial game state. + + This also deals with the other bits of data in the storage around + the game. It checks neither staker is already in a game (and also + marks them as in a game once the new game is created). The reason we + only allow a staker to play one game at a time is to keep the + end-of-game logic simple---this way, a game can't end suddenly in + the middle because one player lost their stake in another game, it + can only end due to it's own moves or timeouts. + + It also initialises the timeout level to the current level plus + [timeout_period_in_blocks] (which will become a protocol constant + soon) to mark the block level at which it becomes possible for + anyone to end the game by timeout. + + May fail with: + {ul + {li [Sc_rollup_does_not_exist] if [rollup] does not exist} + {li [Sc_rollup_no_conflict] if [refuter] is staked on an ancestor of + the commitment staked on by [defender], or vice versa} + {li [Sc_rollup_not_staked] if one of the [refuter] or [defender] is + not actually staked} + {li [Sc_rollup_staker_in_game] if one of the [refuter] or [defender] + is already playing a game} + } *) +let get_or_init_game ctxt rollup ~refuter ~defender = + let open Lwt_tzresult_syntax in + let stakers = Sc_rollup_game_repr.Index.normalize (refuter, defender) in + let* ctxt, game = Store.Game.find (ctxt, rollup) stakers in + match game with + | Some g -> return (g, ctxt) + | None -> + let* ctxt, opp_1 = Store.Opponent.find (ctxt, rollup) refuter in + let* ctxt, opp_2 = Store.Opponent.find (ctxt, rollup) defender in + let* _ = + match (opp_1, opp_2) with + | None, None -> return () + | _ -> fail Sc_rollup_staker_in_game + in + let* (_, child), ctxt = get_conflict_point ctxt rollup refuter defender in + let* child, ctxt = + Commitment_storage.get_commitment_unsafe ctxt rollup child + in + let* parent, ctxt = + Commitment_storage.get_commitment_unsafe ctxt rollup child.predecessor + in + let* ctxt, inbox = Store.Inbox.get ctxt rollup in + let game = + Sc_rollup_game_repr.initial inbox ~parent ~child ~refuter ~defender + in + let* ctxt, _ = Store.Game.init (ctxt, rollup) stakers game in + let* ctxt, _ = + Store.Game_timeout.init (ctxt, rollup) stakers (timeout_level ctxt) + in + let* ctxt, _ = Store.Opponent.init (ctxt, rollup) refuter defender in + let* ctxt, _ = Store.Opponent.init (ctxt, rollup) defender refuter in + return (game, ctxt) + +(* TODO: #2926 this requires carbonation *) +let update_game ctxt rollup ~player ~opponent refutation = + let open Lwt_tzresult_syntax in + let alice, bob = Sc_rollup_game_repr.Index.normalize (player, opponent) in + let* game, ctxt = + get_or_init_game ctxt rollup ~refuter:player ~defender:opponent + in + let* _ = + let turn = match game.turn with Alice -> alice | Bob -> bob in + if Sc_rollup_repr.Staker.equal turn player then return () + else fail Sc_rollup_wrong_turn + in + match Sc_rollup_game_repr.play game refutation with + | Either.Left outcome -> return (Some outcome, ctxt) + | Either.Right new_game -> + let* ctxt, _ = Store.Game.update (ctxt, rollup) (alice, bob) new_game in + let* ctxt, _ = + Store.Game_timeout.update + (ctxt, rollup) + (alice, bob) + (timeout_level ctxt) + in + return (None, ctxt) + +(* TODO: #2926 this requires carbonation *) +let timeout ctxt rollup stakers = + let open Lwt_tzresult_syntax in + let level = (Raw_context.current_level ctxt).level in + let alice, bob = Sc_rollup_game_repr.Index.normalize stakers in + let* ctxt, game = Store.Game.find (ctxt, rollup) (alice, bob) in + match game with + | None -> fail Sc_rollup_no_game + | Some game -> + let* ctxt, timeout_level = + Store.Game_timeout.get (ctxt, rollup) (alice, bob) + in + if Raw_level_repr.(level > timeout_level) then + return (Sc_rollup_game_repr.{loser = game.turn; reason = Timeout}, ctxt) + else fail Sc_rollup_timeout_level_not_reached + +(* TODO: #2926 this requires carbonation *) +let apply_outcome ctxt rollup stakers (outcome : Sc_rollup_game_repr.outcome) = + let open Lwt_tzresult_syntax in + let alice, bob = Sc_rollup_game_repr.Index.normalize stakers in + let losing_staker = Sc_rollup_game_repr.Index.staker stakers outcome.loser in + let* ctxt = Stake_storage.remove_staker ctxt rollup losing_staker in + let* ctxt, _, _ = Store.Game.remove (ctxt, rollup) (alice, bob) in + let* ctxt, _, _ = Store.Game_timeout.remove (ctxt, rollup) (alice, bob) in + let* ctxt, _, _ = Store.Opponent.remove (ctxt, rollup) alice in + let* ctxt, _, _ = Store.Opponent.remove (ctxt, rollup) bob in + return (Sc_rollup_game_repr.Ended (outcome.reason, losing_staker), ctxt) + +module Internal_for_tests = struct + let get_conflict_point = get_conflict_point +end diff --git a/src/proto_alpha/lib_protocol/sc_rollup_refutation_storage.mli b/src/proto_alpha/lib_protocol/sc_rollup_refutation_storage.mli new file mode 100644 index 0000000000000000000000000000000000000000..d5f2563a8caedb55569bc54fc5d2895a34b2706d --- /dev/null +++ b/src/proto_alpha/lib_protocol/sc_rollup_refutation_storage.mli @@ -0,0 +1,135 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* Copyright (c) 2022 TriliTech *) +(* *) +(* 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. *) +(* *) +(*****************************************************************************) + +module Commitment_hash = Sc_rollup_commitment_repr.Hash + +type conflict_point = Commitment_hash.t * Commitment_hash.t + +(** [update_game ctxt rollup player opponent refutation] handles the + storage-side logic for when one of the players makes a move in the + game. It initializes the game if necessary (the first move looks + much like any other). It checks that [player] is the player whose + turn it is; if so, it applies [refutation] using the [play] function. + + If the result is a new game, this is stored and the timeout level is + updated. + + If the result is an [outcome], this will be returned. + + May fail with: + {ul + {li [Sc_rollup_does_not_exist] if [rollup] does not exist} + {li [Sc_rollup_no_conflict] if [player] is staked on an ancestor of + the commitment staked on by [opponent], or vice versa} + {li [Sc_rollup_not_staked] if one of the [player] or [opponent] is + not actually staked} + {li [Sc_rollup_staker_in_game] if one of the [player] or [opponent] + is already playing a game} + {li [Sc_rollup_wrong_turn] if a player is trying to move out of + turn} + } *) +val update_game : + Raw_context.t -> + Sc_rollup_repr.t -> + player:Sc_rollup_repr.Staker.t -> + opponent:Sc_rollup_repr.Staker.t -> + Sc_rollup_game_repr.refutation -> + (Sc_rollup_game_repr.outcome option * Raw_context.t) tzresult Lwt.t + +(* TODO: #2902 update reference to timeout period in doc-string *) + +(** [timeout ctxt rollup stakers] checks that the timeout has + elapsed and if this function returns a game outcome that punishes whichever + of [stakers] is supposed to have played a move. + + The timeout period is currently defined in + [timeout_period_in_blocks]. This should become a protocol constant + soon. + + May fail with: + {ul + {li [Sc_rollup_no_game] if the game does not in fact exist} + {li [Sc_rollup_timeout_level_not_reached] if the player still has + time in which to play} + } + + Note: this function takes the two stakers as a pair rather than + separate arguments. This reflects the fact that for this function + the two players are symmetric. This function will normalize the + order of the players if necessary to get a valid game index, so the + argument [stakers] doesn't have to be in normal form. *) +val timeout : + Raw_context.t -> + Sc_rollup_repr.t -> + Sc_rollup_repr.Staker.t * Sc_rollup_repr.Staker.t -> + (Sc_rollup_game_repr.outcome * Raw_context.t) tzresult Lwt.t + +(** [apply_outcome ctxt rollup outcome] takes an [outcome] produced + by [timeout] or [update_game] and performs the necessary end-of-game + cleanup: remove the game itself from the store and punish the losing + player by removing their stake. + + It also translates the 'internal' type to represent the end of the + game, [outcome], into the [status] type that makes sense to the + outside world. + + This is mostly just calling [remove_staker], so it can fail with the + same errors as that. However, if it is called on an [outcome] + generated by [update_game] or [timeout] it should not fail. + + Note: this function takes the two stakers as a pair rather than + separate arguments. This reflects the fact that for this function + the two players are symmetric. This function will normalize the + order of the players if necessary to get a valid game index, so the + argument [stakers] doesn't have to be in normal form. *) +val apply_outcome : + Raw_context.t -> + Sc_rollup_repr.t -> + Sc_rollup_repr.Staker.t * Sc_rollup_repr.Staker.t -> + Sc_rollup_game_repr.outcome -> + (Sc_rollup_game_repr.status * Raw_context.t) tzresult Lwt.t + +(**/**) + +module Internal_for_tests : sig + (** [get_conflict_point context rollup staker1 staker2] returns the first point + of disagreement between the given stakers. The returned commitments are + distinct, and have the same [parent] commitment. + + May fail with: + {ul + {li [Sc_rollup_does_not_exist] if [rollup] does not exist} + {li [Sc_rollup_no_conflict] if [staker1] is staked on an ancestor of the + commitment staked on by [staker2], or vice versa} + {li [Sc_rollup_not_staked] if one of the stakers is not staked} + } *) + val get_conflict_point : + Raw_context.t -> + Sc_rollup_repr.t -> + Sc_rollup_repr.Staker.t -> + Sc_rollup_repr.Staker.t -> + (conflict_point * Raw_context.t) tzresult Lwt.t +end diff --git a/src/proto_alpha/lib_protocol/sc_rollup_repr.ml b/src/proto_alpha/lib_protocol/sc_rollup_repr.ml index ae0f644ff7c23ef1f15bba60765f42ef45897380..3a9b343ded22d59fff57df2aaa30791c2eb43734 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_repr.ml +++ b/src/proto_alpha/lib_protocol/sc_rollup_repr.ml @@ -80,35 +80,6 @@ module Internal_for_tests = struct Address.hash_bytes [data] end -(* 32 *) -let commitment_hash_prefix = "\017\144\021\100" (* scc1(54) *) - -module Commitment_hash = struct - let prefix = "scc1" - - let encoded_size = 54 - - module H = - Blake2B.Make - (Base58) - (struct - let name = "commitment_hash" - - let title = "The hash of a commitment of a smart contract rollup" - - let b58check_prefix = commitment_hash_prefix - - (* defaults to 32 *) - let size = None - end) - - include H - - let () = Base58.check_encoded_prefix b58check_encoding prefix encoded_size - - include Path_encoding.Make_hex (H) -end - (* 32 *) let state_hash_prefix = "\017\144\122\202" (* scs1(54) *) @@ -217,10 +188,6 @@ module Index = struct let compare = Address.compare end -module Commitment_hash_index = struct - include Commitment_hash -end - module Number_of_messages = Bounded.Int32.Make (struct let min_int = 0l @@ -236,77 +203,6 @@ module Number_of_ticks = Bounded.Int32.Make (struct let max_int = Int32.max_int end) -module Commitment = struct - type t = { - compressed_state : State_hash.t; - inbox_level : Raw_level_repr.t; - predecessor : Commitment_hash.t; - number_of_messages : Number_of_messages.t; - number_of_ticks : Number_of_ticks.t; - } - - let pp fmt - { - compressed_state; - inbox_level; - predecessor; - number_of_messages; - number_of_ticks; - } = - Format.fprintf - fmt - "@[SCORU Commitment:@ compressed_state: %a@ inbox_level: %a@ \ - predecessor: %a@ number_of_messages: %ld@ number_of_ticks: %ld@]" - State_hash.pp - compressed_state - Raw_level_repr.pp - inbox_level - Commitment_hash.pp - predecessor - (Number_of_messages.to_int32 number_of_messages) - (Number_of_ticks.to_int32 number_of_ticks) - - let encoding = - let open Data_encoding in - conv - (fun { - compressed_state; - inbox_level; - predecessor; - number_of_messages; - number_of_ticks; - } -> - ( compressed_state, - inbox_level, - predecessor, - number_of_messages, - number_of_ticks )) - (fun ( compressed_state, - inbox_level, - predecessor, - number_of_messages, - number_of_ticks ) -> - { - compressed_state; - inbox_level; - predecessor; - number_of_messages; - number_of_ticks; - }) - (obj5 - (req "compressed_state" State_hash.encoding) - (req "inbox_level" Raw_level_repr.encoding) - (req "predecessor" Commitment_hash.encoding) - (req "number_of_messages" Number_of_messages.encoding) - (req "number_of_ticks" Number_of_ticks.encoding)) - - let hash commitment = - let commitment_bytes = - Data_encoding.Binary.to_bytes_exn encoding commitment - in - Commitment_hash.hash_bytes [commitment_bytes] -end - module Kind = struct (* diff --git a/src/proto_alpha/lib_protocol/sc_rollup_repr.mli b/src/proto_alpha/lib_protocol/sc_rollup_repr.mli index 72807ac004a546844d89cc07e3c2f93e287b6985..2f7229e3133654e65c61ecea0fe8b9a323fb77c4 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_repr.mli +++ b/src/proto_alpha/lib_protocol/sc_rollup_repr.mli @@ -56,63 +56,22 @@ module Internal_for_tests : sig val originated_sc_rollup : Origination_nonce.t -> Address.t end -module Commitment_hash : S.HASH - module State_hash : S.HASH (** Number of messages consumed by a single commitment. This represents a claim about the shape of the Inbox, which can be disputed as part of a commitment dispute. - See also {!Sc_rollup_repr.Commitments}. *) + See also {!Commitment_repr.}. *) module Number_of_messages : Bounded.Int32.S (** Number of ticks computed by a single commitment. This represents a claim about the state of the PVM, which can be disputed as part of a commitment dispute. - See also {!Sc_rollup_repr.Commitments}. *) + See also {!Commitment_repr.}. *) module Number_of_ticks : Bounded.Int32.S -(** A commitment represents a claim about the state of the Inbox and PVM at - some Inbox level. - - More formally, a commitment is a claim that: - - {ul - {li assuming the PVM and Inbox are in a state implied by [predecessor]} - {li the PVM consumes [number_of_messages] messages tagged with - [inbox_level] from the Inbox} - {li the PVM advances to the state [compressed_state] over - [number_of_ticks] ticks } - } - - Commitments are disjoint. The next correct commitment is a function of the - previous machine state and Inbox. - - [number_of_messages] and [inbox_level] can be proven/disproven by Merkle - proofs on the Inbox state. - - [compressed_state] and [number_of_ticks] can be proven/disproven by PVM - execution, or equivalently, by an interactive proof game between - conflicting parties, such that a correct executor always wins the game. - *) -module Commitment : sig - type t = { - compressed_state : State_hash.t; - inbox_level : Raw_level_repr.t; - predecessor : Commitment_hash.t; - number_of_messages : Number_of_messages.t; - number_of_ticks : Number_of_ticks.t; - } - - val pp : Format.formatter -> t -> unit - - val encoding : t Data_encoding.t - - val hash : t -> Commitment_hash.t -end - (** A smart contract rollup is identified by its address. *) type t = Address.t @@ -129,9 +88,6 @@ val pp : Format.formatter -> t -> unit (** The data model uses an index of these addresses. *) module Index : Storage_description.INDEX with type t = Address.t -module Commitment_hash_index : - Storage_description.INDEX with type t = Commitment_hash.t - (** A smart contract rollup has a kind, which assigns meaning to rollup operations. *) module Kind : sig diff --git a/src/proto_alpha/lib_protocol/sc_rollup_stake_storage.ml b/src/proto_alpha/lib_protocol/sc_rollup_stake_storage.ml new file mode 100644 index 0000000000000000000000000000000000000000..8c4c19f27286e8d3816045f5d295b741eaccee56 --- /dev/null +++ b/src/proto_alpha/lib_protocol/sc_rollup_stake_storage.ml @@ -0,0 +1,361 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* Copyright (c) 2022 TriliTech *) +(* *) +(* 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. *) +(* *) +(*****************************************************************************) + +open Sc_rollup_errors +module Store = Storage.Sc_rollup +module Commitment_storage = Sc_rollup_commitment_storage +module Commitment = Sc_rollup_commitment_repr +module Commitment_hash = Commitment.Hash + +let find_staker ctxt rollup staker = + let open Lwt_tzresult_syntax in + let* ctxt, res = Store.Stakers.find (ctxt, rollup) staker in + match res with + | None -> fail Sc_rollup_not_staked + | Some branch -> return (branch, ctxt) + +let modify_staker_count ctxt rollup f = + let open Lwt_tzresult_syntax in + let* ctxt, maybe_count = Store.Staker_count.find ctxt rollup in + let count = Option.value ~default:0l maybe_count in + let* ctxt, size_diff, _was_bound = + Store.Staker_count.add ctxt rollup (f count) + in + assert (Compare.Int.(size_diff = 0)) ; + return ctxt + +let deposit_stake ctxt rollup staker = + let open Lwt_tzresult_syntax in + let* lcc, ctxt = Commitment_storage.last_cemented_commitment ctxt rollup in + let* ctxt, res = Store.Stakers.find (ctxt, rollup) staker in + match res with + | None -> + (* TODO: https://gitlab.com/tezos/tezos/-/issues/2449 + We should lock stake here, and fail if there aren't enough funds. + *) + let* ctxt, _size = Store.Stakers.init (ctxt, rollup) staker lcc in + let* ctxt = modify_staker_count ctxt rollup Int32.succ in + return ctxt + | Some _ -> fail Sc_rollup_already_staked + +let withdraw_stake ctxt rollup staker = + let open Lwt_tzresult_syntax in + let* lcc, ctxt = Commitment_storage.last_cemented_commitment ctxt rollup in + let* ctxt, res = Store.Stakers.find (ctxt, rollup) staker in + match res with + | None -> fail Sc_rollup_not_staked + | Some staked_on_commitment -> + if Commitment_hash.(staked_on_commitment = lcc) then + (* TODO: https://gitlab.com/tezos/tezos/-/issues/2449 + We should refund stake here. + *) + let* ctxt, _size_freed = + Store.Stakers.remove_existing (ctxt, rollup) staker + in + modify_staker_count ctxt rollup Int32.pred + else fail Sc_rollup_not_staked_on_lcc + +let assert_commitment_not_too_far_ahead ctxt rollup lcc commitment = + let open Lwt_tzresult_syntax in + let* ctxt, min_level = + if Commitment_hash.(lcc = zero) then + let* level = Store.Initial_level.get ctxt rollup in + return (ctxt, level) + else + let* lcc, ctxt = + Commitment_storage.get_commitment_unsafe ctxt rollup lcc + in + return (ctxt, Commitment.(lcc.inbox_level)) + in + let max_level = Commitment.(commitment.inbox_level) in + if + let sc_rollup_max_lookahead = + Constants_storage.sc_rollup_max_lookahead_in_blocks ctxt + in + Compare.Int32.( + sc_rollup_max_lookahead < Raw_level_repr.diff max_level min_level) + then fail Sc_rollup_too_far_ahead + else return ctxt + +(** 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_period ctxt rollup commitment = + let open Lwt_tzresult_syntax in + let pred_hash = Commitment.(commitment.predecessor) in + let* ctxt, pred_level = + if Commitment_hash.(pred_hash = zero) then + let* level = Store.Initial_level.get ctxt rollup in + return (ctxt, level) + else + let* pred, ctxt = + Commitment_storage.get_commitment_unsafe ctxt rollup pred_hash + in + return (ctxt, Commitment.(pred.inbox_level)) + in + (* We want to check the following inequalities on [commitment.inbox_level], + [commitment.predecessor.inbox_level] and the constant [sc_rollup_commitment_period]. + + - Greater-than-or-equal (>=), to ensure inbox_levels are monotonically + increasing along each branch of commitments. Together with + [assert_commitment_not_too_far_ahead] this is sufficient to limit the + depth of the commitment tree, which is also the number of commitments stored + per staker. This constraint must be enforced at submission time. + + - Equality (=), so that L2 blocks are produced at a regular rate. This + ensures that there is only ever one branch of correct commitments, + simplifying refutation logic. This could also be enforced at refutation time + rather than submission time, but doing it here works too. + + Because [a >= b && a = b] is equivalent to [a = b], we can just keep the latter as + an optimization. + *) + let sc_rollup_commitment_period = + Constants_storage.sc_rollup_commitment_period_in_blocks ctxt + in + if + Raw_level_repr.( + commitment.inbox_level = add pred_level sc_rollup_commitment_period) + then return ctxt + else fail Sc_rollup_bad_inbox_level + +(** Check invariants on [inbox_level], enforcing overallocation of storage and + regularity of block production. + + The constants used by [assert_refine_conditions_met] must be chosen such + that the maximum cost of storage allocated by each staker is 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_period ctxt rollup commitment + +let get_commitment_stake_count ctxt rollup node = + let open Lwt_tzresult_syntax in + let* ctxt, maybe_staked_on_commitment = + Store.Commitment_stake_count.find (ctxt, rollup) node + in + return (Option.value ~default:0l maybe_staked_on_commitment, ctxt) + +let modify_commitment_stake_count ctxt rollup node f = + let open Lwt_tzresult_syntax in + let* count, ctxt = get_commitment_stake_count ctxt rollup node in + let new_count = f count in + let* ctxt, size_diff, _was_bound = + Store.Commitment_stake_count.add (ctxt, rollup) node new_count + in + return (new_count, size_diff, ctxt) + +let deallocate ctxt rollup node = + let open Lwt_tzresult_syntax in + if Commitment_hash.(node = zero) then return ctxt + else + let* ctxt, _size_freed = + Store.Commitments.remove_existing (ctxt, rollup) node + in + let* ctxt, _size_freed = + Store.Commitment_added.remove_existing (ctxt, rollup) node + in + let* ctxt, _size_freed = + Store.Commitment_stake_count.remove_existing (ctxt, rollup) node + in + return ctxt + +let decrease_commitment_stake_count ctxt rollup node = + let open Lwt_tzresult_syntax in + let* new_count, _size_diff, ctxt = + modify_commitment_stake_count ctxt rollup node Int32.pred + in + if Compare.Int32.(new_count <= 0l) then deallocate ctxt rollup node + else return ctxt + +let increase_commitment_stake_count ctxt rollup node = + let open Lwt_tzresult_syntax in + let* _new_count, size_diff, ctxt = + modify_commitment_stake_count ctxt rollup node Int32.succ + in + return (size_diff, ctxt) + +let refine_stake ctxt rollup staker commitment = + let open Lwt_tzresult_syntax in + let* lcc, ctxt = Commitment_storage.last_cemented_commitment ctxt rollup in + let* staked_on, ctxt = find_staker ctxt rollup staker in + let* ctxt = assert_refine_conditions_met ctxt rollup lcc commitment in + let new_hash = Commitment.hash commitment in + (* TODO: https://gitlab.com/tezos/tezos/-/issues/2559 + Add a test checking that L2 nodes can catch up after going offline. *) + let rec go node ctxt = + (* WARNING: Do NOT reorder this sequence of ifs. + we must check for staked_on before LCC, since refining + from the LCC to another commit is a valid operation. *) + if Commitment_hash.(node = staked_on) then ( + (* Previously staked commit found: + Insert new commitment if not existing *) + let* ctxt, commitment_size_diff, _was_bound = + Store.Commitments.add (ctxt, rollup) new_hash commitment + in + let level = (Raw_context.current_level ctxt).level in + let* commitment_added_size_diff, commitment_added_level, ctxt = + Commitment_storage.set_commitment_added ctxt rollup new_hash level + in + let* ctxt, staker_count_diff = + Store.Stakers.update (ctxt, rollup) staker new_hash + in + let* stake_count_size_diff, ctxt = + increase_commitment_stake_count ctxt rollup new_hash + in + (* WARNING: [commitment_storage_size] is a defined constant, and used + to set a bound on the relationship between [max_lookahead], + [commitment_period] and [stake_amount]. Be careful changing this + calculation. *) + let size_diff = + commitment_size_diff + commitment_added_size_diff + + stake_count_size_diff + staker_count_diff + in + let expected_size_diff = + Constants_storage.sc_rollup_commitment_storage_size_in_bytes ctxt + in + (* First submission adds [sc_rollup_commitment_storage_size_in_bytes] to storage. + Later submission adds 0 due to content-addressing. *) + assert (Compare.Int.(size_diff = 0 || size_diff = expected_size_diff)) ; + return (new_hash, commitment_added_level, ctxt) + (* See WARNING above. *)) + else if Commitment_hash.(node = lcc) then + (* We reached the LCC, but [staker] is not staked directly on it. + Thus, we backtracked. Note that everyone is staked indirectly on + the LCC. *) + fail Sc_rollup_staker_backtracked + else + let* pred, ctxt = + Commitment_storage.get_predecessor_unsafe ctxt rollup node + in + let* _size, ctxt = increase_commitment_stake_count ctxt rollup node in + (go [@ocaml.tailcall]) pred ctxt + in + go Commitment.(commitment.predecessor) ctxt + +let publish_commitment ctxt rollup staker commitment = + let open Lwt_tzresult_syntax in + let* ctxt, res = Store.Stakers.find (ctxt, rollup) staker in + match res with + | None -> + let* ctxt = deposit_stake ctxt rollup staker in + refine_stake ctxt rollup staker commitment + | Some _ -> refine_stake ctxt rollup staker commitment + +(** Try to consume n messages. *) +let consume_n_messages ctxt rollup n = + let open Lwt_tzresult_syntax in + let* ctxt, inbox = Store.Inbox.get ctxt rollup in + Sc_rollup_inbox_repr.consume_n_messages n inbox >>?= function + | None -> return ctxt + | Some inbox -> + let* ctxt, size = Store.Inbox.update ctxt rollup inbox in + assert (Compare.Int.(size <= 0)) ; + return ctxt + +let cement_commitment ctxt rollup new_lcc = + let open Lwt_tzresult_syntax in + let refutation_deadline_blocks = + Constants_storage.sc_rollup_challenge_window_in_blocks ctxt + in + (* Calling [last_final_commitment] first to trigger failure in case of + non-existing rollup. *) + let* old_lcc, ctxt = + Commitment_storage.last_cemented_commitment ctxt rollup + in + (* Get is safe, as [Stakers_size] is initialized on origination. *) + let* ctxt, total_staker_count = Store.Staker_count.get ctxt rollup in + if Compare.Int32.(total_staker_count <= 0l) then fail Sc_rollup_no_stakers + else + let* new_lcc_commitment, ctxt = + Commitment_storage.get_commitment_unsafe ctxt rollup new_lcc + in + let* ctxt, new_lcc_added = + Store.Commitment_added.get (ctxt, rollup) new_lcc + in + if Commitment_hash.(new_lcc_commitment.predecessor <> old_lcc) then + fail Sc_rollup_parent_not_lcc + else + let* new_lcc_stake_count, ctxt = + get_commitment_stake_count ctxt rollup new_lcc + in + if Compare.Int32.(total_staker_count <> new_lcc_stake_count) then + fail Sc_rollup_disputed + else if + let level = (Raw_context.current_level ctxt).level in + Raw_level_repr.(level < add new_lcc_added refutation_deadline_blocks) + then fail Sc_rollup_too_recent + else + (* update LCC *) + let* ctxt, lcc_size_diff = + Store.Last_cemented_commitment.update ctxt rollup new_lcc + in + assert (Compare.Int.(lcc_size_diff = 0)) ; + (* At this point we know all stakers are implicitly staked + on the new LCC, and no one is directly staked on the old LCC. We + can safely deallocate the old LCC. + *) + let* ctxt = deallocate ctxt rollup old_lcc in + consume_n_messages + ctxt + rollup + (Int32.to_int + @@ Sc_rollup_repr.Number_of_messages.to_int32 + new_lcc_commitment.number_of_messages) + +let remove_staker ctxt rollup staker = + let open Lwt_tzresult_syntax in + let* lcc, ctxt = Commitment_storage.last_cemented_commitment ctxt rollup in + let* ctxt, res = Store.Stakers.find (ctxt, rollup) staker in + match res with + | None -> fail Sc_rollup_not_staked + | Some staked_on -> + if Commitment_hash.(staked_on = lcc) then fail Sc_rollup_remove_lcc + else + let* ctxt, _size_diff = + Store.Stakers.remove_existing (ctxt, rollup) staker + in + let* ctxt = modify_staker_count ctxt rollup Int32.pred in + let rec go node ctxt = + if Commitment_hash.(node = lcc) then return ctxt + else + let* pred, ctxt = + Commitment_storage.get_predecessor_unsafe ctxt rollup node + in + let* ctxt = decrease_commitment_stake_count ctxt rollup node in + (go [@ocaml.tailcall]) pred ctxt + in + go staked_on ctxt + +module Internal_for_tests = struct + let deposit_stake = deposit_stake + + let withdraw_stake = withdraw_stake + + let refine_stake = refine_stake +end diff --git a/src/proto_alpha/lib_protocol/sc_rollup_stake_storage.mli b/src/proto_alpha/lib_protocol/sc_rollup_stake_storage.mli new file mode 100644 index 0000000000000000000000000000000000000000..3ce6e4c7055e7e15fc25e6b77352aa600cae0f6a --- /dev/null +++ b/src/proto_alpha/lib_protocol/sc_rollup_stake_storage.mli @@ -0,0 +1,210 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* Copyright (c) 2022 TriliTech *) +(* *) +(* 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. *) +(* *) +(*****************************************************************************) + +(** [remove_staker context rollup staker] forcibly removes the given [staker] + and confiscates their frozen deposits. + + Any commitments no longer staked on are removed and storage reclaimed by + [remove_staker]. Because of this there is no need to explicitly reject + commitments. + + May fail with: + {ul + {li [Sc_rollup_does_not_exist] if [rollup] does not exist} + {li [Sc_rollup_not_staked] if [staker] is not staked} + {li [Sc_rollup_remove_lcc] if [staker] is staked on a cemented commitment} + } *) +val remove_staker : + Raw_context.t -> + Sc_rollup_repr.t -> + Sc_rollup_repr.Staker.t -> + Raw_context.t tzresult Lwt.t + +(** This is a wrapper around [deposit_stake] and [refine_stake] that + deposits a stake and then refines it to the specified commitment, + creating that commitment if necessary. Before calling + [deposit_stake] it checks that the staker is not already staked, and + if so will skip that step and go straight to calling [refine_stake]. + + May fail with: + {ul + {li [Sc_rollup_does_not_exist] if [rollup] does not exist} + {li [Sc_rollup_too_far_ahead] if [staker] would be more than + [sc_rollup_max_future_commitments] ahead of the Last Cemented Commitment} + {li [Sc_rollup_bad_inbox_level] if [commitment]'s predecessor is + less than [sc_rollup_commitment_period] blocks ahead} + {li [Sc_rollup_staker_backtracked] if [staker] is not staked on an ancestor + of [commitment]} + {li [Sc_rollup_unknown_commitment] if the parent of the given commitment + does not exist} + {li [Sc_rollup_staker_funds_too_low] if [staker] is not previously a staker, and does not have enough funds + to cover the deposit} + } + + Returns the hash of the given commitment, and the level when the commitment + was first published by some staker. + + This function does not authenticate the staker. *) +val publish_commitment : + Raw_context.t -> + Sc_rollup_repr.t -> + Sc_rollup_repr.Staker.t -> + Sc_rollup_commitment_repr.t -> + (Sc_rollup_commitment_repr.Hash.t * Raw_level_repr.t * Raw_context.t) tzresult + Lwt.t + +(** [cement_commitment context rollup commitment] cements the given + commitment. + + 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: + {ol + {li The deadline for [commitment] must have passed.} + {li The predecessor of [commitment] must be the Last Cemented Commitment.} + {li There must be at least one staker.} + {li All stakers must be indirectly staked on [commitment].} + } + + If successful, [last_cemented_commitment] is set to the given [commitment] and + the appropriate amount of inbox messages is consumed. The old LCC is also + deallocated. + + May fail with: + {ul + {li [Sc_rollup_does_not_exist] if [rollup] does not exist} + {li [Sc_rollup_unknown_commitment] if [commitment] does not exist} + {li [Sc_rollup_parent_not_lcc] if [commitment] is not the child of the last cemented commitment} + {li [Sc_rollup_too_recent] if [commitment] has not passed its deadline} + {li [Sc_rollup_no_stakers] if there are zero stakers} + {li [Sc_rollup_disputed] if at least one staker is not staked on [commitment]} + } *) +val cement_commitment : + Raw_context.t -> + Sc_rollup_repr.t -> + Sc_rollup_commitment_repr.Hash.t -> + Raw_context.t tzresult Lwt.t + +(** [find_staker ctxt rollup staker] returns the branch on which the stake + is deposited for the [rollup]'s [staker]. + + May fail with [Sc_rollup_not_staked] if [staker] is not staked. *) +val find_staker : + Raw_context.t -> + Sc_rollup_repr.t -> + Signature.public_key_hash -> + (Sc_rollup_commitment_repr.Hash.t * Raw_context.t) tzresult Lwt.t + +(**/**) + +module Internal_for_tests : sig + (** [deposit_stake context rollup staker] stakes [staker] at the last + cemented commitment, freezing [sc_rollup_deposit] from [staker]'s account + balance. + + May fail with: + {ul + {li [Sc_rollup_does_not_exist] if [rollup] does not exist} + {li [Sc_rollup_already_staked] if [staker] is already staked} + {li [Sc_rollup_staker_funds_too_low] if [staker] does not have enough + funds to cover the deposit} + } + + This should usually be followed by [refine_stake] to stake on a + specific commitment. + + This function does not authenticate the staker. *) + val deposit_stake : + Raw_context.t -> + Sc_rollup_repr.t -> + Sc_rollup_repr.Staker.t -> + Raw_context.t tzresult Lwt.t + + (** [withdraw_stake context rollup staker] removes [staker] and returns + any deposit previously frozen by [deposit_stake]. + + May fail with: + {ul + {li [Sc_rollup_does_not_exist] if [rollup] does not exist} + {li [Sc_rollup_not_staked_on_lcc] if [staker] is not staked on the last + cemented commitment} + } + + Note that it is not possible to be staked on a Cemented commitment other + than the Last, because of Cementation Rule #4. See [cement_commitment] + for details. + + By design, the operation wrapping this should {i not} be authenticated, + as it may be necessary for nodes on the honest branch to refund stakers on + the LCC. They must do so by using [withdraw_stake] as they are implicitly + staked on the LCC and can not dispute it. *) + val withdraw_stake : + Raw_context.t -> + Sc_rollup_repr.t -> + Sc_rollup_repr.Staker.t -> + Raw_context.t tzresult Lwt.t + + (** [refine_stake context rollup staker commitment] moves the stake of + [staker] to [commitment]. Because we do not assume any form of coordination + between validators, we do not distinguish between {i adding new} + 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 + a [context] with greater level, or behavior is undefined. + + The first time a commitment hash is staked on, it is assigned a deadline, + which is counted in Tezos blocks (levels). Further stakes on the block does + not affect the deadline. The commitment can not be cemented before the + deadline has expired. Note that if a commitment is removed due to disputes + and then re-entered, a later deadline may be assigned. Assuming one honest + staker is always available, this only affects invalid commitments. + + May fail with: + {ul + {li [Sc_rollup_does_not_exist] if [rollup] does not exist} + {li [Sc_rollup_too_far_ahead] if [staker] would be more than + [sc_rollup_max_future_commitments] ahead of the Last Cemented Commitment} + {li [Sc_rollup_bad_inbox_level] if [commitment]'s predecessor is + less than [sc_rollup_commitment_period] blocks ahead} + {li [Sc_rollup_not_staked] if [staker] is not staked} + {li [Sc_rollup_staker_backtracked] if [staker] is not staked on an ancestor of [commitment]} + {li [Sc_rollup_unknown_commitment] if the parent of the given commitment does not exist} + } + + Returns the hash of the given commitment. + + This function does not authenticate the staker. *) + val refine_stake : + Raw_context.t -> + Sc_rollup_repr.t -> + Sc_rollup_repr.Staker.t -> + Sc_rollup_commitment_repr.t -> + (Sc_rollup_commitment_repr.Hash.t * Raw_level_repr.t * Raw_context.t) + tzresult + Lwt.t +end diff --git a/src/proto_alpha/lib_protocol/sc_rollup_storage.ml b/src/proto_alpha/lib_protocol/sc_rollup_storage.ml index 18e96f304b1caee93e749cba3a2eca47563e531c..7ab813f9220b80a0d7deeecc514feba55ed8bc13 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_storage.ml +++ b/src/proto_alpha/lib_protocol/sc_rollup_storage.ml @@ -24,283 +24,10 @@ (* *) (*****************************************************************************) -type error += - | (* `Temporary *) Sc_rollup_already_staked - | (* `Temporary *) Sc_rollup_disputed - | (* `Temporary *) Sc_rollup_does_not_exist of Sc_rollup_repr.t - | (* `Temporary *) Sc_rollup_no_conflict - | (* `Temporary *) Sc_rollup_no_stakers - | (* `Temporary *) Sc_rollup_not_staked - | (* `Temporary *) Sc_rollup_not_staked_on_lcc - | (* `Temporary *) Sc_rollup_parent_not_lcc - | (* `Temporary *) Sc_rollup_remove_lcc - | (* `Temporary *) Sc_rollup_staker_backtracked - | (* `Temporary *) Sc_rollup_too_far_ahead - | (* `Temporary *) Sc_rollup_too_recent - | (* `Temporary *) - Sc_rollup_unknown_commitment of - Sc_rollup_repr.Commitment_hash.t - | (* `Temporary *) Sc_rollup_bad_inbox_level - | (* `Temporary *) Sc_rollup_max_number_of_available_messages_reached - | (* `Temporary *) Sc_rollup_wrong_turn - | (* `Temporary *) Sc_rollup_no_game - | (* `Temporary *) Sc_rollup_staker_in_game - | (* `Temporary *) Sc_rollup_timeout_level_not_reached - | (* `Temporary *) - Sc_rollup_max_number_of_messages_reached_for_commitment_period - | (* `Temporary *) Sc_rollup_invalid_outbox_message_index - | (* `Temporary *) Sc_rollup_outbox_level_expired - | (* `Temporary *) Sc_rollup_outbox_message_already_applied - -let () = - register_error_kind - `Temporary - ~id:"Sc_rollup_max_number_of_available_messages_reached" - ~title:"Maximum number of available messages reached" - ~description:"Maximum number of available messages reached" - Data_encoding.unit - (function - | Sc_rollup_max_number_of_available_messages_reached -> Some () - | _ -> None) - (fun () -> Sc_rollup_max_number_of_available_messages_reached) ; - register_error_kind - `Temporary - ~id:"Sc_rollup_staker_in_game" - ~title:"Staker is already playing a game" - ~description:"Attempt to start a game where one staker is already busy" - Data_encoding.unit - (function Sc_rollup_staker_in_game -> Some () | _ -> None) - (fun () -> Sc_rollup_staker_in_game) ; - register_error_kind - `Temporary - ~id:"Sc_rollup_timeout_level_not_reached" - ~title:"Attempt to timeout game too early" - ~description:"Attempt to timeout game too early" - Data_encoding.unit - (function Sc_rollup_timeout_level_not_reached -> Some () | _ -> None) - (fun () -> Sc_rollup_timeout_level_not_reached) ; - register_error_kind - `Temporary - ~id:"Sc_rollup_no_game" - ~title:"Refutation game does not exist" - ~description:"Refutation game does not exist" - Data_encoding.unit - (function Sc_rollup_no_game -> Some () | _ -> None) - (fun () -> Sc_rollup_no_game) ; - register_error_kind - `Temporary - ~id:"Sc_rollup_wrong_turn" - ~title:"Attempt to play move but not staker's turn" - ~description:"Attempt to play move but not staker's turn" - Data_encoding.unit - (function Sc_rollup_wrong_turn -> Some () | _ -> None) - (fun () -> Sc_rollup_wrong_turn) ; - register_error_kind - `Temporary - ~id:"Sc_rollup_max_number_of_messages_reached_for_commitment_period" - ~title:"Maximum number of messages reached for commitment period" - ~description:"Maximum number of messages reached for commitment period" - Data_encoding.unit - (function - | Sc_rollup_max_number_of_messages_reached_for_commitment_period -> - Some () - | _ -> None) - (fun () -> Sc_rollup_max_number_of_messages_reached_for_commitment_period) ; - - let description = "Already staked." in - register_error_kind - `Temporary - ~id:"Sc_rollup_already_staked" - ~title:"Already staked" - ~description - ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) - Data_encoding.empty - (function Sc_rollup_already_staked -> Some () | _ -> None) - (fun () -> Sc_rollup_already_staked) ; - let description = "Attempted to cement a disputed commitment." in - register_error_kind - `Temporary - ~id:"Sc_rollup_disputed" - ~title:"Commitment disputed" - ~description - ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) - Data_encoding.empty - (function Sc_rollup_disputed -> Some () | _ -> None) - (fun () -> Sc_rollup_disputed) ; - let description = "Attempted to use a rollup that has not been originated." in - register_error_kind - `Temporary - ~id:"Sc_rollup_does_not_exist" - ~title:"Rollup does not exist" - ~description - ~pp:(fun ppf x -> - Format.fprintf ppf "Rollup %a does not exist" Sc_rollup_repr.pp x) - Data_encoding.(obj1 (req "rollup" Sc_rollup_repr.encoding)) - (function Sc_rollup_does_not_exist x -> Some x | _ -> None) - (fun x -> Sc_rollup_does_not_exist x) ; - let description = "No conflict." in - register_error_kind - `Temporary - ~id:"Sc_rollup_no_conflict" - ~title:"No conflict" - ~description - ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) - Data_encoding.empty - (function Sc_rollup_no_conflict -> Some () | _ -> None) - (fun () -> Sc_rollup_no_conflict) ; - let description = "No stakers." in - register_error_kind - `Temporary - ~id:"Sc_rollup_no_stakers" - ~title:"No stakers" - ~description - ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) - Data_encoding.empty - (function Sc_rollup_no_stakers -> Some () | _ -> None) - (fun () -> Sc_rollup_no_stakers) ; - let description = "Unknown staker." in - register_error_kind - `Temporary - ~id:"Sc_rollup_not_staked" - ~title:"Unknown staker" - ~description - ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) - Data_encoding.empty - (function Sc_rollup_not_staked -> Some () | _ -> None) - (fun () -> Sc_rollup_not_staked) ; - let description = - "Attempted to withdraw while not staked on the last cemented commitment." - in - register_error_kind - `Temporary - ~id:"Sc_rollup_not_staked_on_lcc" - ~title:"Rollup not staked on LCC" - ~description - ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) - Data_encoding.empty - (function Sc_rollup_not_staked_on_lcc -> Some () | _ -> None) - (fun () -> Sc_rollup_not_staked_on_lcc) ; - let description = "Parent is not cemented." in - register_error_kind - `Temporary - ~id:"Sc_rollup_parent_not_lcc" - ~title:"Parent not cemented" - ~description - ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) - Data_encoding.empty - (function Sc_rollup_parent_not_lcc -> Some () | _ -> None) - (fun () -> Sc_rollup_parent_not_lcc) ; - let description = "Can not remove a cemented commitment." in - register_error_kind - `Temporary - ~id:"Sc_rollup_remove_lcc" - ~title:"Can not remove cemented" - ~description - ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) - Data_encoding.empty - (function Sc_rollup_remove_lcc -> Some () | _ -> None) - (fun () -> Sc_rollup_remove_lcc) ; - let description = "Staker backtracked." in - register_error_kind - `Temporary - ~id:"Sc_rollup_staker_backtracked" - ~title:"Staker backtracked" - ~description - ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) - Data_encoding.empty - (function Sc_rollup_staker_backtracked -> Some () | _ -> None) - (fun () -> Sc_rollup_staker_backtracked) ; - let description = - "Commitment is too far ahead of the last cemented commitment." - in - register_error_kind - `Temporary - ~id:"Sc_rollup_too_far_ahead" - ~title:"Commitment too far ahead" - ~description - ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) - Data_encoding.empty - (function Sc_rollup_too_far_ahead -> Some () | _ -> None) - (fun () -> Sc_rollup_too_far_ahead) ; - let description = - "Attempted to cement a commitment before its refutation deadline." - in - register_error_kind - `Temporary - ~id:"Sc_rollup_too_recent" - ~title:"Commitment too recent" - ~description - ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) - Data_encoding.empty - (function Sc_rollup_too_recent -> Some () | _ -> None) - (fun () -> Sc_rollup_too_recent) ; - let description = "Unknown commitment." in - register_error_kind - `Temporary - ~id:"Sc_rollup_unknown_commitment" - ~title:"Unknown commitment" - ~description - ~pp:(fun ppf x -> - Format.fprintf - ppf - "Commitment %a does not exist" - Sc_rollup_repr.Commitment_hash.pp - x) - Data_encoding.( - obj1 (req "commitment" Sc_rollup_repr.Commitment_hash.encoding)) - (function Sc_rollup_unknown_commitment x -> Some x | _ -> None) - (fun x -> Sc_rollup_unknown_commitment x) ; - let description = "Attempted to commit to a bad inbox level." in - register_error_kind - `Temporary - ~id:"Sc_rollup_bad_inbox_level" - ~title:"Committing to a bad inbox level" - ~description - ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) - Data_encoding.empty - (function Sc_rollup_bad_inbox_level -> Some () | _ -> None) - (fun () -> Sc_rollup_bad_inbox_level) ; - let description = "Invalid rollup outbox message index" in - register_error_kind - `Temporary - ~id:"Sc_rollup_invalid_outbox_message_index" - ~title:"Invalid rollup outbox message index" - ~description - ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) - Data_encoding.empty - (function Sc_rollup_invalid_outbox_message_index -> Some () | _ -> None) - (fun () -> Sc_rollup_invalid_outbox_message_index) ; - let description = "Outbox level expired" in - register_error_kind - `Temporary - ~id:"Sc_rollup_outbox_level_expired" - ~title:description - ~description - ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) - Data_encoding.empty - (function Sc_rollup_outbox_level_expired -> Some () | _ -> None) - (fun () -> Sc_rollup_outbox_level_expired) ; - let description = "Outbox message already applied" in - register_error_kind - `Temporary - ~id:"Sc_rollup_outbox_message_already_applied" - ~title:description - ~description - ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) - Data_encoding.empty - (function Sc_rollup_outbox_message_already_applied -> Some () | _ -> None) - (fun () -> Sc_rollup_outbox_message_already_applied) ; - () - +open Sc_rollup_errors module Store = Storage.Sc_rollup -module Commitment = Sc_rollup_repr.Commitment -module Commitment_hash = Sc_rollup_repr.Commitment_hash - -module Internal = struct - let update_num_and_size_of_messages ~num_messages ~total_messages_size message - = - (num_messages + 1, total_messages_size + String.length message) -end +module Commitment = Sc_rollup_commitment_repr +module Commitment_hash = Commitment.Hash let originate ctxt ~kind ~boot_sector = Raw_context.increment_origination_nonce ctxt >>?= fun (ctxt, nonce) -> @@ -330,557 +57,6 @@ let originate ctxt ~kind ~boot_sector = let kind ctxt address = Store.PVM_kind.find ctxt address -let last_cemented_commitment ctxt rollup = - let open Lwt_tzresult_syntax in - let* ctxt, res = Store.Last_cemented_commitment.find ctxt rollup in - match res with - | None -> fail (Sc_rollup_does_not_exist rollup) - | Some lcc -> return (lcc, ctxt) - -(** Try to consume n messages. *) -let consume_n_messages ctxt rollup n = - let open Lwt_tzresult_syntax in - let* ctxt, inbox = Store.Inbox.get ctxt rollup in - Sc_rollup_inbox_repr.consume_n_messages n inbox >>?= function - | None -> return ctxt - | Some inbox -> - let* ctxt, size = Store.Inbox.update ctxt rollup inbox in - assert (Compare.Int.(size <= 0)) ; - return ctxt - -let inbox ctxt rollup = - let open Lwt_tzresult_syntax in - let* ctxt, res = Store.Inbox.find ctxt rollup in - match res with - | None -> fail (Sc_rollup_does_not_exist rollup) - | Some inbox -> return (inbox, ctxt) - -let assert_inbox_size_ok ctxt inbox extra_num_messages = - let next_size = - Z.add - (Sc_rollup_inbox_repr.number_of_available_messages inbox) - (Z.of_int extra_num_messages) - in - let max_size = Constants_storage.sc_rollup_max_available_messages ctxt in - fail_unless - Compare.Z.(next_size <= Z.of_int max_size) - Sc_rollup_max_number_of_available_messages_reached - -let assert_inbox_nb_messages_in_commitment_period inbox extra_messages = - let nb_messages_in_commitment_period = - Int64.add - (Sc_rollup_inbox_repr.number_of_messages_during_commitment_period inbox) - (Int64.of_int extra_messages) - in - let limit = Int64.of_int32 Sc_rollup_repr.Number_of_messages.max_int in - fail_when - Compare.Int64.(nb_messages_in_commitment_period > limit) - Sc_rollup_max_number_of_messages_reached_for_commitment_period - -let add_messages ctxt rollup messages = - let {Level_repr.level; _} = Raw_context.current_level ctxt in - let open Lwt_tzresult_syntax in - let open Raw_context in - let commitment_period = - Constants_storage.sc_rollup_commitment_period_in_blocks ctxt |> Int32.of_int - in - let* inbox, ctxt = inbox ctxt rollup in - let* num_messages, total_messages_size, ctxt = - List.fold_left_es - (fun (num_messages, total_messages_size, ctxt) message -> - let*? ctxt = - Raw_context.consume_gas - ctxt - Sc_rollup_costs.Constants.cost_update_num_and_size_of_messages - in - let num_messages, total_messages_size = - Internal.update_num_and_size_of_messages - ~num_messages - ~total_messages_size - message - in - return (num_messages, total_messages_size, ctxt)) - (0, 0, ctxt) - messages - in - let* () = assert_inbox_size_ok ctxt inbox num_messages in - let start = - Sc_rollup_inbox_repr.starting_level_of_current_commitment_period inbox - in - let freshness = Raw_level_repr.diff level start in - let inbox = - let open Int32 in - let open Compare.Int32 in - if freshness >= commitment_period then ( - let nb_periods = - to_int ((mul (div freshness commitment_period)) commitment_period) - in - let new_starting_level = Raw_level_repr.(add start nb_periods) in - assert (Raw_level_repr.(new_starting_level <= level)) ; - assert ( - rem (Raw_level_repr.diff new_starting_level start) commitment_period - = 0l) ; - Sc_rollup_inbox_repr.start_new_commitment_period inbox new_starting_level) - else inbox - in - let* () = assert_inbox_nb_messages_in_commitment_period inbox num_messages in - let inbox_level = Sc_rollup_inbox_repr.inbox_level inbox in - let* origination_level = Storage.Sc_rollup.Initial_level.get ctxt rollup in - let levels = - Int32.sub - (Raw_level_repr.to_int32 inbox_level) - (Raw_level_repr.to_int32 origination_level) - in - let*? current_messages, ctxt = - Sc_rollup_in_memory_inbox.current_messages ctxt rollup - in - let gas_cost_add_messages = - Sc_rollup_costs.cost_add_messages ~num_messages ~total_messages_size levels - in - let*? ctxt = Raw_context.consume_gas ctxt gas_cost_add_messages in - (* - Notice that the protocol is forgetful: it throws away the inbox - history. On the contrary, the history is stored by the rollup - node to produce inclusion proofs when needed. - *) - let* current_messages, inbox = - Sc_rollup_inbox_repr.( - add_messages_no_history inbox level messages current_messages) - in - let*? ctxt = - Sc_rollup_in_memory_inbox.set_current_messages ctxt rollup current_messages - in - let* ctxt, size = Store.Inbox.update ctxt rollup inbox in - return (inbox, Z.of_int size, ctxt) - -(* This function is called in other functions in the module only after they have - checked for the existence of the rollup, and therefore it is not necessary - for it to check for the existence of the rollup again. It is not directly - exposed by the module. Instead, a different public function [get_commitment] - is provided, which checks for the existence of [rollup] before calling - [get_commitment_internal]. *) -let get_commitment_internal ctxt rollup commitment = - let open Lwt_tzresult_syntax in - let* ctxt, res = Store.Commitments.find (ctxt, rollup) commitment in - match res with - | None -> fail (Sc_rollup_unknown_commitment commitment) - | Some commitment -> return (commitment, ctxt) - -let get_commitment ctxt rollup commitment = - let open Lwt_tzresult_syntax in - (* Assert that a last cemented commitment exists. *) - let* _lcc, ctxt = last_cemented_commitment ctxt rollup in - get_commitment_internal ctxt rollup commitment - -let get_predecessor ctxt rollup node = - let open Lwt_tzresult_syntax in - let* commitment, ctxt = get_commitment_internal ctxt rollup node in - return (commitment.predecessor, ctxt) - -let find_staker ctxt rollup staker = - let open Lwt_tzresult_syntax in - let* ctxt, res = Store.Stakers.find (ctxt, rollup) staker in - match res with - | None -> fail Sc_rollup_not_staked - | Some branch -> return (branch, ctxt) - -let modify_staker_count ctxt rollup f = - let open Lwt_tzresult_syntax in - let* ctxt, maybe_count = Store.Staker_count.find ctxt rollup in - let count = Option.value ~default:0l maybe_count in - let* ctxt, size_diff, _was_bound = - Store.Staker_count.add ctxt rollup (f count) - in - assert (Compare.Int.(size_diff = 0)) ; - return ctxt - -let get_commitment_stake_count ctxt rollup node = - let open Lwt_tzresult_syntax in - let* ctxt, maybe_staked_on_commitment = - Store.Commitment_stake_count.find (ctxt, rollup) node - in - return (Option.value ~default:0l maybe_staked_on_commitment, ctxt) - -(** [set_commitment_added ctxt rollup node current] sets the commitment - addition time of [node] to [current] iff the commitment time was - not previously set, and leaves it unchanged otherwise. - *) -let set_commitment_added ctxt rollup node new_value = - let open Lwt_tzresult_syntax in - let* ctxt, res = Store.Commitment_added.find (ctxt, rollup) node in - match res with - | Some old_value -> - (* No need to re-add the read value *) - return (0, old_value, ctxt) - | None -> - let* ctxt, size_diff, _was_bound = - Store.Commitment_added.add (ctxt, rollup) node new_value - in - return (size_diff, new_value, ctxt) - -let deallocate ctxt rollup node = - let open Lwt_tzresult_syntax in - if Commitment_hash.(node = zero) then return ctxt - else - let* ctxt, _size_freed = - Store.Commitments.remove_existing (ctxt, rollup) node - in - let* ctxt, _size_freed = - Store.Commitment_added.remove_existing (ctxt, rollup) node - in - let* ctxt, _size_freed = - Store.Commitment_stake_count.remove_existing (ctxt, rollup) node - in - return ctxt - -let modify_commitment_stake_count ctxt rollup node f = - let open Lwt_tzresult_syntax in - let* count, ctxt = get_commitment_stake_count ctxt rollup node in - let new_count = f count in - let* ctxt, size_diff, _was_bound = - Store.Commitment_stake_count.add (ctxt, rollup) node new_count - in - return (new_count, size_diff, ctxt) - -let increase_commitment_stake_count ctxt rollup node = - let open Lwt_tzresult_syntax in - let* _new_count, size_diff, ctxt = - modify_commitment_stake_count ctxt rollup node Int32.succ - in - return (size_diff, ctxt) - -let decrease_commitment_stake_count ctxt rollup node = - let open Lwt_tzresult_syntax in - let* new_count, _size_diff, ctxt = - modify_commitment_stake_count ctxt rollup node Int32.pred - in - if Compare.Int32.(new_count <= 0l) then deallocate ctxt rollup node - else return ctxt - -let deposit_stake ctxt rollup staker = - let open Lwt_tzresult_syntax in - let* lcc, ctxt = last_cemented_commitment ctxt rollup in - let* ctxt, res = Store.Stakers.find (ctxt, rollup) staker in - match res with - | None -> - (* TODO: https://gitlab.com/tezos/tezos/-/issues/2449 - We should lock stake here, and fail if there aren't enough funds. - *) - let* ctxt, _size = Store.Stakers.init (ctxt, rollup) staker lcc in - let* ctxt = modify_staker_count ctxt rollup Int32.succ in - return ctxt - | Some _ -> fail Sc_rollup_already_staked - -let withdraw_stake ctxt rollup staker = - let open Lwt_tzresult_syntax in - let* lcc, ctxt = last_cemented_commitment ctxt rollup in - let* ctxt, res = Store.Stakers.find (ctxt, rollup) staker in - match res with - | None -> fail Sc_rollup_not_staked - | Some staked_on_commitment -> - if Commitment_hash.(staked_on_commitment = lcc) then - (* TODO: https://gitlab.com/tezos/tezos/-/issues/2449 - We should refund stake here. - *) - let* ctxt, _size_freed = - Store.Stakers.remove_existing (ctxt, rollup) staker - in - modify_staker_count ctxt rollup Int32.pred - else fail Sc_rollup_not_staked_on_lcc - -let assert_commitment_not_too_far_ahead ctxt rollup lcc commitment = - let open Lwt_tzresult_syntax in - let* ctxt, min_level = - if Commitment_hash.(lcc = zero) then - let* level = Store.Initial_level.get ctxt rollup in - return (ctxt, level) - else - let* lcc, ctxt = get_commitment_internal ctxt rollup lcc in - return (ctxt, Commitment.(lcc.inbox_level)) - in - let max_level = Commitment.(commitment.inbox_level) in - if - let sc_rollup_max_lookahead = - Constants_storage.sc_rollup_max_lookahead_in_blocks ctxt - in - Compare.Int32.( - sc_rollup_max_lookahead < Raw_level_repr.diff max_level min_level) - then fail Sc_rollup_too_far_ahead - else return ctxt - -(** 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_period ctxt rollup commitment = - let open Lwt_tzresult_syntax in - let pred_hash = Commitment.(commitment.predecessor) in - let* ctxt, pred_level = - if Commitment_hash.(pred_hash = zero) then - let* level = Store.Initial_level.get ctxt rollup in - return (ctxt, level) - else - let* pred, ctxt = get_commitment_internal ctxt rollup pred_hash in - return (ctxt, Commitment.(pred.inbox_level)) - in - (* We want to check the following inequalities on [commitment.inbox_level], - [commitment.predecessor.inbox_level] and the constant [sc_rollup_commitment_period]. - - - Greater-than-or-equal (>=), to ensure inbox_levels are monotonically - increasing along each branch of commitments. Together with - [assert_commitment_not_too_far_ahead] this is sufficient to limit the - depth of the commitment tree, which is also the number of commitments stored - per staker. This constraint must be enforced at submission time. - - - Equality (=), so that L2 blocks are produced at a regular rate. This - ensures that there is only ever one branch of correct commitments, - simplifying refutation logic. This could also be enforced at refutation time - rather than submission time, but doing it here works too. - - Because [a >= b && a = b] is equivalent to [a = b], we can just keep the latter as - an optimization. - *) - let sc_rollup_commitment_period = - Constants_storage.sc_rollup_commitment_period_in_blocks ctxt - in - if - Raw_level_repr.( - commitment.inbox_level = add pred_level sc_rollup_commitment_period) - then return ctxt - else fail Sc_rollup_bad_inbox_level - -(** Check invariants on [inbox_level], enforcing overallocation of storage and - regularity of block production. - - The constants used by [assert_refine_conditions_met] must be chosen such - that the maximum cost of storage allocated by each staker is 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_period ctxt rollup commitment - -let refine_stake ctxt rollup staker commitment = - let open Lwt_tzresult_syntax in - let* lcc, ctxt = last_cemented_commitment ctxt rollup in - let* staked_on, ctxt = find_staker ctxt rollup staker in - let* ctxt = assert_refine_conditions_met ctxt rollup lcc commitment in - let new_hash = Commitment.hash commitment in - (* TODO: https://gitlab.com/tezos/tezos/-/issues/2559 - Add a test checking that L2 nodes can catch up after going offline. *) - let rec go node ctxt = - (* WARNING: Do NOT reorder this sequence of ifs. - we must check for staked_on before LCC, since refining - from the LCC to another commit is a valid operation. *) - if Commitment_hash.(node = staked_on) then ( - (* Previously staked commit found: - Insert new commitment if not existing *) - let* ctxt, commitment_size_diff, _was_bound = - Store.Commitments.add (ctxt, rollup) new_hash commitment - in - let level = (Raw_context.current_level ctxt).level in - let* commitment_added_size_diff, commitment_added_level, ctxt = - set_commitment_added ctxt rollup new_hash level - in - let* ctxt, staker_count_diff = - Store.Stakers.update (ctxt, rollup) staker new_hash - in - let* stake_count_size_diff, ctxt = - increase_commitment_stake_count ctxt rollup new_hash - in - (* WARNING: [commitment_storage_size] is a defined constant, and used - to set a bound on the relationship between [max_lookahead], - [commitment_period] and [stake_amount]. Be careful changing this - calculation. *) - let size_diff = - commitment_size_diff + commitment_added_size_diff - + stake_count_size_diff + staker_count_diff - in - let expected_size_diff = - Constants_storage.sc_rollup_commitment_storage_size_in_bytes ctxt - in - (* First submission adds [sc_rollup_commitment_storage_size_in_bytes] to storage. - Later submission adds 0 due to content-addressing. *) - assert (Compare.Int.(size_diff = 0 || size_diff = expected_size_diff)) ; - return (new_hash, commitment_added_level, ctxt) - (* See WARNING above. *)) - else if Commitment_hash.(node = lcc) then - (* We reached the LCC, but [staker] is not staked directly on it. - Thus, we backtracked. Note that everyone is staked indirectly on - the LCC. *) - fail Sc_rollup_staker_backtracked - else - let* pred, ctxt = get_predecessor ctxt rollup node in - let* _size, ctxt = increase_commitment_stake_count ctxt rollup node in - (go [@ocaml.tailcall]) pred ctxt - in - go Commitment.(commitment.predecessor) ctxt - -let publish_commitment ctxt rollup staker commitment = - let open Lwt_tzresult_syntax in - let* ctxt, res = Store.Stakers.find (ctxt, rollup) staker in - let* ctxt = - match res with - | None -> deposit_stake ctxt rollup staker - | Some _ -> return ctxt - in - refine_stake ctxt rollup staker commitment - -let cement_commitment ctxt rollup new_lcc = - let open Lwt_tzresult_syntax in - let refutation_deadline_blocks = - Constants_storage.sc_rollup_challenge_window_in_blocks ctxt - in - (* Calling [last_final_commitment] first to trigger failure in case of - non-existing rollup. *) - let* old_lcc, ctxt = last_cemented_commitment ctxt rollup in - (* Get is safe, as [Stakers_size] is initialized on origination. *) - let* ctxt, total_staker_count = Store.Staker_count.get ctxt rollup in - if Compare.Int32.(total_staker_count <= 0l) then fail Sc_rollup_no_stakers - else - let* new_lcc_commitment, ctxt = - get_commitment_internal ctxt rollup new_lcc - in - let* ctxt, new_lcc_added = - Store.Commitment_added.get (ctxt, rollup) new_lcc - in - if Commitment_hash.(new_lcc_commitment.predecessor <> old_lcc) then - fail Sc_rollup_parent_not_lcc - else - let* new_lcc_stake_count, ctxt = - get_commitment_stake_count ctxt rollup new_lcc - in - if Compare.Int32.(total_staker_count <> new_lcc_stake_count) then - fail Sc_rollup_disputed - else if - let level = (Raw_context.current_level ctxt).level in - Raw_level_repr.(level < add new_lcc_added refutation_deadline_blocks) - then fail Sc_rollup_too_recent - else - (* update LCC *) - let* ctxt, lcc_size_diff = - Store.Last_cemented_commitment.update ctxt rollup new_lcc - in - assert (Compare.Int.(lcc_size_diff = 0)) ; - (* At this point we know all stakers are implicitly staked - on the new LCC, and no one is directly staked on the old LCC. We - can safely deallocate the old LCC. - *) - let* ctxt = deallocate ctxt rollup old_lcc in - 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 - -(** [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_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. *) - 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 - (* 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* () = - 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. - - 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 - 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 = - (* We know that commit1 <> commit2 at the first call and during recursive calls - as well. *) - let* commit1_info, ctxt = get_commitment_internal ctxt rollup commit1 in - let* commit2_info, ctxt = get_commitment_internal ctxt rollup commit2 in - (* This assert should hold because: - - We call function [traverse_in_parallel] with two initial commitments - whose levels are equal to [target_inbox_level], - - In recursive calls, the commitments are replaced by their respective - predecessors, and we know that successive commitments in a branch are - spaced by [sc_rollup_commitment_period_in_blocks] *) - 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 - (* Different predecessors means they run in parallel. *) - (traverse_in_parallel [@ocaml.tailcall]) - ctxt - commit1_info.predecessor - commit2_info.predecessor - in - 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 traverse_in_parallel ctxt commit1 commit2 - -let remove_staker ctxt rollup staker = - let open Lwt_tzresult_syntax in - let* lcc, ctxt = last_cemented_commitment ctxt rollup in - let* ctxt, res = Store.Stakers.find (ctxt, rollup) staker in - match res with - | None -> fail Sc_rollup_not_staked - | Some staked_on -> - if Commitment_hash.(staked_on = lcc) then fail Sc_rollup_remove_lcc - else - let* ctxt, _size_diff = - Store.Stakers.remove_existing (ctxt, rollup) staker - in - let* ctxt = modify_staker_count ctxt rollup Int32.pred in - let rec go node ctxt = - if Commitment_hash.(node = lcc) then return ctxt - else - let* pred, ctxt = get_predecessor ctxt rollup node in - let* ctxt = decrease_commitment_stake_count ctxt rollup node in - (go [@ocaml.tailcall]) pred ctxt - in - go staked_on ctxt - let list ctxt = Store.PVM_kind.keys ctxt >|= Result.return let initial_level ctxt rollup = @@ -897,108 +73,6 @@ let get_boot_sector ctxt rollup = | None -> fail (Sc_rollup_does_not_exist rollup) | Some boot_sector -> return boot_sector -let last_cemented_commitment_hash_with_level ctxt rollup = - let open Lwt_tzresult_syntax in - let* commitment_hash, ctxt = last_cemented_commitment ctxt rollup in - if Commitment_hash.(commitment_hash = zero) then - let+ initial_level = Storage.Sc_rollup.Initial_level.get ctxt rollup in - (commitment_hash, initial_level, ctxt) - else - let+ {inbox_level; _}, ctxt = - get_commitment_internal ctxt rollup commitment_hash - in - (commitment_hash, inbox_level, ctxt) - -(** TODO: #2902 replace with protocol constant and consider good value. *) -let timeout_period_in_blocks = 500 - -let timeout_level ctxt = - let level = Raw_context.current_level ctxt in - Raw_level_repr.add level.level timeout_period_in_blocks - -let get_or_init_game ctxt rollup ~refuter ~defender = - let open Lwt_tzresult_syntax in - let stakers = Sc_rollup_game_repr.Index.normalize (refuter, defender) in - let* ctxt, game = Store.Game.find (ctxt, rollup) stakers in - match game with - | Some g -> return (g, ctxt) - | None -> - let* ctxt, opp_1 = Store.Opponent.find (ctxt, rollup) refuter in - let* ctxt, opp_2 = Store.Opponent.find (ctxt, rollup) defender in - let* _ = - match (opp_1, opp_2) with - | None, None -> return () - | _ -> fail Sc_rollup_staker_in_game - in - let* (_, child), ctxt = get_conflict_point ctxt rollup refuter defender in - let* child, ctxt = get_commitment_internal ctxt rollup child in - let* parent, ctxt = - get_commitment_internal ctxt rollup child.predecessor - in - let* ctxt, inbox = Store.Inbox.get ctxt rollup in - let game = - Sc_rollup_game_repr.initial inbox ~parent ~child ~refuter ~defender - in - let* ctxt, _ = Store.Game.init (ctxt, rollup) stakers game in - let* ctxt, _ = - Store.Game_timeout.init (ctxt, rollup) stakers (timeout_level ctxt) - in - let* ctxt, _ = Store.Opponent.init (ctxt, rollup) refuter defender in - let* ctxt, _ = Store.Opponent.init (ctxt, rollup) defender refuter in - return (game, ctxt) - -(* TODO: #2926 this requires carbonation *) -let update_game ctxt rollup ~player ~opponent refutation = - let open Lwt_tzresult_syntax in - let alice, bob = Sc_rollup_game_repr.Index.normalize (player, opponent) in - let* game, ctxt = - get_or_init_game ctxt rollup ~refuter:player ~defender:opponent - in - let* _ = - let turn = match game.turn with Alice -> alice | Bob -> bob in - if Sc_rollup_repr.Staker.equal turn player then return () - else fail Sc_rollup_wrong_turn - in - match Sc_rollup_game_repr.play game refutation with - | Either.Left outcome -> return (Some outcome, ctxt) - | Either.Right new_game -> - let* ctxt, _ = Store.Game.update (ctxt, rollup) (alice, bob) new_game in - let* ctxt, _ = - Store.Game_timeout.update - (ctxt, rollup) - (alice, bob) - (timeout_level ctxt) - in - return (None, ctxt) - -(* TODO: #2926 this requires carbonation *) -let timeout ctxt rollup stakers = - let open Lwt_tzresult_syntax in - let level = (Raw_context.current_level ctxt).level in - let alice, bob = Sc_rollup_game_repr.Index.normalize stakers in - let* ctxt, game = Store.Game.find (ctxt, rollup) (alice, bob) in - match game with - | None -> fail Sc_rollup_no_game - | Some game -> - let* ctxt, timeout_level = - Store.Game_timeout.get (ctxt, rollup) (alice, bob) - in - if Raw_level_repr.(level > timeout_level) then - return (Sc_rollup_game_repr.{loser = game.turn; reason = Timeout}, ctxt) - else fail Sc_rollup_timeout_level_not_reached - -(* TODO: #2926 this requires carbonation *) -let apply_outcome ctxt rollup stakers (outcome : Sc_rollup_game_repr.outcome) = - let open Lwt_tzresult_syntax in - let alice, bob = Sc_rollup_game_repr.Index.normalize stakers in - let losing_staker = Sc_rollup_game_repr.Index.staker stakers outcome.loser in - let* ctxt = remove_staker ctxt rollup losing_staker in - let* ctxt, _, _ = Store.Game.remove (ctxt, rollup) (alice, bob) in - let* ctxt, _, _ = Store.Game_timeout.remove (ctxt, rollup) (alice, bob) in - let* ctxt, _, _ = Store.Opponent.remove (ctxt, rollup) alice in - let* ctxt, _, _ = Store.Opponent.remove (ctxt, rollup) bob in - return (Sc_rollup_game_repr.Ended (outcome.reason, losing_staker), ctxt) - module Outbox = struct let level_index ctxt level = let max_active_levels = diff --git a/src/proto_alpha/lib_protocol/sc_rollup_storage.mli b/src/proto_alpha/lib_protocol/sc_rollup_storage.mli index 7a09832d140a6cd1e50e27df4de2d5f52f73668f..74f5e775730e4f9cf2ded99509fb1d9e83ed9006 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_storage.mli +++ b/src/proto_alpha/lib_protocol/sc_rollup_storage.mli @@ -24,142 +24,6 @@ (* *) (*****************************************************************************) -(** Defines storage for Smart Contract Optimistic Rollups. - - {2 Commitments} - - [Commitment]s are stored directly in the L1 context. Commitments are - immutable and content-addressed, and can be indexed by a [Commitment_hash]. - - A commitment represents a claim about the state of a PVM. - - We also keep auxiliary state about each commitment, namely: - - {ul - {li When it was first added.} - {li Its current number of stakers.} - } - - This auxiliary data is not part of the commitment itself. They represent - information that the L1 knows about the claim, not the claim itself. - - {3 Predecessors and Boot state} - Each commitment contains the hash of its {i predecessor}. Multiple - commitments can have the same predecessor. Therefore, commitments form - a Merkle tree. - - Conceptually the root of this tree is the [Commitment_hash.zero]. This - commitment claims that the PVM (Proof-generating Virtual Machine) is in a - pre-boot state and waiting to start booting by interpreting the boot sector with - respect to the Machine semantics. - - {3 Cemented and Disputable commitments} - Commitments accepted as true by the protocol are referred to as Cemented. - - {3 Stakers} - The Stakers table maps Stakers (implicit accounts) to commitments hashes. - - Let [Stakers(S)] mean "looking up the key S in [Stakers]". - - A staker [S] is directly staked on [C] if [Stakers(S) = C]. A staker [S] - is indirectly staked on [C] if [C] is an ancestor of [Stakers(S)] in the commitment tree. - - {3 Dispute} - Commitments that have at least one sibling are referred to as Disputed. - More formally, a commitment C is disputed if at least one staker is not - (directly or indirectly) staked on C. - - {3 Dispute resolution} - The rollup protocol ensures that all disputes are resolved before cementing - a commitment. Therefore, cemented commitments form a list rather than a tree. - - In the context we only store the Last Cemented Commitment (LCC), which is - by definition a descendant of [zero]. We also store all Disputable - commitments that have at least one Staker. - - For example, assuming the full set of commitments for a rollup - looks like this: - - {[ - LCC staker1 staker2 - | | | - | V | - V --c3 | - zero--c1 --c2--/ | - \ V - --c4------ c5 - ]} - then commitments [c2..c5] will be stored in the context. - - {3 Conflicts} - - Let Commitments(S) be the set of commitments directly staked on by staker S. - - Two stakers A and B are: - - {ul - {li In total agreement iff Commitments(A) = Commitments(B).} - {li In partial agreement iff either Commitments(A) ⊂ Commitments(B), or - Commitments(B) ⊂ Commitments(A).} - {li In conflict iff they are neither in total or partial agreement.}} - - We can further refine a conflict to note what they are in conflict about, - e.g. they may be in conflict about the inbox, about execution, or both. We - can resolve conflicts by first resolving the conflict about inbox, then - about execution (since execution is irrelevant if the inbox is not - correct). - *) - -type error += - | (* `Temporary *) - Sc_rollup_does_not_exist of Sc_rollup_repr.t - | (* `Temporary *) - Sc_rollup_already_staked - | (* `Temporary *) - Sc_rollup_not_staked_on_lcc - | (* `Temporary *) - Sc_rollup_staker_backtracked - | (* `Temporary *) - Sc_rollup_unknown_commitment of - Sc_rollup_repr.Commitment_hash.t - | (* `Temporary *) - Sc_rollup_parent_not_lcc - | (* `Temporary *) - Sc_rollup_too_far_ahead - | (* `Temporary *) - Sc_rollup_too_recent - | (* `Temporary *) - Sc_rollup_no_stakers - | (* `Temporary *) - Sc_rollup_disputed - | (* `Temporary *) - Sc_rollup_no_conflict - | (* `Temporary *) - Sc_rollup_not_staked - | (* `Temporary *) - Sc_rollup_remove_lcc - | (* `Temporary *) - Sc_rollup_staker_in_game - | (* `Temporary *) - Sc_rollup_bad_inbox_level - | (* `Temporary *) - Sc_rollup_max_number_of_messages_reached_for_commitment_period - | (* `Temporary *) Sc_rollup_invalid_outbox_message_index - | (* `Temporary *) Sc_rollup_outbox_level_expired - | (* `Temporary *) Sc_rollup_outbox_message_already_applied - -(** Module [Internal] implements functions that are used only internally by - the [Sc_rollup_storage] module, but need to be exposed in tests or - benchmarks. - *) -module Internal : sig - (** [update_num_and_size_of_messages ~num_messages ~total_messages_size - message] returns the length and total messages size - [messages]. *) - val update_num_and_size_of_messages : - num_messages:int -> total_messages_size:int -> string -> int * int -end - (** [originate context ~kind ~boot_sector] produces an address [a] for a smart contract rollup using the origination nonce found in [context]. This function also initializes the storage with a new @@ -181,247 +45,6 @@ val kind : Sc_rollup_repr.t -> Sc_rollup_repr.Kind.t option tzresult Lwt.t -(** [add_messages context rollup msg] adds [msg] to [rollup]'s inbox. - - This function returns the updated context as well as the size diff. - - May fail with: - {ul - {li [Sc_rollup_max_number_of_available_messages] if [inbox] is full} - {li [Sc_rollup_max_number_of_messages_reached_for_commitment_period] if - the number of messages pushed during commitment period is too high} - } -*) -val add_messages : - Raw_context.t -> - Sc_rollup_repr.t -> - string list -> - (Sc_rollup_inbox_repr.t * Z.t * Raw_context.t) tzresult Lwt.t - -(** [inbox context rollup] returns the current state of the inbox. *) -val inbox : - Raw_context.t -> - Sc_rollup_repr.t -> - (Sc_rollup_inbox_repr.t * Raw_context.t) tzresult Lwt.t - -(** [deposit_stake context rollup staker] stakes [staker] at the last - cemented commitment, freezing [sc_rollup_deposit] from [staker]'s account - balance. - - May fail with: - {ul - {li [Sc_rollup_does_not_exist] if [rollup] does not exist} - {li [Sc_rollup_already_staked] if [staker] is already staked} - {li [Sc_rollup_staker_funds_too_low] if [staker] does not have enough funds to cover the deposit} - } - - This should usually be followed by [refine_stake] to stake on a - specific commitment. - - This function does not authenticate the staker. *) -val deposit_stake : - Raw_context.t -> - Sc_rollup_repr.t -> - Sc_rollup_repr.Staker.t -> - Raw_context.t tzresult Lwt.t - -(** [withdraw_stake context rollup staker] removes [staker] and returns - any deposit previously frozen by [deposit_stake]. - - May fail with: - {ul - {li [Sc_rollup_does_not_exist] if [rollup] does not exist} - {li [Sc_rollup_not_staked_on_lcc] if [staker] is not staked on the last - cemented commitment} - } - - Note that it is not possible to be staked on a Cemented commitment other - than the Last, because of Cementation Rule #4. See [cement_commitment] - for details. - - By design, the operation wrapping this should {i not} be authenticated, - as it may be necessary for nodes on the honest branch to refund stakers on - the LCC. They must do so by using [withdraw_stake] as they are implicitly - staked on the LCC and can not dispute it. *) -val withdraw_stake : - Raw_context.t -> - Sc_rollup_repr.t -> - Sc_rollup_repr.Staker.t -> - Raw_context.t tzresult Lwt.t - -(** [refine_stake context rollup staker commitment] moves the stake of - [staker] to [commitment]. Because we do not assume any form of coordination - between validators, we do not distinguish between {i adding new} - 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 - a [context] with greater level, or behavior is undefined. - - The first time a commitment hash is staked on, it is assigned a deadline, - which is counted in Tezos blocks (levels). Further stakes on the block does - not affect the deadline. The commitment can not be cemented before the - deadline has expired. Note that if a commitment is removed due to disputes - and then re-entered, a later deadline may be assigned. Assuming one honest - staker is always available, this only affects invalid commitments. - - May fail with: - {ul - {li [Sc_rollup_does_not_exist] if [rollup] does not exist} - {li [Sc_rollup_too_far_ahead] if [staker] would be more than - [sc_rollup_max_future_commitments] ahead of the Last Cemented Commitment} - {li [Sc_rollup_bad_inbox_level] if [commitment]'s predecessor is - less than [sc_rollup_commitment_period] blocks ahead} - {li [Sc_rollup_not_staked] if [staker] is not staked} - {li [Sc_rollup_staker_backtracked] if [staker] is not staked on an ancestor of [commitment]} - {li [Sc_rollup_unknown_commitment] if the parent of the given commitment does not exist} - } - - Returns the hash of the given commitment. - - This function does not authenticate the staker. *) -val refine_stake : - Raw_context.t -> - Sc_rollup_repr.t -> - Sc_rollup_repr.Staker.t -> - Sc_rollup_repr.Commitment.t -> - (Sc_rollup_repr.Commitment_hash.t * Raw_level_repr.t * Raw_context.t) tzresult - Lwt.t - -(** This is a wrapper around [deposit_stake] and [refine_stake] that - deposits a stake and then refines it to the specified commitment, - creating that commitment if necessary. Before calling - [deposit_stake] it checks that the staker is not already staked, and - if so will skip that step and go straight to calling [refine_stake]. - - May fail with: - {ul - {li [Sc_rollup_does_not_exist] if [rollup] does not exist} - {li [Sc_rollup_too_far_ahead] if [staker] would be more than - [sc_rollup_max_future_commitments] ahead of the Last Cemented Commitment} - {li [Sc_rollup_bad_inbox_level] if [commitment]'s predecessor is - less than [sc_rollup_commitment_period] blocks ahead} - {li [Sc_rollup_staker_backtracked] if [staker] is not staked on an ancestor - of [commitment]} - {li [Sc_rollup_unknown_commitment] if the parent of the given commitment - does not exist} - {li [Sc_rollup_staker_funds_too_low] if [staker] is not previously a staker, and does not have enough funds - to cover the deposit} - } - - Returns the hash of the given commitment, and the level when the commitment - was first published by some staker. - - This function does not authenticate the staker. *) -val publish_commitment : - Raw_context.t -> - Sc_rollup_repr.t -> - Sc_rollup_repr.Staker.t -> - Sc_rollup_repr.Commitment.t -> - (Sc_rollup_repr.Commitment_hash.t * Raw_level_repr.t * Raw_context.t) tzresult - Lwt.t - -(** [last_cemented_commitment context rollup] returns the last cemented - commitment of the rollup. - - If no commitments have been cemented, the rollup is said to be in a - pre-boot state, and [last_cemented_commitment = Commitment_hash.zero]. - - May fail with: - {ul - {li [Sc_rollup_does_not_exist] if [rollup] does not exist}} *) -val last_cemented_commitment : - Raw_context.t -> - Sc_rollup_repr.t -> - (Sc_rollup_repr.Commitment_hash.t * Raw_context.t) tzresult Lwt.t - -(** [cement_commitment context rollup commitment] cements the given - commitment. - - 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: - {ol - {li The deadline for [commitment] must have passed.} - {li The predecessor of [commitment] must be the Last Cemented Commitment.} - {li There must be at least one staker.} - {li All stakers must be indirectly staked on [commitment].} - } - - If successful, [last_cemented_commitment] is set to the given [commitment] and - the appropriate amount of inbox messages is consumed. The old LCC is also - deallocated. - - May fail with: - {ul - {li [Sc_rollup_does_not_exist] if [rollup] does not exist} - {li [Sc_rollup_unknown_commitment] if [commitment] does not exist} - {li [Sc_rollup_parent_not_lcc] if [commitment] is not the child of the last cemented commitment} - {li [Sc_rollup_too_recent] if [commitment] has not passed its deadline} - {li [Sc_rollup_no_stakers] if there are zero stakers} - {li [Sc_rollup_disputed] if at least one staker is not staked on [commitment]} - } *) -val cement_commitment : - Raw_context.t -> - Sc_rollup_repr.t -> - Sc_rollup_repr.Commitment_hash.t -> - Raw_context.t tzresult Lwt.t - -type conflict_point = - Sc_rollup_repr.Commitment_hash.t * Sc_rollup_repr.Commitment_hash.t - -(** [get_conflict_point context rollup staker1 staker2] returns the first point - of disagreement between the given stakers. The returned commitments are - distinct, and have the same [parent] commitment. - - May fail with: - {ul - {li [Sc_rollup_does_not_exist] if [rollup] does not exist} - {li [Sc_rollup_no_conflict] if [staker1] is staked on an ancestor of the - commitment staked on by [staker2], or vice versa} - {li [Sc_rollup_not_staked] if one of the stakers is not staked} - } *) -val get_conflict_point : - Raw_context.t -> - Sc_rollup_repr.t -> - Sc_rollup_repr.Staker.t -> - Sc_rollup_repr.Staker.t -> - (conflict_point * Raw_context.t) tzresult Lwt.t - -(** [get_commitment context rollup commitment_hash] returns the commitment with the given hash. - - May fail with: - {ul - {li [Sc_rollup_does_not_exist] if [rollup] does not exist} - {li [Sc_rollup_unknown_commitment] if [commitment] does not exist} - } *) -val get_commitment : - Raw_context.t -> - Sc_rollup_repr.t -> - Sc_rollup_repr.Commitment_hash.t -> - (Sc_rollup_repr.Commitment.t * Raw_context.t) tzresult Lwt.t - -(** [remove_staker context rollup staker] forcibly removes the given [staker] - and confiscates their frozen deposits. - - Any commitments no longer staked on are removed and storage reclaimed by - [remove_staker]. Because of this there is no need to explicitly reject - commitments. - - May fail with: - {ul - {li [Sc_rollup_does_not_exist] if [rollup] does not exist} - {li [Sc_rollup_not_staked] if [staker] is not staked} - {li [Sc_rollup_remove_lcc] if [staker] is staked on a cemented commitment} - } *) -val remove_staker : - Raw_context.t -> - Sc_rollup_repr.t -> - Sc_rollup_repr.Staker.t -> - Raw_context.t tzresult Lwt.t - -(** [list context] returns a list of all rollups that have been originated. *) val list : Raw_context.t -> Sc_rollup_repr.t list tzresult Lwt.t (** [initial_level ctxt sc_rollup] returns the level at which a [sc_rollup] was @@ -432,144 +55,6 @@ val initial_level : (** [get_boot_sector ctxt sc_rollup] retrieves the boot sector for [sc_rollup]. *) val get_boot_sector : Raw_context.t -> Sc_rollup_repr.t -> string tzresult Lwt.t -(* [last_cemented_commitment_hash_with_level ctxt sc_rollup] returns the hash - and level of the last cemented commitment (lcc) for [sc_rollup]. If the - rollup exists but no lcc exists, the initial commitment - `Sc_rollup.Commitment.zero` together with the rollup origination level is - returned. - - May fail with: - {ul - {li [Sc_rollup_does_not_exist] if [rollup] does not exist}} *) -val last_cemented_commitment_hash_with_level : - Raw_context.t -> - Sc_rollup_repr.t -> - (Sc_rollup_repr.Commitment_hash.t * Raw_level_repr.t * Raw_context.t) tzresult - Lwt.t - -(** [get_or_init_game ctxt rollup refuter defender] returns the current - game between the two stakers [refuter] and [defender] if it exists. - - If it does not already exist, it creates one with [refuter] as the - first player to move. The initial state of the game will be obtained - from the commitment pair belonging to [defender] at the conflict - point. See [Sc_rollup_game_repr.initial] for documentation on how a - pair of commitments is turned into an initial game state. - - This also deals with the other bits of data in the storage around - the game. It checks neither staker is already in a game (and also - marks them as in a game once the new game is created). The reason we - only allow a staker to play one game at a time is to keep the - end-of-game logic simple---this way, a game can't end suddenly in - the middle because one player lost their stake in another game, it - can only end due to it's own moves or timeouts. - - It also initialises the timeout level to the current level plus - [timeout_period_in_blocks] (which will become a protocol constant - soon) to mark the block level at which it becomes possible for - anyone to end the game by timeout. - - May fail with: - {ul - {li [Sc_rollup_does_not_exist] if [rollup] does not exist} - {li [Sc_rollup_no_conflict] if [refuter] is staked on an ancestor of - the commitment staked on by [defender], or vice versa} - {li [Sc_rollup_not_staked] if one of the [refuter] or [defender] is - not actually staked} - {li [Sc_rollup_staker_in_game] if one of the [refuter] or [defender] - is already playing a game} - } *) -val get_or_init_game : - Raw_context.t -> - Sc_rollup_repr.t -> - refuter:Sc_rollup_repr.Staker.t -> - defender:Sc_rollup_repr.Staker.t -> - (Sc_rollup_game_repr.t * Raw_context.t) tzresult Lwt.t - -(** [update_game ctxt rollup player opponent refutation] handles the - storage-side logic for when one of the players makes a move in the - game. It initializes the game if necessary (the first move looks - much like any other). It checks that [player] is the player whose - turn it is; if so, it applies [refutation] using the [play] function. - - If the result is a new game, this is stored and the timeout level is - updated. - - If the result is an [outcome], this will be returned. - - May fail with: - {ul - {li [Sc_rollup_does_not_exist] if [rollup] does not exist} - {li [Sc_rollup_no_conflict] if [player] is staked on an ancestor of - the commitment staked on by [opponent], or vice versa} - {li [Sc_rollup_not_staked] if one of the [player] or [opponent] is - not actually staked} - {li [Sc_rollup_staker_in_game] if one of the [player] or [opponent] - is already playing a game} - {li [Sc_rollup_wrong_turn] if a player is trying to move out of - turn} - } *) -val update_game : - Raw_context.t -> - Sc_rollup_repr.t -> - player:Sc_rollup_repr.Staker.t -> - opponent:Sc_rollup_repr.Staker.t -> - Sc_rollup_game_repr.refutation -> - (Sc_rollup_game_repr.outcome option * Raw_context.t) tzresult Lwt.t - -(* TODO: #2902 update reference to timeout period in doc-string *) - -(** [timeout ctxt rollup stakers] checks that the timeout has - elapsed and if this function returns a game outcome that punishes whichever - of [stakers] is supposed to have played a move. - - The timeout period is currently defined in - [timeout_period_in_blocks]. This should become a protocol constant - soon. - - May fail with: - {ul - {li [Sc_rollup_no_game] if the game does not in fact exist} - {li [Sc_rollup_timeout_level_not_reached] if the player still has - time in which to play} - } - - Note: this function takes the two stakers as a pair rather than - separate arguments. This reflects the fact that for this function - the two players are symmetric. This function will normalize the - order of the players if necessary to get a valid game index, so the - argument [stakers] doesn't have to be in normal form. *) -val timeout : - Raw_context.t -> - Sc_rollup_repr.t -> - Sc_rollup_repr.Staker.t * Sc_rollup_repr.Staker.t -> - (Sc_rollup_game_repr.outcome * Raw_context.t) tzresult Lwt.t - -(** [apply_outcome ctxt rollup outcome] takes an [outcome] produced - by [timeout] or [update_game] and performs the necessary end-of-game - cleanup: remove the game itself from the store and punish the losing - player by removing their stake. - - It also translates the 'internal' type to represent the end of the - game, [outcome], into the [status] type that makes sense to the - outside world. - - This is mostly just calling [remove_staker], so it can fail with the - same errors as that. However, if it is called on an [outcome] - generated by [update_game] or [timeout] it should not fail. - - Note: this function takes the two stakers as a pair rather than - separate arguments. This reflects the fact that for this function - the two players are symmetric. This function will normalize the - order of the players if necessary to get a valid game index, so the - argument [stakers] doesn't have to be in normal form. *) -val apply_outcome : - Raw_context.t -> - Sc_rollup_repr.t -> - Sc_rollup_repr.Staker.t * Sc_rollup_repr.Staker.t -> - Sc_rollup_game_repr.outcome -> - (Sc_rollup_game_repr.status * Raw_context.t) tzresult Lwt.t - (** A module for managing state concerning a rollup's outbox. *) module Outbox : sig (** [record_applied_message ctxt rollup level ~message_index] marks the diff --git a/src/proto_alpha/lib_protocol/storage.ml b/src/proto_alpha/lib_protocol/storage.ml index b545d2a24b0b34db63607ab26c3054be62abe76b..536a85c546d32f4471bc157620c89e0f613b7250 100644 --- a/src/proto_alpha/lib_protocol/storage.ml +++ b/src/proto_alpha/lib_protocol/storage.ml @@ -1540,9 +1540,9 @@ module Sc_rollup = struct let name = ["last_cemented_commitment"] end) (struct - type t = Sc_rollup_repr.Commitment_hash.t + type t = Sc_rollup_commitment_repr.Hash.t - let encoding = Sc_rollup_repr.Commitment_hash.encoding + let encoding = Sc_rollup_commitment_repr.Hash.encoding end) module Stakers = @@ -1553,9 +1553,9 @@ module Sc_rollup = struct end)) (Public_key_hash_index) (struct - type t = Sc_rollup_repr.Commitment_hash.t + type t = Sc_rollup_commitment_repr.Hash.t - let encoding = Sc_rollup_repr.Commitment_hash.encoding + let encoding = Sc_rollup_commitment_repr.Hash.encoding end) module Staker_count = @@ -1575,11 +1575,11 @@ module Sc_rollup = struct (struct let name = ["commitments"] end)) - (Make_index (Sc_rollup_repr.Commitment_hash_index)) + (Make_index (Sc_rollup_commitment_repr.Hash_index)) (struct - type t = Sc_rollup_repr.Commitment.t + type t = Sc_rollup_commitment_repr.t - let encoding = Sc_rollup_repr.Commitment.encoding + let encoding = Sc_rollup_commitment_repr.encoding end) module Commitment_stake_count = @@ -1588,7 +1588,7 @@ module Sc_rollup = struct (struct let name = ["commitment_stake_count"] end)) - (Make_index (Sc_rollup_repr.Commitment_hash_index)) + (Make_index (Sc_rollup_commitment_repr.Hash_index)) (struct type t = int32 @@ -1601,7 +1601,7 @@ module Sc_rollup = struct (struct let name = ["commitment_added"] end)) - (Make_index (Sc_rollup_repr.Commitment_hash_index)) + (Make_index (Sc_rollup_commitment_repr.Hash_index)) (struct type t = Raw_level_repr.t diff --git a/src/proto_alpha/lib_protocol/storage.mli b/src/proto_alpha/lib_protocol/storage.mli index f137b0be6fafc4dbe20ba2b64c4912172d4de7c3..f34a9d1ed398b29c3caff3333512ef6b97f32a70 100644 --- a/src/proto_alpha/lib_protocol/storage.mli +++ b/src/proto_alpha/lib_protocol/storage.mli @@ -706,13 +706,13 @@ module Sc_rollup : sig module Last_cemented_commitment : Non_iterable_indexed_carbonated_data_storage with type key = Sc_rollup_repr.t - and type value = Sc_rollup_repr.Commitment_hash.t + and type value = Sc_rollup_commitment_repr.Hash.t and type t := Raw_context.t module Stakers : Non_iterable_indexed_carbonated_data_storage with type key = Signature.Public_key_hash.t - and type value = Sc_rollup_repr.Commitment_hash.t + and type value = Sc_rollup_commitment_repr.Hash.t and type t = Raw_context.t * Sc_rollup_repr.t (** Cache: This should always be the number of entries in [Stakers]. @@ -729,8 +729,8 @@ module Sc_rollup : sig module Commitments : Non_iterable_indexed_carbonated_data_storage - with type key = Sc_rollup_repr.Commitment_hash.t - and type value = Sc_rollup_repr.Commitment.t + with type key = Sc_rollup_commitment_repr.Hash.t + and type value = Sc_rollup_commitment_repr.t and type t = Raw_context.t * Sc_rollup_repr.t (** Cache: This should always be the number of stakers that are directly or @@ -755,13 +755,13 @@ module Sc_rollup : sig *) module Commitment_stake_count : Non_iterable_indexed_carbonated_data_storage - with type key = Sc_rollup_repr.Commitment_hash.t + with type key = Sc_rollup_commitment_repr.Hash.t and type value = int32 and type t = Raw_context.t * Sc_rollup_repr.t module Commitment_added : Non_iterable_indexed_carbonated_data_storage - with type key = Sc_rollup_repr.Commitment_hash.t + with type key = Sc_rollup_commitment_repr.Hash.t and type value = Raw_level_repr.t and type t = Raw_context.t * Sc_rollup_repr.t diff --git a/src/proto_alpha/lib_protocol/test/helpers/op.mli b/src/proto_alpha/lib_protocol/test/helpers/op.mli index ce8a6ce39413f0575e360ce83a84c05f9cf38362..c627b4b16742fce7de09b987825787b42b72c82d 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/op.mli +++ b/src/proto_alpha/lib_protocol/test/helpers/op.mli @@ -389,5 +389,5 @@ val sc_rollup_cement : Context.t -> Contract.t -> Sc_rollup.t -> - Sc_rollup.Commitment_hash.t -> + Sc_rollup.Commitment.Hash.t -> Operation.packed tzresult Lwt.t 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 d64c7503f726379f714a173db8d42e143cf7416f..30f301f720a7f7d7e5fd9af6dc86f27d1efcd376 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 @@ -148,7 +148,7 @@ let dummy_commitment ctxt rollup = return Sc_rollup.Commitment. { - predecessor = Sc_rollup.Commitment_hash.zero; + predecessor = Sc_rollup.Commitment.Hash.zero; inbox_level; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 3000l; @@ -188,7 +188,7 @@ let test_cement_fails_if_premature () = let hash = Sc_rollup.Commitment.hash c in let* cement_op = Op.sc_rollup_cement (I i) contract rollup hash in let expect_failure = function - | Environment.Ecoproto_error (Sc_rollup_storage.Sc_rollup_too_recent as e) + | Environment.Ecoproto_error (Sc_rollup_errors.Sc_rollup_too_recent as e) :: _ -> Assert.test_error_encodings e ; return_unit @@ -216,7 +216,7 @@ let test_publish_fails_on_backtrack () = let* i = Incremental.begin_construction b in let expect_failure = function | Environment.Ecoproto_error - (Sc_rollup_storage.Sc_rollup_staker_backtracked as e) + (Sc_rollup_errors.Sc_rollup_staker_backtracked as e) :: _ -> Assert.test_error_encodings e ; return_unit @@ -251,8 +251,8 @@ let test_cement_fails_on_conflict () = let hash = Sc_rollup.Commitment.hash commitment1 in let* cement_op = Op.sc_rollup_cement (I i) contract1 rollup hash in let expect_failure = function - | Environment.Ecoproto_error (Sc_rollup_storage.Sc_rollup_disputed as e) - :: _ -> + | Environment.Ecoproto_error (Sc_rollup_errors.Sc_rollup_disputed as e) :: _ + -> Assert.test_error_encodings e ; return_unit | _ -> diff --git a/src/proto_alpha/lib_protocol/test/integration/test_constants.ml b/src/proto_alpha/lib_protocol/test/integration/test_constants.ml index 8b092324f5789311a3daadf6417138f4bad5b5ff..d5200d11094cc419797b59e0e4212266dd482d9f 100644 --- a/src/proto_alpha/lib_protocol/test/integration/test_constants.ml +++ b/src/proto_alpha/lib_protocol/test/integration/test_constants.ml @@ -127,7 +127,7 @@ let test_sc_rollup_commitment_storage_size () = let commitment = Alpha_context.Sc_rollup.Commitment. { - predecessor = Alpha_context.Sc_rollup.Commitment_hash.zero; + predecessor = Alpha_context.Sc_rollup.Commitment.Hash.zero; inbox_level = Alpha_context.Raw_level.of_int32_exn 21l; number_of_messages; number_of_ticks; diff --git a/src/proto_alpha/lib_protocol/test/pbt/test_refutation_game.ml b/src/proto_alpha/lib_protocol/test/pbt/test_refutation_game.ml index d548089648e7281be9d7f8ac629b8a960b51bf52..1dec44f739216b3a0b7c65001e0ddaae1170ae95 100644 --- a/src/proto_alpha/lib_protocol/test/pbt/test_refutation_game.ml +++ b/src/proto_alpha/lib_protocol/test/pbt/test_refutation_game.ml @@ -86,7 +86,7 @@ let number_of_ticks_exn n = | None -> Stdlib.failwith "Bad Number_of_ticks" let get_comm pred inbox_level messages ticks state = - Sc_rollup_repr.Commitment. + Sc_rollup_commitment_repr. { predecessor = pred; inbox_level = Raw_level_repr.of_int32_exn inbox_level; @@ -581,7 +581,7 @@ struct let number_of_ticks = Int32.of_int int_tick in let parent = get_comm - Sc_rollup_repr.Commitment_hash.zero + Sc_rollup_commitment_repr.Hash.zero 0l 3l 1l @@ -589,7 +589,7 @@ struct in let child = get_comm - Sc_rollup_repr.Commitment_hash.zero + Sc_rollup_commitment_repr.Hash.zero 0l 3l number_of_ticks 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 f0405696ab8f07fc85e6928fd42339be455a3387..770b7a9db8b957c3f15a0d68657b6f8f7877158c 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 @@ -34,6 +34,7 @@ open Protocol open Lwt_result_syntax +module Commitment_repr = Sc_rollup_commitment_repr (** Lift a computation using using environment errors to use shell errors. *) let lift k = Lwt.map Environment.wrap_tzresult k @@ -60,7 +61,13 @@ let originate_rollup_and_deposit_with_one_staker () = let staker = Sc_rollup_repr.Staker.of_b58check_exn "tz1SdKt9kjPp1HRQFkBmXtBhgMfvdgFhSjmG" in - let+ ctxt = lift @@ Sc_rollup_storage.deposit_stake ctxt rollup staker in + let+ ctxt = + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.deposit_stake + ctxt + rollup + staker + in (ctxt, rollup, staker) (** Originate a rollup with two stakers and make a deposit to the initial LCC *) @@ -73,8 +80,20 @@ let originate_rollup_and_deposit_with_two_stakers () = let staker2 = Sc_rollup_repr.Staker.of_b58check_exn "tz1RikjCkrEde1QQmuesp796jCxeiyE6t3Vo" in - let* ctxt = lift @@ Sc_rollup_storage.deposit_stake ctxt rollup staker1 in - let+ ctxt = lift @@ Sc_rollup_storage.deposit_stake ctxt rollup staker2 in + let* ctxt = + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.deposit_stake + ctxt + rollup + staker1 + in + let+ ctxt = + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.deposit_stake + ctxt + rollup + staker2 + in (ctxt, rollup, staker1, staker2) (** Trivial assertion. @@ -113,9 +132,9 @@ let assert_fails_with_missing_rollup ~loc op = let assert_commitment_hash_equal ~loc _ctxt x y = Assert.equal ~loc - Sc_rollup_repr.Commitment_hash.equal + Commitment_repr.Hash.equal "Compare commitment hash" - Sc_rollup_repr.Commitment_hash.pp + Commitment_repr.Hash.pp x y @@ -130,19 +149,18 @@ let assert_kinds_are_equal ~loc x y = let test_deposit_to_missing_rollup () = assert_fails_with_missing_rollup ~loc:__LOC__ (fun ctxt rollup -> - Sc_rollup_storage.deposit_stake ctxt rollup Sc_rollup_repr.Staker.zero) + Sc_rollup_stake_storage.Internal_for_tests.deposit_stake + ctxt + rollup + Sc_rollup_repr.Staker.zero) let test_initial_state_is_pre_boot () = let* ctxt = new_context () in let* rollup, ctxt = lift @@ new_sc_rollup ctxt in let* lcc, ctxt = - lift @@ Sc_rollup_storage.last_cemented_commitment ctxt rollup + lift @@ Sc_rollup_commitment_storage.last_cemented_commitment ctxt rollup in - assert_commitment_hash_equal - ~loc:__LOC__ - ctxt - lcc - Sc_rollup_repr.Commitment_hash.zero + assert_commitment_hash_equal ~loc:__LOC__ ctxt lcc Commitment_repr.Hash.zero let test_deposit_to_existing_rollup () = let* ctxt = new_context () in @@ -152,7 +170,12 @@ let test_deposit_to_existing_rollup () = Signature.Public_key_hash.of_b58check_exn "tz1SdKt9kjPp1HRQFkBmXtBhgMfvdgFhSjmG" in - let* ctxt = Sc_rollup_storage.deposit_stake ctxt rollup staker in + let* ctxt = + Sc_rollup_stake_storage.Internal_for_tests.deposit_stake + ctxt + rollup + staker + in assert_true ctxt let test_removing_staker_from_lcc_fails () = @@ -162,10 +185,16 @@ let test_removing_staker_from_lcc_fails () = Signature.Public_key_hash.of_b58check_exn "tz1SdKt9kjPp1HRQFkBmXtBhgMfvdgFhSjmG" in - let* ctxt = lift @@ Sc_rollup_storage.deposit_stake ctxt rollup staker in + let* ctxt = + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.deposit_stake + ctxt + rollup + staker + in assert_fails_with ~loc:__LOC__ - (Sc_rollup_storage.remove_staker ctxt rollup staker) + (Sc_rollup_stake_storage.remove_staker ctxt rollup staker) "Can not remove a cemented commitment." let test_deposit_then_withdraw () = @@ -176,8 +205,18 @@ let test_deposit_then_withdraw () = Signature.Public_key_hash.of_b58check_exn "tz1SdKt9kjPp1HRQFkBmXtBhgMfvdgFhSjmG" in - let* ctxt = Sc_rollup_storage.deposit_stake ctxt rollup staker in - let* ctxt = Sc_rollup_storage.withdraw_stake ctxt rollup staker in + let* ctxt = + Sc_rollup_stake_storage.Internal_for_tests.deposit_stake + ctxt + rollup + staker + in + let* ctxt = + Sc_rollup_stake_storage.Internal_for_tests.withdraw_stake + ctxt + rollup + staker + in assert_true ctxt let test_can_not_stake_twice () = @@ -187,15 +226,27 @@ let test_can_not_stake_twice () = Signature.Public_key_hash.of_b58check_exn "tz1SdKt9kjPp1HRQFkBmXtBhgMfvdgFhSjmG" in - let* ctxt = lift @@ Sc_rollup_storage.deposit_stake ctxt rollup staker in + let* ctxt = + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.deposit_stake + ctxt + rollup + staker + in assert_fails_with ~loc:__LOC__ - (Sc_rollup_storage.deposit_stake ctxt rollup staker) + (Sc_rollup_stake_storage.Internal_for_tests.deposit_stake + ctxt + rollup + staker) "Already staked." let test_withdrawal_from_missing_rollup () = assert_fails_with_missing_rollup ~loc:__LOC__ (fun ctxt rollup -> - Sc_rollup_storage.withdraw_stake ctxt rollup Sc_rollup_repr.Staker.zero) + Sc_rollup_stake_storage.Internal_for_tests.withdraw_stake + ctxt + rollup + Sc_rollup_repr.Staker.zero) let test_withdraw_when_not_staked () = let* ctxt = new_context () in @@ -206,7 +257,10 @@ let test_withdraw_when_not_staked () = in assert_fails_with ~loc:__LOC__ - (Sc_rollup_storage.withdraw_stake ctxt rollup staker) + (Sc_rollup_stake_storage.Internal_for_tests.withdraw_stake + ctxt + rollup + staker) "Unknown staker." let test_withdrawing_twice () = @@ -216,11 +270,26 @@ let test_withdrawing_twice () = Signature.Public_key_hash.of_b58check_exn "tz1SdKt9kjPp1HRQFkBmXtBhgMfvdgFhSjmG" in - let* ctxt = lift @@ Sc_rollup_storage.deposit_stake ctxt rollup staker in - let* ctxt = lift @@ Sc_rollup_storage.withdraw_stake ctxt rollup staker in + let* ctxt = + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.deposit_stake + ctxt + rollup + staker + in + let* ctxt = + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.withdraw_stake + ctxt + rollup + staker + in assert_fails_with ~loc:__LOC__ - (Sc_rollup_storage.withdraw_stake ctxt rollup staker) + (Sc_rollup_stake_storage.Internal_for_tests.withdraw_stake + ctxt + rollup + staker) "Unknown staker." let number_of_messages_exn n = @@ -250,11 +319,16 @@ let test_deposit_then_refine () = Sc_rollup_repr.Staker.of_b58check_exn "tz1SdKt9kjPp1HRQFkBmXtBhgMfvdgFhSjmG" in - let* ctxt = Sc_rollup_storage.deposit_stake ctxt rollup staker in + let* ctxt = + Sc_rollup_stake_storage.Internal_for_tests.deposit_stake + ctxt + rollup + staker + in let commitment = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = valid_inbox_level ctxt 1l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -262,7 +336,11 @@ let test_deposit_then_refine () = } in let* _node, _level, ctxt = - Sc_rollup_storage.refine_stake ctxt rollup staker commitment + Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker + commitment in assert_true ctxt @@ -272,11 +350,17 @@ let test_deposit_then_refine_bad_inbox () = let staker = Sc_rollup_repr.Staker.of_b58check_exn "tz1SdKt9kjPp1HRQFkBmXtBhgMfvdgFhSjmG" in - let* ctxt = lift @@ Sc_rollup_storage.deposit_stake ctxt rollup staker in + let* ctxt = + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.deposit_stake + ctxt + rollup + staker + in let commitment = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = Raw_level_repr.of_int32_exn 22l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -285,7 +369,11 @@ let test_deposit_then_refine_bad_inbox () = in assert_fails_with ~loc:__LOC__ - (Sc_rollup_storage.refine_stake ctxt rollup staker commitment) + (Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker + commitment) "Attempted to commit to a bad inbox level." let test_publish () = @@ -297,9 +385,9 @@ let test_publish () = "tz1SdKt9kjPp1HRQFkBmXtBhgMfvdgFhSjmG" in let commitment = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = valid_inbox_level ctxt 1l; number_of_messages = number_of_messages_exn 5l; number_of_ticks = number_of_ticks_exn 152231l; @@ -307,7 +395,7 @@ let test_publish () = } in let* _node, _level, ctxt = - Sc_rollup_storage.publish_commitment ctxt rollup staker commitment + Sc_rollup_stake_storage.publish_commitment ctxt rollup staker commitment in assert_true ctxt @@ -316,9 +404,9 @@ let test_publish_returns_oldest_publish_level () = originate_rollup_and_deposit_with_two_stakers () in let commitment = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = valid_inbox_level ctxt 1l; number_of_messages = number_of_messages_exn 5l; number_of_ticks = number_of_ticks_exn 152231l; @@ -326,7 +414,8 @@ let test_publish_returns_oldest_publish_level () = } in let* _node, level1, ctxt = - lift @@ Sc_rollup_storage.publish_commitment ctxt rollup staker1 commitment + lift + @@ Sc_rollup_stake_storage.publish_commitment ctxt rollup staker1 commitment in let current_level = Raw_level_repr.to_int32 (Raw_context.current_level ctxt).level @@ -339,7 +428,8 @@ let test_publish_returns_oldest_publish_level () = in let ctxt = Raw_context.Internal_for_tests.add_level ctxt 10 in let* _node, level2, _ctxt = - lift @@ Sc_rollup_storage.publish_commitment ctxt rollup staker2 commitment + lift + @@ Sc_rollup_stake_storage.publish_commitment ctxt rollup staker2 commitment in Assert.equal_int32 ~loc:__LOC__ @@ -354,9 +444,9 @@ let test_withdraw_and_cement () = Constants_storage.sc_rollup_challenge_window_in_blocks ctxt in let commitment = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = valid_inbox_level ctxt 1l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -364,11 +454,24 @@ let test_withdraw_and_cement () = } in let* c1, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker1 commitment + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker1 + commitment + in + let* ctxt = + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.withdraw_stake + ctxt + rollup + staker2 in - let* ctxt = lift @@ Sc_rollup_storage.withdraw_stake ctxt rollup staker2 in let ctxt = Raw_context.Internal_for_tests.add_level ctxt challenge_window in - let* ctxt = lift @@ Sc_rollup_storage.cement_commitment ctxt rollup c1 in + let* ctxt = + lift @@ Sc_rollup_stake_storage.cement_commitment ctxt rollup c1 + in assert_true ctxt let test_deposit_then_publish () = @@ -379,11 +482,16 @@ let test_deposit_then_publish () = Sc_rollup_repr.Staker.of_b58check_exn "tz1SdKt9kjPp1HRQFkBmXtBhgMfvdgFhSjmG" in - let* ctxt = Sc_rollup_storage.deposit_stake ctxt rollup staker in + let* ctxt = + Sc_rollup_stake_storage.Internal_for_tests.deposit_stake + ctxt + rollup + staker + in let commitment = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = valid_inbox_level ctxt 1l; number_of_messages = number_of_messages_exn 5l; number_of_ticks = number_of_ticks_exn 152231l; @@ -391,7 +499,7 @@ let test_deposit_then_publish () = } in let* _node, _level, ctxt = - Sc_rollup_storage.publish_commitment ctxt rollup staker commitment + Sc_rollup_stake_storage.publish_commitment ctxt rollup staker commitment in assert_true ctxt @@ -400,9 +508,9 @@ let test_publish_missing_rollup () = Sc_rollup_repr.Staker.of_b58check_exn "tz1SdKt9kjPp1HRQFkBmXtBhgMfvdgFhSjmG" in let commitment ctxt = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = valid_inbox_level ctxt 1l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -410,7 +518,11 @@ let test_publish_missing_rollup () = } in assert_fails_with_missing_rollup ~loc:__LOC__ (fun ctxt rollup -> - Sc_rollup_storage.publish_commitment ctxt rollup staker (commitment ctxt)) + Sc_rollup_stake_storage.publish_commitment + ctxt + rollup + staker + (commitment ctxt)) let test_cement () = let* ctxt = new_context () in @@ -423,11 +535,16 @@ let test_cement () = Sc_rollup_repr.Staker.of_b58check_exn "tz1SdKt9kjPp1HRQFkBmXtBhgMfvdgFhSjmG" in - let* ctxt = Sc_rollup_storage.deposit_stake ctxt rollup staker in + let* ctxt = + Sc_rollup_stake_storage.Internal_for_tests.deposit_stake + ctxt + rollup + staker + in let commitment = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = valid_inbox_level ctxt 1l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -435,12 +552,16 @@ let test_cement () = } in let* c1, _level, ctxt = - Sc_rollup_storage.refine_stake ctxt rollup staker commitment + Sc_rollup_stake_storage.Internal_for_tests.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_stake_storage.cement_commitment ctxt rollup c1 in assert_true ctxt (* Create and cement three commitments: @@ -459,9 +580,9 @@ let test_cement_three_commitments () = lift @@ let commitment = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = level 1l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -469,10 +590,14 @@ let test_cement_three_commitments () = } in let* c1, _level, ctxt = - Sc_rollup_storage.refine_stake ctxt rollup staker commitment + Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker + commitment in let commitment = - Sc_rollup_repr.Commitment. + Commitment_repr. { predecessor = c1; inbox_level = level 2l; @@ -482,10 +607,14 @@ let test_cement_three_commitments () = } in let* c2, _level, ctxt = - Sc_rollup_storage.refine_stake ctxt rollup staker commitment + Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker + commitment in let commitment = - Sc_rollup_repr.Commitment. + Commitment_repr. { predecessor = c2; inbox_level = level 3l; @@ -495,12 +624,16 @@ let test_cement_three_commitments () = } in let* c3, _level, ctxt = - Sc_rollup_storage.refine_stake ctxt rollup staker commitment + Sc_rollup_stake_storage.Internal_for_tests.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 + let* ctxt = Sc_rollup_stake_storage.cement_commitment ctxt rollup c1 in + let* ctxt = Sc_rollup_stake_storage.cement_commitment ctxt rollup c2 in + let* ctxt = Sc_rollup_stake_storage.cement_commitment ctxt rollup c3 in assert_true ctxt let test_cement_then_remove () = @@ -512,11 +645,17 @@ let test_cement_then_remove () = let staker = Sc_rollup_repr.Staker.of_b58check_exn "tz1SdKt9kjPp1HRQFkBmXtBhgMfvdgFhSjmG" in - let* ctxt = lift @@ Sc_rollup_storage.deposit_stake ctxt rollup staker in + let* ctxt = + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.deposit_stake + ctxt + rollup + staker + in let commitment = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = valid_inbox_level ctxt 1l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -524,13 +663,20 @@ let test_cement_then_remove () = } in let* c1, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker commitment + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker + commitment in let ctxt = Raw_context.Internal_for_tests.add_level ctxt challenge_window in - let* ctxt = lift @@ Sc_rollup_storage.cement_commitment ctxt rollup c1 in + let* ctxt = + lift @@ Sc_rollup_stake_storage.cement_commitment ctxt rollup c1 + in assert_fails_with ~loc:__LOC__ - (Sc_rollup_storage.remove_staker ctxt rollup staker) + (Sc_rollup_stake_storage.remove_staker ctxt rollup staker) "Can not remove a cemented commitment." let test_cement_consumes_available_messages () = @@ -542,17 +688,24 @@ let test_cement_consumes_available_messages () = let staker = Sc_rollup_repr.Staker.of_b58check_exn "tz1SdKt9kjPp1HRQFkBmXtBhgMfvdgFhSjmG" in - let* ctxt = lift @@ Sc_rollup_storage.deposit_stake ctxt rollup staker in + let* ctxt = + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.deposit_stake + ctxt + rollup + staker + in let* inbox, _n, ctxt = - lift @@ Sc_rollup_storage.add_messages ctxt rollup ["one"; "two"; "three"] + lift + @@ Sc_rollup_inbox_storage.add_messages ctxt rollup ["one"; "two"; "three"] in let available_messages = Sc_rollup_inbox_repr.number_of_available_messages inbox in let commitment = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = valid_inbox_level ctxt 1l; number_of_messages = number_of_messages_exn 1l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -560,11 +713,18 @@ let test_cement_consumes_available_messages () = } in let* c1, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker commitment + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker + commitment in let ctxt = Raw_context.Internal_for_tests.add_level ctxt challenge_window in - let* ctxt = lift @@ Sc_rollup_storage.cement_commitment ctxt rollup c1 in - let* new_inbox, _ctxt = lift @@ Sc_rollup_storage.inbox ctxt rollup in + let* ctxt = + lift @@ Sc_rollup_stake_storage.cement_commitment ctxt rollup c1 + in + let* new_inbox, _ctxt = lift @@ Sc_rollup_inbox_storage.inbox ctxt rollup in let new_available_messages = Sc_rollup_inbox_repr.number_of_available_messages new_inbox in @@ -590,13 +750,19 @@ let test_cement_unknown_commitment_fails () = Sc_rollup_repr.Staker.of_b58check_exn "tz1SdKt9kjPp1HRQFkBmXtBhgMfvdgFhSjmG" in let ctxt = Raw_context.Internal_for_tests.add_level ctxt challenge_window in - let* ctxt = lift @@ Sc_rollup_storage.deposit_stake ctxt rollup staker in + let* ctxt = + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.deposit_stake + ctxt + rollup + staker + in assert_fails_with ~loc:__LOC__ - (Sc_rollup_storage.cement_commitment + (Sc_rollup_stake_storage.cement_commitment ctxt rollup - Sc_rollup_repr.Commitment_hash.zero) + Commitment_repr.Hash.zero) "Commitment scc12XhSULdV8bAav21e99VYLTpqAjTd7NU8Mn4zFdKPSA8auMbggG does \ not exist" @@ -609,11 +775,17 @@ let test_cement_with_zero_stakers_fails () = let staker = Sc_rollup_repr.Staker.of_b58check_exn "tz1SdKt9kjPp1HRQFkBmXtBhgMfvdgFhSjmG" in - let* ctxt = lift @@ Sc_rollup_storage.deposit_stake ctxt rollup staker in + let* ctxt = + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.deposit_stake + ctxt + rollup + staker + in let commitment = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = valid_inbox_level ctxt 1l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -621,14 +793,21 @@ let test_cement_with_zero_stakers_fails () = } in let* c1, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker commitment + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker + commitment in let ctxt = Raw_context.Internal_for_tests.add_level ctxt challenge_window in - let* ctxt = lift @@ Sc_rollup_storage.remove_staker ctxt rollup staker in + let* ctxt = + lift @@ Sc_rollup_stake_storage.remove_staker ctxt rollup staker + in assert_fails_with ~loc:__LOC__ - (Sc_rollup_storage.cement_commitment ctxt rollup c1) + (Sc_rollup_stake_storage.cement_commitment ctxt rollup c1) "No stakers." let test_cement_fail_too_recent () = @@ -641,11 +820,17 @@ let test_cement_fail_too_recent () = let staker = Sc_rollup_repr.Staker.of_b58check_exn "tz1SdKt9kjPp1HRQFkBmXtBhgMfvdgFhSjmG" in - let* ctxt = lift @@ Sc_rollup_storage.deposit_stake ctxt rollup staker in + let* ctxt = + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.deposit_stake + ctxt + rollup + staker + in let commitment = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = level 1l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -653,12 +838,17 @@ let test_cement_fail_too_recent () = } in let* c1, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker commitment + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker + commitment in let* () = assert_fails_with ~loc:__LOC__ - (Sc_rollup_storage.cement_commitment ctxt rollup c1) + (Sc_rollup_stake_storage.cement_commitment ctxt rollup c1) "Attempted to cement a commitment before its refutation deadline." in let ctxt = @@ -667,7 +857,7 @@ let test_cement_fail_too_recent () = let* () = assert_fails_with ~loc:__LOC__ - (Sc_rollup_storage.cement_commitment ctxt rollup c1) + (Sc_rollup_stake_storage.cement_commitment ctxt rollup c1) "Attempted to cement a commitment before its refutation deadline." in assert_true ctxt @@ -677,9 +867,9 @@ let test_cement_deadline_uses_oldest_add_time () = originate_rollup_and_deposit_with_two_stakers () in let commitment = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = valid_inbox_level ctxt 1l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -687,7 +877,12 @@ let test_cement_deadline_uses_oldest_add_time () = } in let* c1, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker1 commitment + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker1 + commitment in let challenge_window = Constants_storage.sc_rollup_challenge_window_in_blocks ctxt @@ -695,9 +890,16 @@ let test_cement_deadline_uses_oldest_add_time () = let ctxt = Raw_context.Internal_for_tests.add_level ctxt challenge_window in let* c2, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker2 commitment + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker2 + commitment + in + let* ctxt = + lift @@ Sc_rollup_stake_storage.cement_commitment ctxt rollup c1 in - let* ctxt = lift @@ Sc_rollup_storage.cement_commitment ctxt rollup c1 in assert_commitment_hash_equal ~loc:__LOC__ ctxt c1 c2 let test_last_cemented_commitment_hash_with_level () = @@ -710,11 +912,17 @@ let test_last_cemented_commitment_hash_with_level () = Sc_rollup_repr.Staker.of_b58check_exn "tz1SdKt9kjPp1HRQFkBmXtBhgMfvdgFhSjmG" in let inbox_level = valid_inbox_level ctxt 1l in - let* ctxt = lift @@ Sc_rollup_storage.deposit_stake ctxt rollup staker in + let* ctxt = + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.deposit_stake + ctxt + rollup + staker + in let commitment = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -722,13 +930,22 @@ let test_last_cemented_commitment_hash_with_level () = } in let* c1, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker commitment + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker + commitment in let ctxt = Raw_context.Internal_for_tests.add_level ctxt challenge_window in - let* ctxt = lift @@ Sc_rollup_storage.cement_commitment ctxt rollup c1 in + let* ctxt = + lift @@ Sc_rollup_stake_storage.cement_commitment ctxt rollup c1 + in let* c1', inbox_level', ctxt = lift - @@ Sc_rollup_storage.last_cemented_commitment_hash_with_level ctxt rollup + @@ Sc_rollup_commitment_storage.last_cemented_commitment_hash_with_level + ctxt + rollup in let* () = assert_commitment_hash_equal ~loc:__LOC__ ctxt c1 c1' in Assert.equal_int32 @@ -742,11 +959,17 @@ let test_withdrawal_fails_when_not_staked_on_lcc () = let staker = Sc_rollup_repr.Staker.of_b58check_exn "tz1SdKt9kjPp1HRQFkBmXtBhgMfvdgFhSjmG" in - let* ctxt = lift @@ Sc_rollup_storage.deposit_stake ctxt rollup staker in + let* ctxt = + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.deposit_stake + ctxt + rollup + staker + in let commitment = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = valid_inbox_level ctxt 1l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -754,11 +977,19 @@ let test_withdrawal_fails_when_not_staked_on_lcc () = } in let* _node, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker commitment + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker + commitment in assert_fails_with ~loc:__LOC__ - (Sc_rollup_storage.withdraw_stake ctxt rollup staker) + (Sc_rollup_stake_storage.Internal_for_tests.withdraw_stake + ctxt + rollup + staker) "Attempted to withdraw while not staked on the last cemented commitment." let test_initial_level_of_rollup () = @@ -777,9 +1008,9 @@ let test_stake_on_existing_node () = originate_rollup_and_deposit_with_two_stakers () in let commitment = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = valid_inbox_level ctxt 1l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -788,10 +1019,18 @@ let test_stake_on_existing_node () = in lift @@ let* _node, _level, ctxt = - Sc_rollup_storage.refine_stake ctxt rollup staker1 commitment + Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker1 + commitment in let* _node, _level, ctxt = - Sc_rollup_storage.refine_stake ctxt rollup staker2 commitment + Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker2 + commitment in assert_true ctxt @@ -801,9 +1040,9 @@ let test_cement_with_two_stakers () = in let level = valid_inbox_level ctxt in let commitment1 = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = level 1l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -812,10 +1051,14 @@ let test_cement_with_two_stakers () = in lift @@ let* c1, _level, ctxt = - Sc_rollup_storage.refine_stake ctxt rollup staker1 commitment1 + Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker1 + commitment1 in let commitment2 = - Sc_rollup_repr.Commitment. + Commitment_repr. { predecessor = c1; inbox_level = level 2l; @@ -825,7 +1068,11 @@ let test_cement_with_two_stakers () = } in let* _node, _level, ctxt = - Sc_rollup_storage.refine_stake ctxt rollup staker2 commitment2 + Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker2 + commitment2 in let challenge_window = Constants_storage.sc_rollup_challenge_window_in_blocks ctxt @@ -834,7 +1081,7 @@ let test_cement_with_two_stakers () = 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_stake_storage.cement_commitment ctxt rollup c1 in assert_true ctxt let test_can_remove_staker () = @@ -843,9 +1090,9 @@ let test_can_remove_staker () = in let level = valid_inbox_level ctxt in let commitment1 = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = level 1l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -854,10 +1101,14 @@ let test_can_remove_staker () = in lift @@ let* c1, _level, ctxt = - Sc_rollup_storage.refine_stake ctxt rollup staker1 commitment1 + Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker1 + commitment1 in let commitment2 = - Sc_rollup_repr.Commitment. + Commitment_repr. { predecessor = c1; inbox_level = level 2l; @@ -867,16 +1118,20 @@ let test_can_remove_staker () = } in let* _node, _level, ctxt = - Sc_rollup_storage.refine_stake ctxt rollup staker2 commitment2 + Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker2 + commitment2 in - let* ctxt = Sc_rollup_storage.remove_staker ctxt rollup staker1 in + let* ctxt = Sc_rollup_stake_storage.remove_staker ctxt rollup staker1 in let challenge_window = Constants_storage.sc_rollup_challenge_window_in_blocks ctxt 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_stake_storage.cement_commitment ctxt rollup c1 in assert_true ctxt let test_can_remove_staker2 () = @@ -885,9 +1140,9 @@ let test_can_remove_staker2 () = in let level = valid_inbox_level ctxt in let commitment1 = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = level 1l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -896,10 +1151,14 @@ let test_can_remove_staker2 () = in lift @@ let* c1, _level, ctxt = - Sc_rollup_storage.refine_stake ctxt rollup staker1 commitment1 + Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker1 + commitment1 in let commitment2 = - Sc_rollup_repr.Commitment. + Commitment_repr. { predecessor = c1; inbox_level = level 2l; @@ -909,9 +1168,13 @@ let test_can_remove_staker2 () = } in let* _node, _level, ctxt = - Sc_rollup_storage.refine_stake ctxt rollup staker2 commitment2 + Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker2 + commitment2 in - let* ctxt = Sc_rollup_storage.remove_staker ctxt rollup staker2 in + let* ctxt = Sc_rollup_stake_storage.remove_staker ctxt rollup staker2 in let challenge_window = Constants_storage.sc_rollup_challenge_window_in_blocks ctxt in @@ -919,7 +1182,7 @@ let test_can_remove_staker2 () = 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_stake_storage.cement_commitment ctxt rollup c1 in assert_true ctxt let test_removed_staker_can_not_withdraw () = @@ -928,9 +1191,9 @@ let test_removed_staker_can_not_withdraw () = in let level = valid_inbox_level ctxt in let commitment1 = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = level 1l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -938,10 +1201,15 @@ let test_removed_staker_can_not_withdraw () = } in let* c1, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker1 commitment1 + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker1 + commitment1 in let commitment2 = - Sc_rollup_repr.Commitment. + Commitment_repr. { predecessor = c1; inbox_level = level 2l; @@ -951,12 +1219,22 @@ let test_removed_staker_can_not_withdraw () = } in let* _node, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker2 commitment2 + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker2 + commitment2 + in + let* ctxt = + lift @@ Sc_rollup_stake_storage.remove_staker ctxt rollup staker2 in - let* ctxt = lift @@ Sc_rollup_storage.remove_staker ctxt rollup staker2 in assert_fails_with ~loc:__LOC__ - (Sc_rollup_storage.withdraw_stake ctxt rollup staker2) + (Sc_rollup_stake_storage.Internal_for_tests.withdraw_stake + ctxt + rollup + staker2) "Unknown staker." let test_no_cement_on_conflict () = @@ -965,9 +1243,9 @@ let test_no_cement_on_conflict () = in let level = valid_inbox_level ctxt in let commitment1 = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = level 1l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -975,12 +1253,17 @@ let test_no_cement_on_conflict () = } in let* c1, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker1 commitment1 + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker1 + commitment1 in let commitment2 = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = level 1l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 44l; @@ -988,12 +1271,17 @@ let test_no_cement_on_conflict () = } in let* _node, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker2 commitment2 + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker2 + commitment2 in let ctxt = Raw_context.Internal_for_tests.add_level ctxt 5000 in assert_fails_with ~loc:__LOC__ - (Sc_rollup_storage.cement_commitment ctxt rollup c1) + (Sc_rollup_stake_storage.cement_commitment ctxt rollup c1) "Attempted to cement a disputed commitment." (** Tests that [c1] can not be finalized in the following scenario: @@ -1007,9 +1295,9 @@ let test_no_cement_with_one_staker_at_zero_commitment () = originate_rollup_and_deposit_with_two_stakers () in let commitment1 = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = valid_inbox_level ctxt 1l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -1017,7 +1305,12 @@ let test_no_cement_with_one_staker_at_zero_commitment () = } in let* c1, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker1 commitment1 + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker1 + commitment1 in let challenge_window = Constants_storage.sc_rollup_challenge_window_in_blocks ctxt @@ -1025,7 +1318,7 @@ let test_no_cement_with_one_staker_at_zero_commitment () = let ctxt = Raw_context.Internal_for_tests.add_level ctxt challenge_window in assert_fails_with ~loc:__LOC__ - (Sc_rollup_storage.cement_commitment ctxt rollup c1) + (Sc_rollup_stake_storage.cement_commitment ctxt rollup c1) "Attempted to cement a disputed commitment." let test_non_cemented_parent () = @@ -1034,9 +1327,9 @@ let test_non_cemented_parent () = in let level = valid_inbox_level ctxt in let commitment1 = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = level 1l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -1044,10 +1337,15 @@ let test_non_cemented_parent () = } in let* c1, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker1 commitment1 + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker1 + commitment1 in let commitment2 = - Sc_rollup_repr.Commitment. + Commitment_repr. { predecessor = c1; inbox_level = level 2l; @@ -1057,7 +1355,12 @@ let test_non_cemented_parent () = } in let* c2, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker2 commitment2 + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker2 + commitment2 in let challenge_window = Constants_storage.sc_rollup_challenge_window_in_blocks ctxt @@ -1065,7 +1368,7 @@ let test_non_cemented_parent () = let ctxt = Raw_context.Internal_for_tests.add_level ctxt challenge_window in assert_fails_with ~loc:__LOC__ - (Sc_rollup_storage.cement_commitment ctxt rollup c2) + (Sc_rollup_stake_storage.cement_commitment ctxt rollup c2) "Parent is not cemented." let test_finds_conflict_point_at_lcc () = @@ -1074,9 +1377,9 @@ let test_finds_conflict_point_at_lcc () = in let level = valid_inbox_level ctxt in let commitment1 = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = level 1l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -1084,12 +1387,17 @@ let test_finds_conflict_point_at_lcc () = } in let* c1, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker1 commitment1 + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker1 + commitment1 in let commitment2 = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = level 1l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 55l; @@ -1097,10 +1405,20 @@ let test_finds_conflict_point_at_lcc () = } in let* _c2, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker2 commitment2 + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker2 + commitment2 in let* (left, _right), ctxt = - lift @@ Sc_rollup_storage.get_conflict_point ctxt rollup staker1 staker2 + lift + @@ Sc_rollup_refutation_storage.Internal_for_tests.get_conflict_point + ctxt + rollup + staker1 + staker2 in assert_commitment_hash_equal ~loc:__LOC__ ctxt left c1 @@ -1110,9 +1428,9 @@ let test_finds_conflict_point_beneath_lcc () = in let level = valid_inbox_level ctxt in let commitment1 = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = level 1l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -1120,10 +1438,15 @@ let test_finds_conflict_point_beneath_lcc () = } in let* c1, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker1 commitment1 + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker1 + commitment1 in let commitment2 = - Sc_rollup_repr.Commitment. + Commitment_repr. { predecessor = c1; inbox_level = level 2l; @@ -1133,10 +1456,15 @@ let test_finds_conflict_point_beneath_lcc () = } in let* c2, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker1 commitment2 + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker1 + commitment2 in let commitment3 = - Sc_rollup_repr.Commitment. + Commitment_repr. { predecessor = c1; inbox_level = level 2l; @@ -1146,10 +1474,20 @@ let test_finds_conflict_point_beneath_lcc () = } in let* c3, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker2 commitment3 + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker2 + commitment3 in let* (left, right), ctxt = - lift @@ Sc_rollup_storage.get_conflict_point ctxt rollup staker1 staker2 + lift + @@ Sc_rollup_refutation_storage.Internal_for_tests.get_conflict_point + ctxt + rollup + staker1 + staker2 in let* () = assert_commitment_hash_equal ~loc:__LOC__ ctxt left c2 in assert_commitment_hash_equal ~loc:__LOC__ ctxt right c3 @@ -1160,9 +1498,9 @@ let test_conflict_point_is_first_point_of_disagreement () = in let level = valid_inbox_level ctxt in let commitment1 = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = level 1l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -1170,10 +1508,15 @@ let test_conflict_point_is_first_point_of_disagreement () = } in let* c1, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker1 commitment1 + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker1 + commitment1 in let commitment2 = - Sc_rollup_repr.Commitment. + Commitment_repr. { predecessor = c1; inbox_level = level 2l; @@ -1183,10 +1526,15 @@ let test_conflict_point_is_first_point_of_disagreement () = } in let* c2, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker1 commitment2 + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker1 + commitment2 in let commitment3 = - Sc_rollup_repr.Commitment. + Commitment_repr. { predecessor = c1; inbox_level = level 2l; @@ -1196,10 +1544,15 @@ let test_conflict_point_is_first_point_of_disagreement () = } in let* c3, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker2 commitment3 + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker2 + commitment3 in let commitment4 = - Sc_rollup_repr.Commitment. + Commitment_repr. { predecessor = c2; inbox_level = level 3l; @@ -1209,10 +1562,20 @@ let test_conflict_point_is_first_point_of_disagreement () = } in let* _c4, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker1 commitment4 + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker1 + commitment4 in let* (left, right), ctxt = - lift @@ Sc_rollup_storage.get_conflict_point ctxt rollup staker1 staker2 + lift + @@ Sc_rollup_refutation_storage.Internal_for_tests.get_conflict_point + ctxt + rollup + staker1 + staker2 in let* () = assert_commitment_hash_equal ~loc:__LOC__ ctxt left c2 in assert_commitment_hash_equal ~loc:__LOC__ ctxt right c3 @@ -1233,9 +1596,9 @@ let test_conflict_point_computation_fits_in_gas_limit () = (Int32.of_int commitment_freq) in let root_commitment = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = level 1l; number_of_messages = number_of_messages_exn 1l; number_of_ticks = number_of_ticks_exn 1l; @@ -1243,14 +1606,24 @@ let test_conflict_point_computation_fits_in_gas_limit () = } in let* root_commitment_hash, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker1 root_commitment + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker1 + root_commitment in let* _node, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker2 root_commitment + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker2 + root_commitment in let rec branch ctxt staker_id staker predecessor i max acc = let commitment = - Sc_rollup_repr.Commitment. + Commitment_repr. { predecessor; inbox_level = level i; @@ -1260,7 +1633,12 @@ let test_conflict_point_computation_fits_in_gas_limit () = } in let* commitment_hash, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker commitment + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker + commitment in if i = max then return (Array.of_list (List.rev (commitment_hash :: acc)), ctxt) @@ -1286,7 +1664,12 @@ let test_conflict_point_computation_fits_in_gas_limit () = (Constants_storage.hard_gas_limit_per_operation ctxt) in let* (left, right), ctxt = - lift @@ Sc_rollup_storage.get_conflict_point ctxt rollup staker1 staker2 + lift + @@ Sc_rollup_refutation_storage.Internal_for_tests.get_conflict_point + ctxt + rollup + staker1 + staker2 in let* () = assert_commitment_hash_equal ~loc:__LOC__ ctxt left branch_1.(0) in assert_commitment_hash_equal ~loc:__LOC__ ctxt right branch_2.(0) @@ -1296,9 +1679,9 @@ let test_no_conflict_point_one_staker_at_lcc_preboot () = originate_rollup_and_deposit_with_two_stakers () in let commitment = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = valid_inbox_level ctxt 1l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -1306,11 +1689,20 @@ let test_no_conflict_point_one_staker_at_lcc_preboot () = } in let* _, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker1 commitment + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker1 + commitment in assert_fails_with ~loc:__LOC__ - (Sc_rollup_storage.get_conflict_point ctxt rollup staker1 staker2) + (Sc_rollup_refutation_storage.Internal_for_tests.get_conflict_point + ctxt + rollup + staker1 + staker2) "No conflict." let test_no_conflict_point_both_stakers_at_lcc_preboot () = @@ -1319,7 +1711,11 @@ let test_no_conflict_point_both_stakers_at_lcc_preboot () = in assert_fails_with ~loc:__LOC__ - (Sc_rollup_storage.get_conflict_point ctxt rollup staker1 staker2) + (Sc_rollup_refutation_storage.Internal_for_tests.get_conflict_point + ctxt + rollup + staker1 + staker2) "No conflict." let test_no_conflict_point_one_staker_at_lcc () = @@ -1328,9 +1724,9 @@ let test_no_conflict_point_one_staker_at_lcc () = in let level = valid_inbox_level ctxt in let commitment1 = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = level 1l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -1338,10 +1734,15 @@ let test_no_conflict_point_one_staker_at_lcc () = } in let* c1, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker1 commitment1 + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker1 + commitment1 in let commitment2 = - Sc_rollup_repr.Commitment. + Commitment_repr. { predecessor = c1; inbox_level = level 2l; @@ -1351,16 +1752,27 @@ let test_no_conflict_point_one_staker_at_lcc () = } in let* _node, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker2 commitment2 + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker2 + commitment2 in let challenge_window = Constants_storage.sc_rollup_challenge_window_in_blocks ctxt in let ctxt = Raw_context.Internal_for_tests.add_level ctxt challenge_window in - let* ctxt = lift @@ Sc_rollup_storage.cement_commitment ctxt rollup c1 in + let* ctxt = + lift @@ Sc_rollup_stake_storage.cement_commitment ctxt rollup c1 + in assert_fails_with ~loc:__LOC__ - (Sc_rollup_storage.get_conflict_point ctxt rollup staker1 staker2) + (Sc_rollup_refutation_storage.Internal_for_tests.get_conflict_point + ctxt + rollup + staker1 + staker2) "No conflict." let test_no_conflict_point_both_stakers_at_lcc () = @@ -1368,9 +1780,9 @@ let test_no_conflict_point_both_stakers_at_lcc () = originate_rollup_and_deposit_with_two_stakers () in let commitment1 = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = valid_inbox_level ctxt 1l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -1378,19 +1790,35 @@ let test_no_conflict_point_both_stakers_at_lcc () = } in let* c1, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker1 commitment1 + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker1 + commitment1 in let* _node, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker2 commitment1 + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker2 + commitment1 in let challenge_window = Constants_storage.sc_rollup_challenge_window_in_blocks ctxt in let ctxt = Raw_context.Internal_for_tests.add_level ctxt challenge_window in - let* ctxt = lift @@ Sc_rollup_storage.cement_commitment ctxt rollup c1 in + let* ctxt = + lift @@ Sc_rollup_stake_storage.cement_commitment ctxt rollup c1 + in assert_fails_with ~loc:__LOC__ - (Sc_rollup_storage.get_conflict_point ctxt rollup staker1 staker2) + (Sc_rollup_refutation_storage.Internal_for_tests.get_conflict_point + ctxt + rollup + staker1 + staker2) "No conflict." let test_staker_cannot_backtrack () = @@ -1399,12 +1827,18 @@ let test_staker_cannot_backtrack () = let staker = Sc_rollup_repr.Staker.of_b58check_exn "tz1SdKt9kjPp1HRQFkBmXtBhgMfvdgFhSjmG" in - let* ctxt = lift @@ Sc_rollup_storage.deposit_stake ctxt rollup staker in + let* ctxt = + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.deposit_stake + ctxt + rollup + staker + in let level = valid_inbox_level ctxt in let commitment1 = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = level 1l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -1412,10 +1846,15 @@ let test_staker_cannot_backtrack () = } in let* c1, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker commitment1 + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker + commitment1 in let commitment2 = - Sc_rollup_repr.Commitment. + Commitment_repr. { predecessor = c1; inbox_level = level 2l; @@ -1425,11 +1864,20 @@ let test_staker_cannot_backtrack () = } in let* _, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker commitment2 + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker + commitment2 in assert_fails_with ~loc:__LOC__ - (Sc_rollup_storage.refine_stake ctxt rollup staker commitment1) + (Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker + commitment1) "Staker backtracked." let test_staker_cannot_change_branch () = @@ -1438,9 +1886,9 @@ let test_staker_cannot_change_branch () = in let level = valid_inbox_level ctxt in let commitment1 = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = level 1l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -1448,10 +1896,15 @@ let test_staker_cannot_change_branch () = } in let* c1, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker1 commitment1 + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker1 + commitment1 in let commitment2 = - Sc_rollup_repr.Commitment. + Commitment_repr. { predecessor = c1; inbox_level = level 2l; @@ -1461,10 +1914,15 @@ let test_staker_cannot_change_branch () = } in let* c2, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker1 commitment2 + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker1 + commitment2 in let commitment3 = - Sc_rollup_repr.Commitment. + Commitment_repr. { predecessor = c1; inbox_level = level 2l; @@ -1475,10 +1933,15 @@ let test_staker_cannot_change_branch () = in let* _c3, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker2 commitment3 + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker2 + commitment3 in let commitment4 = - Sc_rollup_repr.Commitment. + Commitment_repr. { predecessor = c2; inbox_level = level 3l; @@ -1488,11 +1951,20 @@ let test_staker_cannot_change_branch () = } in let* _c4, _level, ctxt = - lift @@ Sc_rollup_storage.refine_stake ctxt rollup staker1 commitment4 + lift + @@ Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker1 + commitment4 in assert_fails_with ~loc:__LOC__ - (Sc_rollup_storage.refine_stake ctxt rollup staker2 commitment4) + (Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker2 + commitment4) "Staker backtracked." let test_kind_of_missing_rollup () = @@ -1503,20 +1975,20 @@ let test_kind_of_missing_rollup () = let test_add_messages_from_missing_rollup () = assert_fails_with_missing_rollup ~loc:__LOC__ (fun ctxt rollup -> - Sc_rollup_storage.add_messages ctxt rollup ["Dummy message"]) + Sc_rollup_inbox_storage.add_messages ctxt rollup ["Dummy message"]) let test_inbox_of_missing_rollup () = - assert_fails_with_missing_rollup ~loc:__LOC__ Sc_rollup_storage.inbox + assert_fails_with_missing_rollup ~loc:__LOC__ Sc_rollup_inbox_storage.inbox let test_refine_stake_of_missing_rollup () = assert_fails_with_missing_rollup ~loc:__LOC__ (fun ctxt rollup -> - Sc_rollup_storage.refine_stake + Sc_rollup_stake_storage.Internal_for_tests.refine_stake ctxt rollup Sc_rollup_repr.Staker.zero - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = valid_inbox_level ctxt 1l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -1526,23 +1998,23 @@ let test_refine_stake_of_missing_rollup () = let test_last_cemented_commitment_of_missing_rollup () = assert_fails_with_missing_rollup ~loc:__LOC__ - Sc_rollup_storage.last_cemented_commitment + Sc_rollup_commitment_storage.last_cemented_commitment let test_last_cemented_commitment_hash_with_level_of_missing_rollup () = assert_fails_with_missing_rollup ~loc:__LOC__ - Sc_rollup_storage.last_cemented_commitment_hash_with_level + Sc_rollup_commitment_storage.last_cemented_commitment_hash_with_level let test_cement_commitment_of_missing_rollup () = assert_fails_with_missing_rollup ~loc:__LOC__ (fun ctxt rollup -> - Sc_rollup_storage.cement_commitment + Sc_rollup_stake_storage.cement_commitment ctxt rollup - Sc_rollup_repr.Commitment_hash.zero) + Commitment_repr.Hash.zero) let test_get_conflict_point_on_missing_rollup () = assert_fails_with_missing_rollup ~loc:__LOC__ (fun ctxt rollup -> - Sc_rollup_storage.get_conflict_point + Sc_rollup_refutation_storage.Internal_for_tests.get_conflict_point ctxt rollup Sc_rollup_repr.Staker.zero @@ -1550,24 +2022,27 @@ let test_get_conflict_point_on_missing_rollup () = let test_get_commitment_of_missing_rollup () = assert_fails_with_missing_rollup ~loc:__LOC__ (fun ctxt rollup -> - Sc_rollup_storage.get_commitment + Sc_rollup_commitment_storage.get_commitment ctxt rollup - Sc_rollup_repr.Commitment_hash.zero) + Commitment_repr.Hash.zero) let test_get_missing_commitment () = let* ctxt = new_context () in let* rollup, ctxt = lift @@ new_sc_rollup ctxt in - let commitment_hash = Sc_rollup_repr.Commitment_hash.zero in + let commitment_hash = Commitment_repr.Hash.zero in assert_fails_with ~loc:__LOC__ - (Sc_rollup_storage.get_commitment ctxt rollup commitment_hash) + (Sc_rollup_commitment_storage.get_commitment ctxt rollup commitment_hash) "Commitment scc12XhSULdV8bAav21e99VYLTpqAjTd7NU8Mn4zFdKPSA8auMbggG does \ not exist" let test_remove_staker_from_missing_rollup () = assert_fails_with_missing_rollup ~loc:__LOC__ (fun ctxt rollup -> - Sc_rollup_storage.remove_staker ctxt rollup Sc_rollup_repr.Staker.zero) + Sc_rollup_stake_storage.remove_staker + ctxt + rollup + Sc_rollup_repr.Staker.zero) let test_initial_level_of_missing_rollup () = assert_fails_with_missing_rollup ~loc:__LOC__ Sc_rollup_storage.initial_level @@ -1578,9 +2053,9 @@ let test_concurrent_refinement_point_of_conflict () = in let level = valid_inbox_level before_ctxt in let commitment1 = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = level 1l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -1588,9 +2063,9 @@ let test_concurrent_refinement_point_of_conflict () = } in let commitment2 = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = level 1l; number_of_messages = number_of_messages_exn 10l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -1600,22 +2075,46 @@ let test_concurrent_refinement_point_of_conflict () = let* (c1, c2), _ctxt = lift @@ let* _c1, _level, ctxt = - Sc_rollup_storage.refine_stake before_ctxt rollup staker1 commitment1 + Sc_rollup_stake_storage.Internal_for_tests.refine_stake + before_ctxt + rollup + staker1 + commitment1 in let* _c2, _level, ctxt = - Sc_rollup_storage.refine_stake ctxt rollup staker2 commitment2 + Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker2 + commitment2 in - Sc_rollup_storage.get_conflict_point ctxt rollup staker1 staker2 + Sc_rollup_refutation_storage.Internal_for_tests.get_conflict_point + ctxt + rollup + staker1 + staker2 in let* (c1', c2'), ctxt = lift @@ let* _c2, _level, ctxt = - Sc_rollup_storage.refine_stake before_ctxt rollup staker2 commitment2 + Sc_rollup_stake_storage.Internal_for_tests.refine_stake + before_ctxt + rollup + staker2 + commitment2 in let* _c1, _level, ctxt = - Sc_rollup_storage.refine_stake ctxt rollup staker1 commitment1 + Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker1 + commitment1 in - Sc_rollup_storage.get_conflict_point ctxt rollup staker1 staker2 + Sc_rollup_refutation_storage.Internal_for_tests.get_conflict_point + ctxt + rollup + staker1 + staker2 in let* () = assert_commitment_hash_equal ~loc:__LOC__ ctxt c1 c1' in assert_commitment_hash_equal ~loc:__LOC__ ctxt c2 c2' @@ -1625,9 +2124,9 @@ let test_concurrent_refinement_cement () = originate_rollup_and_deposit_with_two_stakers () in let commitment = - Sc_rollup_repr.Commitment. + Commitment_repr. { - predecessor = Sc_rollup_repr.Commitment_hash.zero; + predecessor = Commitment_repr.Hash.zero; inbox_level = valid_inbox_level before_ctxt 1l; number_of_messages = number_of_messages_exn 3l; number_of_ticks = number_of_ticks_exn 1232909l; @@ -1637,10 +2136,18 @@ let test_concurrent_refinement_cement () = let* c1, _ctxt = lift @@ let* c1, _level, ctxt = - Sc_rollup_storage.refine_stake before_ctxt rollup staker1 commitment + Sc_rollup_stake_storage.Internal_for_tests.refine_stake + before_ctxt + rollup + staker1 + commitment in let* _c2, _level, ctxt = - Sc_rollup_storage.refine_stake ctxt rollup staker2 commitment + Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker2 + commitment in let challenge_window = Constants_storage.sc_rollup_challenge_window_in_blocks ctxt @@ -1648,16 +2155,24 @@ let test_concurrent_refinement_cement () = let ctxt = Raw_context.Internal_for_tests.add_level ctxt challenge_window in - let* ctxt = Sc_rollup_storage.cement_commitment ctxt rollup c1 in - Sc_rollup_storage.last_cemented_commitment ctxt rollup + let* ctxt = Sc_rollup_stake_storage.cement_commitment ctxt rollup c1 in + Sc_rollup_commitment_storage.last_cemented_commitment ctxt rollup in let* c2, ctxt = lift @@ let* c2, _level, ctxt = - Sc_rollup_storage.refine_stake before_ctxt rollup staker2 commitment + Sc_rollup_stake_storage.Internal_for_tests.refine_stake + before_ctxt + rollup + staker2 + commitment in let* _c1, _level, ctxt = - Sc_rollup_storage.refine_stake ctxt rollup staker1 commitment + Sc_rollup_stake_storage.Internal_for_tests.refine_stake + ctxt + rollup + staker1 + commitment in let challenge_window = Constants_storage.sc_rollup_challenge_window_in_blocks ctxt @@ -1665,8 +2180,8 @@ let test_concurrent_refinement_cement () = let ctxt = Raw_context.Internal_for_tests.add_level ctxt challenge_window in - let* ctxt = Sc_rollup_storage.cement_commitment ctxt rollup c2 in - Sc_rollup_storage.last_cemented_commitment ctxt rollup + let* ctxt = Sc_rollup_stake_storage.cement_commitment ctxt rollup c2 in + Sc_rollup_commitment_storage.last_cemented_commitment ctxt rollup in assert_commitment_hash_equal ~loc:__LOC__ ctxt c1 c2 @@ -1709,7 +2224,7 @@ let test_carbonated_memory_inbox_set_messages () = set_gas_limit ctxt (Gas_limit_repr.Arith.integral_of_int_exn 20_000) in let* rollup, ctxt = lift @@ new_sc_rollup ctxt in - let* inbox, ctxt = lift @@ Sc_rollup_storage.inbox ctxt rollup in + let* inbox, ctxt = lift @@ Sc_rollup_inbox_storage.inbox ctxt rollup in let*? current_messages, ctxt = Environment.wrap_tzresult @@ Sc_rollup_in_memory_inbox.current_messages ctxt rollup @@ -1756,7 +2271,7 @@ let test_limit_on_number_of_messages_during_commitment_period with_gap () = else ctxt in let* _inbox, _size_diff, ctxt = - lift @@ Sc_rollup_storage.add_messages ctxt rollup payload + lift @@ Sc_rollup_inbox_storage.add_messages ctxt rollup payload in return ctxt) ctxt @@ -1769,7 +2284,7 @@ let test_limit_on_number_of_messages_during_commitment_period with_gap () = else (* ... but if we stay in the same commitment period, it fails. *) Assert.proto_error ~loc:__LOC__ add_too_many_messages @@ function - | Sc_rollup_storage + | Sc_rollup_errors .Sc_rollup_max_number_of_messages_reached_for_commitment_period -> true | _ -> false diff --git a/src/proto_alpha/lib_sc_rollup/sc_rollup_services.ml b/src/proto_alpha/lib_sc_rollup/sc_rollup_services.ml index 1f7cc230d0d2f6a8b3596c30b0152c08611932c0..1e6f7abaabc2b6b1446bf2577fd0ff8e4695a533 100644 --- a/src/proto_alpha/lib_sc_rollup/sc_rollup_services.ml +++ b/src/proto_alpha/lib_sc_rollup/sc_rollup_services.ml @@ -31,7 +31,7 @@ let commitment_with_hash_and_level_encoding = Data_encoding.( obj3 (req "commitment" Sc_rollup.Commitment.encoding) - (req "hash" Sc_rollup.Commitment_hash.encoding) + (req "hash" Sc_rollup.Commitment.Hash.encoding) (opt "published_at_level" Raw_level.encoding)) let sc_rollup_address () =