diff --git a/docs/protocols/alpha.rst b/docs/protocols/alpha.rst index bdb8f02055f6abb60b94412ba45ca8d4a0bd41d9..ac9f1a3fdda248f3b530bd71374b0593c7738379 100644 --- a/docs/protocols/alpha.rst +++ b/docs/protocols/alpha.rst @@ -18,6 +18,9 @@ It requires protocol environment V10, compared to V9 for Nairobi. Smart Rollups ------------- +- Add the support for bootstrapped smart rollups in storage initialization, + similarly to bootstrapped accounts and smart contracts. (MR :gl:`!8552`) + Zero Knowledge Rollups (ongoing) -------------------------------- diff --git a/src/proto_alpha/lib_benchmarks_proto/storage_benchmarks.ml b/src/proto_alpha/lib_benchmarks_proto/storage_benchmarks.ml index b1fb282687fef4cf5e17f43f70e32d839b4e6d58..e36e82fecbd5e51d223d4f21c6fa07dfabb8cdb2 100644 --- a/src/proto_alpha/lib_benchmarks_proto/storage_benchmarks.ml +++ b/src/proto_alpha/lib_benchmarks_proto/storage_benchmarks.ml @@ -65,7 +65,11 @@ let default_raw_context () = let*! ctxt = add empty ["version"] (Bytes.of_string "genesis") in add ctxt protocol_param_key proto_params) in - let typecheck ctxt script_repr = return ((script_repr, None), ctxt) in + let typecheck_smart_contract ctxt script_repr = + return ((script_repr, None), ctxt) + in + let typecheck_smart_rollup ctxt _script_repr = Result_syntax.return ctxt in + let*! e = Init_storage.prepare_first_block Chain_id.zero @@ -73,7 +77,8 @@ let default_raw_context () = ~level:0l ~timestamp:(Time.Protocol.of_seconds 1643125688L) ~predecessor:Block_hash.zero - ~typecheck + ~typecheck_smart_contract + ~typecheck_smart_rollup in Lwt.return @@ Environment.wrap_tzresult e diff --git a/src/proto_alpha/lib_parameters/default_parameters.ml b/src/proto_alpha/lib_parameters/default_parameters.ml index 9694edbbe003a7b586cf5b0533ee00384645819a..8d3b9d5e80976f997dd46a17050bcc5bc16e7727 100644 --- a/src/proto_alpha/lib_parameters/default_parameters.ml +++ b/src/proto_alpha/lib_parameters/default_parameters.ml @@ -441,11 +441,13 @@ let make_bootstrap_account (pkh, pk, amount, delegate_to, consensus_key) = } let parameters_of_constants ?(bootstrap_accounts = bootstrap_accounts) - ?(bootstrap_contracts = []) ?(commitments = []) constants = + ?(bootstrap_contracts = []) ?(bootstrap_smart_rollups = []) + ?(commitments = []) constants = Parameters. { bootstrap_accounts; bootstrap_contracts; + bootstrap_smart_rollups; commitments; constants; security_deposit_ramp_up_cycles = None; diff --git a/src/proto_alpha/lib_parameters/default_parameters.mli b/src/proto_alpha/lib_parameters/default_parameters.mli index eff7da67497223993fdcca88bfbf31ac7066a7a4..e465d6dc31b3f2baba292fbc6ff84d74704d7927 100644 --- a/src/proto_alpha/lib_parameters/default_parameters.mli +++ b/src/proto_alpha/lib_parameters/default_parameters.mli @@ -45,6 +45,7 @@ val make_bootstrap_account : val parameters_of_constants : ?bootstrap_accounts:Parameters.bootstrap_account list -> ?bootstrap_contracts:Parameters.bootstrap_contract list -> + ?bootstrap_smart_rollups:Parameters.bootstrap_smart_rollup list -> ?commitments:Commitment.t list -> Constants.Parametric.t -> Parameters.t diff --git a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL index 061a870e8d06df969659084c468617986b2a8558..9f9a8a327a5ada1b485f0f4927d3fc88f4778024 100644 --- a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL +++ b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL @@ -162,7 +162,6 @@ "Delegate_missed_endorsements_storage", "Delegate_slashed_deposits_storage", "Delegate_cycles", - "Bootstrap_storage", "Vote_storage", "Ticket_storage", @@ -176,7 +175,6 @@ "Remove_zero_amount_ticket_migration_for_o", "Legacy_script_patches", - "Init_storage", "Sapling_validator", "Global_constants_costs", @@ -195,6 +193,9 @@ "Sc_rollup_refutation_storage", "Zk_rollup_errors", + "Bootstrap_storage", + "Init_storage", + "Destination_storage", "Alpha_context", diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index 00d50cb4561703fde085811320d6f7ff412fea51..d579af4ad917d6ca4e9510700622ac8d7d507b46 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -5127,10 +5127,11 @@ end val prepare_first_block : Chain_id.t -> Context.t -> - typecheck: + typecheck_smart_contract: (context -> Script.t -> ((Script.t * Lazy_storage.diffs option) * context) tzresult Lwt.t) -> + typecheck_smart_rollup:(context -> Script.expr -> context tzresult) -> level:Int32.t -> timestamp:Time.t -> predecessor:Block_hash.t -> @@ -5192,9 +5193,17 @@ module Parameters : sig script : Script.t; } + type bootstrap_smart_rollup = { + address : Sc_rollup_repr.Address.t; + pvm_kind : Sc_rollups.Kind.t; + boot_sector : string; + parameters_ty : Script_repr.lazy_expr; + } + type t = { bootstrap_accounts : bootstrap_account list; bootstrap_contracts : bootstrap_contract list; + bootstrap_smart_rollups : bootstrap_smart_rollup list; commitments : Commitment.t list; constants : Constants.Parametric.t; security_deposit_ramp_up_cycles : int option; diff --git a/src/proto_alpha/lib_protocol/bootstrap_storage.ml b/src/proto_alpha/lib_protocol/bootstrap_storage.ml index 1cf7b6ace7983228ddfd8ea388c320e02c29debf..6b35e1a1037f37bb33ad16d7fe29bf18fdb01e7e 100644 --- a/src/proto_alpha/lib_protocol/bootstrap_storage.ml +++ b/src/proto_alpha/lib_protocol/bootstrap_storage.ml @@ -75,11 +75,11 @@ let init_account (ctxt, balance_updates) >>=? fun () -> return ctxt) >|=? fun ctxt -> (ctxt, new_balance_updates @ balance_updates) -let init_contract ~typecheck (ctxt, balance_updates) +let init_contract ~typecheck_smart_contract (ctxt, balance_updates) ({delegate; amount; script} : Parameters_repr.bootstrap_contract) = Contract_storage.fresh_contract_from_current_nonce ctxt >>?= fun (ctxt, contract_hash) -> - typecheck ctxt script >>=? fun (script, ctxt) -> + typecheck_smart_contract ctxt script >>=? fun (script, ctxt) -> Contract_storage.raw_originate ctxt ~prepaid_bootstrap_storage:true @@ -96,13 +96,66 @@ let init_contract ~typecheck (ctxt, balance_updates) >|=? fun (ctxt, new_balance_updates) -> (ctxt, new_balance_updates @ balance_updates) -let init ctxt ~typecheck ?no_reward_cycles accounts contracts = +let genesis_hash ~boot_sector kind = + let open Lwt_result_syntax in + let (module Machine) = Sc_rollups.Kind.no_proof_machine_of kind in + let empty = Sc_rollup_machine_no_proofs.empty_tree () in + let*! state = Machine.initial_state ~empty in + let*! state = Machine.install_boot_sector state boot_sector in + let*! genesis_hash = Machine.state_hash state in + return genesis_hash + +let init_smart_rollup ~typecheck_smart_rollup ctxt + ({address; boot_sector; pvm_kind; parameters_ty} : + Parameters_repr.bootstrap_smart_rollup) = + let open Lwt_result_syntax in + let*? ctxt = + let open Result_syntax in + let* parameters_ty = Script_repr.force_decode parameters_ty in + typecheck_smart_rollup ctxt parameters_ty + in + let* genesis_hash = genesis_hash ~boot_sector pvm_kind in + let genesis_commitment : Sc_rollup_commitment_repr.t = + { + compressed_state = genesis_hash; + (* Level 0: Genesis block. + Level 1: Block on protocol genesis, that only activates protocols. + Level 2: First block on the activated protocol. + + Therefore we originate the rollup at level 2 so the rollup node + doesn't ask a block on a different protocol. + *) + inbox_level = Raw_level_repr.of_int32_exn 2l; + predecessor = Sc_rollup_commitment_repr.Hash.zero; + number_of_ticks = Sc_rollup_repr.Number_of_ticks.zero; + } + in + let* _, _, ctxt = + Sc_rollup_storage.raw_originate + ctxt + ~kind:pvm_kind + ~genesis_commitment + ~parameters_ty + ~address + in + return ctxt + +let init ctxt ~typecheck_smart_contract ~typecheck_smart_rollup + ?no_reward_cycles accounts contracts smart_rollups = let nonce = Operation_hash.hash_string ["Un festival de GADT."] in let ctxt = Raw_context.init_origination_nonce ctxt nonce in List.fold_left_es init_account (ctxt, []) accounts >>=? fun (ctxt, balance_updates) -> - List.fold_left_es (init_contract ~typecheck) (ctxt, balance_updates) contracts + List.fold_left_es + (init_contract ~typecheck_smart_contract) + (ctxt, balance_updates) + contracts >>=? fun (ctxt, balance_updates) -> + List.fold_left_es + (init_smart_rollup ~typecheck_smart_rollup) + ctxt + smart_rollups + >>=? fun ctxt -> (match no_reward_cycles with | None -> return ctxt | Some cycles -> diff --git a/src/proto_alpha/lib_protocol/bootstrap_storage.mli b/src/proto_alpha/lib_protocol/bootstrap_storage.mli index 91cfc6967c61b9a5143bce58c64c7a251fcd8d06..01366550da5700d050f023b2b2173c4668ccfc72 100644 --- a/src/proto_alpha/lib_protocol/bootstrap_storage.mli +++ b/src/proto_alpha/lib_protocol/bootstrap_storage.mli @@ -30,14 +30,17 @@ val init : Raw_context.t -> - typecheck: + typecheck_smart_contract: (Raw_context.t -> Script_repr.t -> ((Script_repr.t * Lazy_storage_diff.diffs option) * Raw_context.t) tzresult Lwt.t) -> + typecheck_smart_rollup: + (Raw_context.t -> Script_repr.expr -> Raw_context.t tzresult) -> ?no_reward_cycles:int -> Parameters_repr.bootstrap_account list -> Parameters_repr.bootstrap_contract list -> + Parameters_repr.bootstrap_smart_rollup list -> (Raw_context.t * Receipt_repr.balance_updates) tzresult Lwt.t val cycle_end : Raw_context.t -> Cycle_repr.t -> Raw_context.t tzresult Lwt.t diff --git a/src/proto_alpha/lib_protocol/dune b/src/proto_alpha/lib_protocol/dune index 5a4d9c5eb34e9df7c6c8c321bd50f918922ff89e..fdb58622425727769e11ed45e1f9cbc191a486e6 100644 --- a/src/proto_alpha/lib_protocol/dune +++ b/src/proto_alpha/lib_protocol/dune @@ -180,7 +180,6 @@ Delegate_missed_endorsements_storage Delegate_slashed_deposits_storage Delegate_cycles - Bootstrap_storage Vote_storage Ticket_storage Liquidity_baking_storage @@ -191,7 +190,6 @@ Sc_rollup_inbox_storage Remove_zero_amount_ticket_migration_for_o Legacy_script_patches - Init_storage Sapling_validator Global_constants_costs Global_constants_storage @@ -208,6 +206,8 @@ Dal_slot_storage Sc_rollup_refutation_storage Zk_rollup_errors + Bootstrap_storage + Init_storage Destination_storage Alpha_context Script_string @@ -463,7 +463,6 @@ delegate_missed_endorsements_storage.mli delegate_slashed_deposits_storage.ml delegate_slashed_deposits_storage.mli delegate_cycles.ml delegate_cycles.mli - bootstrap_storage.ml bootstrap_storage.mli vote_storage.ml vote_storage.mli ticket_storage.ml ticket_storage.mli liquidity_baking_storage.ml liquidity_baking_storage.mli @@ -474,7 +473,6 @@ sc_rollup_inbox_storage.ml sc_rollup_inbox_storage.mli remove_zero_amount_ticket_migration_for_o.ml legacy_script_patches.ml - init_storage.ml init_storage.mli sapling_validator.ml global_constants_costs.ml global_constants_costs.mli global_constants_storage.ml global_constants_storage.mli @@ -491,6 +489,8 @@ dal_slot_storage.ml dal_slot_storage.mli sc_rollup_refutation_storage.ml sc_rollup_refutation_storage.mli zk_rollup_errors.ml + bootstrap_storage.ml bootstrap_storage.mli + init_storage.ml init_storage.mli destination_storage.ml destination_storage.mli alpha_context.ml alpha_context.mli script_string.ml script_string.mli @@ -747,7 +747,6 @@ delegate_missed_endorsements_storage.mli delegate_slashed_deposits_storage.ml delegate_slashed_deposits_storage.mli delegate_cycles.ml delegate_cycles.mli - bootstrap_storage.ml bootstrap_storage.mli vote_storage.ml vote_storage.mli ticket_storage.ml ticket_storage.mli liquidity_baking_storage.ml liquidity_baking_storage.mli @@ -758,7 +757,6 @@ sc_rollup_inbox_storage.ml sc_rollup_inbox_storage.mli remove_zero_amount_ticket_migration_for_o.ml legacy_script_patches.ml - init_storage.ml init_storage.mli sapling_validator.ml global_constants_costs.ml global_constants_costs.mli global_constants_storage.ml global_constants_storage.mli @@ -775,6 +773,8 @@ dal_slot_storage.ml dal_slot_storage.mli sc_rollup_refutation_storage.ml sc_rollup_refutation_storage.mli zk_rollup_errors.ml + bootstrap_storage.ml bootstrap_storage.mli + init_storage.ml init_storage.mli destination_storage.ml destination_storage.mli alpha_context.ml alpha_context.mli script_string.ml script_string.mli @@ -1015,7 +1015,6 @@ delegate_missed_endorsements_storage.mli delegate_slashed_deposits_storage.ml delegate_slashed_deposits_storage.mli delegate_cycles.ml delegate_cycles.mli - bootstrap_storage.ml bootstrap_storage.mli vote_storage.ml vote_storage.mli ticket_storage.ml ticket_storage.mli liquidity_baking_storage.ml liquidity_baking_storage.mli @@ -1026,7 +1025,6 @@ sc_rollup_inbox_storage.ml sc_rollup_inbox_storage.mli remove_zero_amount_ticket_migration_for_o.ml legacy_script_patches.ml - init_storage.ml init_storage.mli sapling_validator.ml global_constants_costs.ml global_constants_costs.mli global_constants_storage.ml global_constants_storage.mli @@ -1043,6 +1041,8 @@ dal_slot_storage.ml dal_slot_storage.mli sc_rollup_refutation_storage.ml sc_rollup_refutation_storage.mli zk_rollup_errors.ml + bootstrap_storage.ml bootstrap_storage.mli + init_storage.ml init_storage.mli destination_storage.ml destination_storage.mli alpha_context.ml alpha_context.mli script_string.ml script_string.mli diff --git a/src/proto_alpha/lib_protocol/init_storage.ml b/src/proto_alpha/lib_protocol/init_storage.ml index ff680cc9046a038cb45c7d55ac9ca2dd0ea5b9fd..feac14b1ab4abbbe82a407b1e3356f7b48497180 100644 --- a/src/proto_alpha/lib_protocol/init_storage.ml +++ b/src/proto_alpha/lib_protocol/init_storage.ml @@ -156,8 +156,8 @@ let initialize_total_supply_for_o ctxt = ctxt (Tez_repr.of_mutez_exn 940_000_000_000_000L) -let prepare_first_block _chain_id ctxt ~typecheck ~level ~timestamp ~predecessor - = +let prepare_first_block _chain_id ctxt ~typecheck_smart_contract + ~typecheck_smart_rollup ~level ~timestamp ~predecessor = Raw_context.prepare_first_block ~level ~timestamp ctxt >>=? fun (previous_protocol, ctxt) -> let parametric = Raw_context.constants ctxt in @@ -192,10 +192,12 @@ let prepare_first_block _chain_id ctxt ~typecheck ~level ~timestamp ~predecessor Contract_storage.init ctxt >>=? fun ctxt -> Bootstrap_storage.init ctxt - ~typecheck + ~typecheck_smart_contract + ~typecheck_smart_rollup ?no_reward_cycles:param.no_reward_cycles param.bootstrap_accounts param.bootstrap_contracts + param.bootstrap_smart_rollups >>=? fun (ctxt, bootstrap_balance_updates) -> Delegate_cycles.init_first_cycles ctxt ~origin:Protocol_migration >>=? fun (ctxt, deposits_balance_updates) -> @@ -205,7 +207,7 @@ let prepare_first_block _chain_id ctxt ~typecheck ~level ~timestamp ~predecessor >>=? fun ctxt -> Vote_storage.update_listings ctxt >>=? fun ctxt -> (* Must be called after other originations since it unsets the origination nonce. *) - Liquidity_baking_migration.init ctxt ~typecheck + Liquidity_baking_migration.init ctxt ~typecheck:typecheck_smart_contract >>=? fun (ctxt, operation_results) -> Storage.Pending_migration.Operation_results.init ctxt operation_results >>=? fun ctxt -> diff --git a/src/proto_alpha/lib_protocol/init_storage.mli b/src/proto_alpha/lib_protocol/init_storage.mli index 9a8a079a17e9b2ce35f42abd4d35f4fd0a78784f..35cef8c0e2cdc98c5dc59f11da40305c4ab48171 100644 --- a/src/proto_alpha/lib_protocol/init_storage.mli +++ b/src/proto_alpha/lib_protocol/init_storage.mli @@ -34,12 +34,14 @@ val prepare_first_block : Chain_id.t -> Context.t -> - typecheck: + typecheck_smart_contract: (Raw_context.t -> Script_repr.t -> ((Script_repr.t * Lazy_storage_diff.diffs option) * Raw_context.t) Error_monad.tzresult Lwt.t) -> + typecheck_smart_rollup: + (Raw_context.t -> Script_repr.expr -> Raw_context.t tzresult) -> level:int32 -> timestamp:Time.t -> predecessor:Block_hash.t -> diff --git a/src/proto_alpha/lib_protocol/main.ml b/src/proto_alpha/lib_protocol/main.ml index 2f346600822988ed41073878e012bac8c18f1450..f94b7e1de2a46d26a2c143d81a434968f80cd6f1 100644 --- a/src/proto_alpha/lib_protocol/main.ml +++ b/src/proto_alpha/lib_protocol/main.ml @@ -351,8 +351,8 @@ let init chain_id ctxt block_header = let level = block_header.Block_header.level in let timestamp = block_header.timestamp in let predecessor = block_header.predecessor in - let typecheck (ctxt : Alpha_context.context) (script : Alpha_context.Script.t) - = + let typecheck_smart_contract (ctxt : Alpha_context.context) + (script : Alpha_context.Script.t) = let allow_forged_in_storage = false (* There should be no forged value in bootstrap contracts. *) @@ -393,7 +393,8 @@ let init chain_id ctxt block_header = in Alpha_context.prepare_first_block chain_id - ~typecheck + ~typecheck_smart_contract + ~typecheck_smart_rollup:Sc_rollup_operations.validate_untyped_parameters_ty ~level ~timestamp ~predecessor diff --git a/src/proto_alpha/lib_protocol/parameters_repr.ml b/src/proto_alpha/lib_protocol/parameters_repr.ml index 13604ffdc600a09776d0be837ec410587da145e2..bea5a86656f9ccc810ea7cff8cc65ff4a9d20751 100644 --- a/src/proto_alpha/lib_protocol/parameters_repr.ml +++ b/src/proto_alpha/lib_protocol/parameters_repr.ml @@ -38,9 +38,17 @@ type bootstrap_contract = { script : Script_repr.t; } +type bootstrap_smart_rollup = { + address : Sc_rollup_repr.Address.t; + pvm_kind : Sc_rollups.Kind.t; + boot_sector : string; + parameters_ty : Script_repr.lazy_expr; +} + type t = { bootstrap_accounts : bootstrap_account list; bootstrap_contracts : bootstrap_contract list; + bootstrap_smart_rollups : bootstrap_smart_rollup list; commitments : Commitment_repr.t list; constants : Constants_parametric_repr.t; security_deposit_ramp_up_cycles : int option; @@ -209,12 +217,26 @@ let bootstrap_contract_encoding = (req "amount" Tez_repr.encoding) (req "script" Script_repr.encoding)) +let bootstrap_smart_rollup_encoding = + let open Data_encoding in + conv + (fun {address; pvm_kind; boot_sector; parameters_ty} -> + (address, pvm_kind, boot_sector, parameters_ty)) + (fun (address, pvm_kind, boot_sector, parameters_ty) -> + {address; pvm_kind; boot_sector; parameters_ty}) + (obj4 + (req "address" Sc_rollup_repr.Address.encoding) + (req "pvm_kind" Sc_rollups.Kind.encoding) + (req "kernel" (string Hex)) + (req "parameters_ty" Script_repr.lazy_expr_encoding)) + let encoding = let open Data_encoding in conv (fun { bootstrap_accounts; bootstrap_contracts; + bootstrap_smart_rollups; commitments; constants; security_deposit_ramp_up_cycles; @@ -222,12 +244,14 @@ let encoding = } -> ( ( bootstrap_accounts, bootstrap_contracts, + bootstrap_smart_rollups, commitments, security_deposit_ramp_up_cycles, no_reward_cycles ), constants )) (fun ( ( bootstrap_accounts, bootstrap_contracts, + bootstrap_smart_rollups, commitments, security_deposit_ramp_up_cycles, no_reward_cycles ), @@ -235,15 +259,20 @@ let encoding = { bootstrap_accounts; bootstrap_contracts; + bootstrap_smart_rollups; commitments; constants; security_deposit_ramp_up_cycles; no_reward_cycles; }) (merge_objs - (obj5 + (obj6 (req "bootstrap_accounts" (list bootstrap_account_encoding)) (dft "bootstrap_contracts" (list bootstrap_contract_encoding) []) + (dft + "bootstrap_smart_rollups" + (list bootstrap_smart_rollup_encoding) + []) (dft "commitments" (list Commitment_repr.encoding) []) (opt "security_deposit_ramp_up_cycles" int31) (opt "no_reward_cycles" int31)) diff --git a/src/proto_alpha/lib_protocol/parameters_repr.mli b/src/proto_alpha/lib_protocol/parameters_repr.mli index 97bad09f1ccbd3704b1a49070eb9add1674c6576..af74419004669e04947978d848b5dc3f388e31d5 100644 --- a/src/proto_alpha/lib_protocol/parameters_repr.mli +++ b/src/proto_alpha/lib_protocol/parameters_repr.mli @@ -43,11 +43,20 @@ type bootstrap_contract = { script : Script_repr.t; } +(** An originated smart rollup initially existing on a chain since genesis. *) +type bootstrap_smart_rollup = { + address : Sc_rollup_repr.Address.t; + pvm_kind : Sc_rollups.Kind.t; + boot_sector : string; + parameters_ty : Script_repr.lazy_expr; +} + (** Protocol parameters define some constants regulating behaviour of the chain. *) type t = { bootstrap_accounts : bootstrap_account list; bootstrap_contracts : bootstrap_contract list; + bootstrap_smart_rollups : bootstrap_smart_rollup list; commitments : Commitment_repr.t list; constants : Constants_parametric_repr.t; security_deposit_ramp_up_cycles : int option; diff --git a/src/proto_alpha/lib_protocol/sc_rollup_operations.mli b/src/proto_alpha/lib_protocol/sc_rollup_operations.mli index f4ef5c48fa4965be50242749e5520ed3bc302fbd..2bab0932dfcf015494e0bf85777087bf5fd03758 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_operations.mli +++ b/src/proto_alpha/lib_protocol/sc_rollup_operations.mli @@ -82,6 +82,10 @@ val execute_outbox_message : output_proof:string -> (execute_outbox_message_result * context) tzresult Lwt.t +(** [validate_untyped_parameters_ty ctxt script] parses the type and check + that the entrypoints are well-formed. *) +val validate_untyped_parameters_ty : context -> Script.expr -> context tzresult + (** A module used for testing purposes only. *) module Internal_for_tests : sig (** Same as {!execute_outbox_message} but allows overriding the extraction diff --git a/src/proto_alpha/lib_protocol/sc_rollup_storage.ml b/src/proto_alpha/lib_protocol/sc_rollup_storage.ml index 7333f2c6c917951e39faad960fc7dc6b1324e91e..e7cbb0d073be0b168e8c15b9b3946eda010cb122 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_storage.ml +++ b/src/proto_alpha/lib_protocol/sc_rollup_storage.ml @@ -51,11 +51,13 @@ let new_address ctxt = let init_genesis_info ctxt address genesis_commitment = let open Lwt_result_syntax in - let level = (Raw_context.current_level ctxt).level in let*? ctxt, commitment_hash = Sc_rollup_commitment_storage.hash ctxt genesis_commitment in - let genesis_info = Commitment.{commitment_hash; level} in + (* The [genesis_commitment.inbox_level] is equal to the current level. *) + let genesis_info : Commitment.genesis_info = + {commitment_hash; level = genesis_commitment.inbox_level} + in let* ctxt, size = Store.Genesis_info.init ctxt address genesis_info in return (ctxt, genesis_info, size) @@ -107,9 +109,8 @@ let init_commitment_storage ctxt address + commitment_first_publication_level_diff + commitments_per_inbox_level_diff ) -let originate ctxt ~kind ~parameters_ty ~genesis_commitment = +let raw_originate ctxt ~kind ~parameters_ty ~genesis_commitment ~address = let open Lwt_result_syntax in - let*? ctxt, address = new_address ctxt in let* ctxt, pvm_kind_size = Store.PVM_kind.init ctxt address kind in let* ctxt, param_ty_size = Store.Parameters_type.init ctxt address parameters_ty @@ -132,7 +133,15 @@ let originate ctxt ~kind ~parameters_ty ~genesis_commitment = (origination_size + stored_kind_size + addresses_size + param_ty_size + pvm_kind_size + genesis_info_size_diff + commitment_size_diff) in - return (address, size, genesis_info.commitment_hash, ctxt) + return (size, genesis_info.commitment_hash, ctxt) + +let originate ctxt ~kind ~parameters_ty ~genesis_commitment = + let open Lwt_result_syntax in + let*? ctxt, address = new_address ctxt in + let* size, genesis_commitment, ctxt = + raw_originate ctxt ~kind ~parameters_ty ~genesis_commitment ~address + in + return (address, size, genesis_commitment, ctxt) let kind ctxt address = let open Lwt_result_syntax in diff --git a/src/proto_alpha/lib_protocol/sc_rollup_storage.mli b/src/proto_alpha/lib_protocol/sc_rollup_storage.mli index 538450ef03901bc75b291f218425b36bdfd90cd7..a5f447a2280aaba7be9b809327f278ea5ea1fa7f 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_storage.mli +++ b/src/proto_alpha/lib_protocol/sc_rollup_storage.mli @@ -43,6 +43,21 @@ val originate : tzresult Lwt.t +(** [raw_originate context ~kind ~parameters_ty ~genesis_commitment ~address] is + exactly {!originate} but provides the rollup's address ([address]) instead + of randomly generating it. + + This should not be used by [apply.ml], this is needed for bootstrap + smart rollups only. +*) +val raw_originate : + Raw_context.t -> + kind:Sc_rollups.Kind.t -> + parameters_ty:Script_repr.lazy_expr -> + genesis_commitment:Sc_rollup_commitment_repr.t -> + address:Sc_rollup_repr.Address.t -> + (Z.t * Sc_rollup_commitment_repr.Hash.t * Raw_context.t) tzresult Lwt.t + (** [kind context address] returns the kind of the given rollup [address] iff [address] is an existing rollup. Fails with an [Sc_rollup_does_not_exist] error in case the rollup does not exist. *) diff --git a/src/proto_alpha/lib_protocol/test/helpers/block.ml b/src/proto_alpha/lib_protocol/test/helpers/block.ml index f40cf8a13aab5584b9a7ca68ec7fc45fafed9255..e26a0a30ade8aaac872e93dae245e20bc0976dd0 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/block.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/block.ml @@ -380,8 +380,8 @@ let initial_alpha_context ?(commitments = []) constants let level = block_header.level in let timestamp = block_header.timestamp in let predecessor = block_header.predecessor in - let typecheck (ctxt : Alpha_context.context) (script : Alpha_context.Script.t) - = + let typecheck_smart_contract (ctxt : Alpha_context.context) + (script : Alpha_context.Script.t) = let allow_forged_in_storage = false (* There should be no forged value in bootstrap contracts. *) @@ -411,7 +411,8 @@ let initial_alpha_context ?(commitments = []) constants (({script with storage}, lazy_storage_diff), ctxt) in Alpha_context.prepare_first_block - ~typecheck + ~typecheck_smart_contract + ~typecheck_smart_rollup:Sc_rollup_operations.validate_untyped_parameters_ty ~level ~timestamp ~predecessor diff --git a/src/proto_alpha/lib_protocol/test/helpers/context.ml b/src/proto_alpha/lib_protocol/test/helpers/context.ml index c77778c99c0488381986ce6ffe1db22eff6b73e4..9c24fd52b49be84dab75cb8edbb862d02f852e61 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/context.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/context.ml @@ -594,12 +594,16 @@ let default_raw_context () = add empty ["version"] (Bytes.of_string "genesis") >>= fun ctxt -> add ctxt protocol_param_key proto_params) >>= fun context -> - let typecheck ctxt script_repr = return ((script_repr, None), ctxt) in + let typecheck_smart_contract ctxt script_repr = + return ((script_repr, None), ctxt) + in + let typecheck_smart_rollup ctxt _script_repr = Result_syntax.return ctxt in Init_storage.prepare_first_block Chain_id.zero context ~level:0l ~timestamp:(Time.Protocol.of_seconds 1643125688L) ~predecessor:Block_hash.zero - ~typecheck + ~typecheck_smart_contract + ~typecheck_smart_rollup >>= fun e -> Lwt.return @@ Environment.wrap_tzresult e diff --git a/tezt/lib_tezos/RPC.ml b/tezt/lib_tezos/RPC.ml index 51ea2f507fca23f02b2f19a195670aee2ec24400..079a2bcd2c7b42485f71d5be034bf19e85e24543 100644 --- a/tezt/lib_tezos/RPC.ml +++ b/tezt/lib_tezos/RPC.ml @@ -833,7 +833,7 @@ let get_chain_block_context_smart_rollups_all ?(chain = "main") make GET ["chains"; chain; "blocks"; block; "context"; "smart_rollups"; "all"] - Fun.id + (fun rollups -> JSON.as_list rollups |> List.map JSON.as_string) let get_chain_block_context_smart_rollups_smart_rollup_staker_games ?(chain = "main") ?(block = "head") ~staker sc_rollup () = diff --git a/tezt/lib_tezos/RPC.mli b/tezt/lib_tezos/RPC.mli index 8b79da822072c745212c7c59353acddb698b2646..b0fa7369f9179ac79193fc6e30b9f41d7e3998b9 100644 --- a/tezt/lib_tezos/RPC.mli +++ b/tezt/lib_tezos/RPC.mli @@ -806,7 +806,7 @@ val get_chain_block_context_contract_all_ticket_balances : (** RPC: [GET chains//blocks//context/smart_rollups/all] *) val get_chain_block_context_smart_rollups_all : - ?chain:string -> ?block:string -> unit -> JSON.t t + ?chain:string -> ?block:string -> unit -> string list t (** RPC: [GET chains//blocks//context/smart_rollups/smart_rollup//staker//games] *) val get_chain_block_context_smart_rollups_smart_rollup_staker_games : diff --git a/tezt/lib_tezos/protocol.ml b/tezt/lib_tezos/protocol.ml index 8f7f414d422c7d60eba1ceff4db1d9cfd4f76b9b..0e008cc3d90b75ea8ea75c641cd5a15e8df555ad 100644 --- a/tezt/lib_tezos/protocol.ml +++ b/tezt/lib_tezos/protocol.ml @@ -88,14 +88,23 @@ type parameter_overrides = let default_bootstrap_accounts = Array.to_list Account.Bootstrap.keys |> List.map @@ fun key -> (key, None) +type bootstrap_smart_rollup = { + address : string; + pvm_kind : string; + boot_sector : string; + parameters_ty : Ezjsonm.value; +} + let write_parameter_file : ?bootstrap_accounts:(Account.key * int option) list -> ?additional_bootstrap_accounts:(Account.key * int option * bool) list -> + ?bootstrap_smart_rollups:bootstrap_smart_rollup list -> base:(string, t * constants option) Either.t -> parameter_overrides -> string Lwt.t = fun ?(bootstrap_accounts = default_bootstrap_accounts) ?(additional_bootstrap_accounts = []) + ?(bootstrap_smart_rollups = []) ~base parameter_overrides -> (* make a copy of the parameters file and update the given constants *) @@ -127,6 +136,31 @@ let write_parameter_file : in (["bootstrap_accounts"], `A bootstrap_accounts) :: parameter_overrides in + let parameter_overrides = + if List.mem_assoc ["bootstrap_smart_rollups"] parameter_overrides then + parameter_overrides + else + let bootstrap_smart_rollups = + List.map + (fun {address; pvm_kind; boot_sector; parameters_ty} -> + `O + [ + ("address", `String address); + ("pvm_kind", `String pvm_kind); + ("kernel", `String boot_sector); + ("parameters_ty", parameters_ty); + ]) + bootstrap_smart_rollups + in + match bootstrap_smart_rollups with + | [] -> + (* This is useful for tests on protocol before bootstrap smart rollups + support. Otherwise the protocol cannot decode this new field. *) + parameter_overrides + | bootstrap_smart_rollups -> + (["bootstrap_smart_rollups"], `A bootstrap_smart_rollups) + :: parameter_overrides + in let parameters = List.fold_left (fun acc (path, value) -> diff --git a/tezt/lib_tezos/protocol.mli b/tezt/lib_tezos/protocol.mli index 47647842513ba62644cffea3089bdf18fbb84708..a22c6040490d0f64c43fa0561a3c9d73ad2671d4 100644 --- a/tezt/lib_tezos/protocol.mli +++ b/tezt/lib_tezos/protocol.mli @@ -107,6 +107,13 @@ val encoding_prefix : t -> string type parameter_overrides = (string list * [`None | `Int of int | `String_of_int of int | JSON.u]) list +type bootstrap_smart_rollup = { + address : string; + pvm_kind : string; + boot_sector : string; + parameters_ty : Ezjsonm.value; +} + (** Write a protocol parameter file. This function first builds a default parameter file from the [base] @@ -123,10 +130,12 @@ type parameter_overrides = add to activation parameters. Each account is a triplet [(key, balance, revealed)]. If [revealed] the public key is added, else the public key hash is added. Revealed keys are expected to bake - from the start. Default [balance] is 4000000 tez. *) + from the start. Default [balance] is 4000000 tez. + - [bootstrap_smart_rollups] when given. *) val write_parameter_file : ?bootstrap_accounts:(Account.key * int option) list -> ?additional_bootstrap_accounts:(Account.key * int option * bool) list -> + ?bootstrap_smart_rollups:bootstrap_smart_rollup list -> base:(string, t * constants option) Either.t -> parameter_overrides -> string Lwt.t diff --git a/tezt/lib_tezos/sc_rollup_helpers.ml b/tezt/lib_tezos/sc_rollup_helpers.ml index bc9a83478d05adb05959e2c32c14a9f42e40395b..e06c58e093071f533dedfe1c43eb525bf9e22fc0 100644 --- a/tezt/lib_tezos/sc_rollup_helpers.ml +++ b/tezt/lib_tezos/sc_rollup_helpers.ml @@ -104,7 +104,8 @@ let make_parameter name = function | None -> [] | Some value -> [([name], `Int value)] -let setup_l1 ?commitment_period ?challenge_window ?timeout protocol = +let setup_l1 ?bootstrap_smart_rollups ?commitment_period ?challenge_window + ?timeout protocol = let parameters = make_parameter "smart_rollup_commitment_period_in_blocks" commitment_period @ make_parameter "smart_rollup_challenge_window_in_blocks" challenge_window @@ -112,7 +113,9 @@ let setup_l1 ?commitment_period ?challenge_window ?timeout protocol = @ [(["smart_rollup_arith_pvm_enable"], `Bool true)] in let base = Either.right (protocol, None) in - let* parameter_file = Protocol.write_parameter_file ~base parameters in + let* parameter_file = + Protocol.write_parameter_file ?bootstrap_smart_rollups ~base parameters + in let nodes_args = Node.[Synchronisation_threshold 0; History_mode Archive; No_bootstrap_peers] in diff --git a/tezt/lib_tezos/sc_rollup_helpers.mli b/tezt/lib_tezos/sc_rollup_helpers.mli index 78101352b91c29f356995820c174a10eb41914b1..e64dd484e869a7cc49952cede04efd0312d2b5b4 100644 --- a/tezt/lib_tezos/sc_rollup_helpers.mli +++ b/tezt/lib_tezos/sc_rollup_helpers.mli @@ -59,6 +59,7 @@ val prepare_installer_kernel : (** [setup_l1 protocol] initializes a protocol with the given parameters, and returns the L1 node and client. *) val setup_l1 : + ?bootstrap_smart_rollups:Protocol.bootstrap_smart_rollup list -> ?commitment_period:int -> ?challenge_window:int -> ?timeout:int -> diff --git a/tezt/tests/sc_rollup.ml b/tezt/tests/sc_rollup.ml index 146cef6ecef5d20737cf6b954b6efe98d316b3aa..ed116cbb6467c86bd6672f638e27952a73a1e68e 100644 --- a/tezt/tests/sc_rollup.ml +++ b/tezt/tests/sc_rollup.ml @@ -1201,7 +1201,6 @@ let test_rollup_list ~kind = let* rollups = RPC.Client.call client @@ RPC.get_chain_block_context_smart_rollups_all () in - let rollups = JSON.as_list rollups in let () = match rollups with | _ :: _ -> @@ -1218,9 +1217,7 @@ let test_rollup_list ~kind = let* rollups = RPC.Client.call client @@ RPC.get_chain_block_context_smart_rollups_all () in - let rollups = - JSON.as_list rollups |> List.map JSON.as_string |> String_set.of_list - in + let rollups = String_set.of_list rollups in Check.( (rollups = scoru_addresses) (comparable_module (module String_set)) @@ -5173,7 +5170,6 @@ let test_arg_boot_sector_file ~kind = description = "Rollup node uses argument boot sector file"; } @@ fun _protocol rollup_node _rollup_client rollup _node client -> - let _ = client in let invalid_boot_sector = hex_if_wasm "Nairobi est un bien meilleur nom de protocol que Nantes" in @@ -5211,6 +5207,43 @@ let test_arg_boot_sector_file ~kind = let* _ = Sc_rollup_node.wait_sync ~timeout:10. rollup_node in unit +let test_bootstrap_smart_rollup_originated = + register_test + ~supports:(From_protocol 018) + ~__FILE__ + ~tags:["bootstrap"; "parameter"] + ~title:"Bootstrap smart rollups are listed" + @@ fun protocol -> + let bootstrap_arith : Protocol.bootstrap_smart_rollup = + { + address = "sr1RYurGZtN8KNSpkMcCt9CgWeUaNkzsAfXf"; + pvm_kind = "arith"; + boot_sector = ""; + parameters_ty = `O [("prim", `String "unit")]; + } + in + let bootstrap_wasm : Protocol.bootstrap_smart_rollup = + { + address = "sr163Lv22CdE8QagCwf48PWDTquk6isQwv57"; + pvm_kind = "wasm_2_0_0"; + boot_sector = ""; + parameters_ty = `O [("prim", `String "unit")]; + } + in + let bootstrap_smart_rollups = [bootstrap_arith; bootstrap_wasm] in + let* _node, client = setup_l1 ~bootstrap_smart_rollups protocol in + let* rollups = + RPC.Client.call client @@ RPC.get_chain_block_context_smart_rollups_all () + in + let bootstrap_smart_rollups_addresses = + List.map (fun Protocol.{address; _} -> address) bootstrap_smart_rollups + in + Check.( + (rollups = bootstrap_smart_rollups_addresses) + (list string) + ~error_msg:"Expected %R bootstrapped smart rollups, got %L") ; + unit + let register ~kind ~protocols = test_origination ~kind protocols ; test_rollup_node_running ~kind protocols ; @@ -5384,7 +5417,9 @@ let register ~protocols = test_injector_auto_discard protocols ; (* Shared tezts - will be executed for both PVMs. *) register ~kind:"wasm_2_0_0" ~protocols ; - register ~kind:"arith" ~protocols + register ~kind:"arith" ~protocols ; + (* Both Arith and Wasm PVM tezts *) + test_bootstrap_smart_rollup_originated protocols let register_migration ~kind ~migrate_from ~migrate_to = test_migration_inbox ~kind ~migrate_from ~migrate_to ; diff --git a/tezt/tests/tx_sc_rollup.ml b/tezt/tests/tx_sc_rollup.ml index c0427bc75b8c28dbf71a82478b66fa211bbc3cb6..5e8b704f82399a85762210f6474a0164dfeaf0f5 100644 --- a/tezt/tests/tx_sc_rollup.ml +++ b/tezt/tests/tx_sc_rollup.ml @@ -295,8 +295,7 @@ let rec bake_until cond client sc_rollup_node = in bake_until cond client sc_rollup_node -let test_tx_kernel_e2e protocol = - let commitment_period = 10 and challenge_window = 10 in +let setup_classic ~commitment_period ~challenge_window protocol = let* node, client = setup_l1 ~commitment_period ~challenge_window protocol in let bootstrap1_key = Constant.bootstrap1.alias in let sc_rollup_node = @@ -325,6 +324,59 @@ let test_tx_kernel_e2e protocol = client in let* () = Client.bake_for_and_wait client in + return (client, sc_rollup_node, sc_rollup_address, []) + +let setup_bootstrap ~commitment_period ~challenge_window protocol = + let bootstrap1_key = Constant.bootstrap1.alias in + let data_dir = Temp.dir "tx-kernel-data-dir" in + let* boot_sector = + prepare_installer_kernel + ~preimages_dir:(Filename.concat data_dir "wasm_2_0_0") + "tx-kernel" + in + let boot_sector_file = Filename.temp_file "boot-sector" ".hex" in + let () = write_file boot_sector_file ~contents:boot_sector in + let sc_rollup_address = "sr163Lv22CdE8QagCwf48PWDTquk6isQwv57" in + let* parameters_ty = + let client = Client.create_with_mode Client.Mockup in + Client.convert_data_to_json ~data:"pair string (ticket string)" client + in + let bootstrap_tx_kernel : Protocol.bootstrap_smart_rollup = + { + address = sc_rollup_address; + pvm_kind = "wasm_2_0_0"; + boot_sector; + parameters_ty; + } + in + let* node, client = + setup_l1 + ~bootstrap_smart_rollups:[bootstrap_tx_kernel] + ~commitment_period + ~challenge_window + protocol + in + let sc_rollup_node = + Sc_rollup_node.create + ~protocol + Operator + node + ~data_dir + ~base_dir:(Client.base_dir client) + ~default_operator:bootstrap1_key + in + let* () = Client.bake_for_and_wait client in + return + ( client, + sc_rollup_node, + sc_rollup_address, + ["--boot-sector-file"; boot_sector_file] ) + +let tx_kernel_e2e setup protocol = + let commitment_period = 10 and challenge_window = 10 in + let* client, sc_rollup_node, sc_rollup_address, node_args = + setup ~commitment_period ~challenge_window protocol + in (* Run the rollup node, ensure origination succeeds. *) let* genesis_info = @@ -333,7 +385,7 @@ let test_tx_kernel_e2e protocol = sc_rollup_address in let init_level = JSON.(genesis_info |-> "level" |> as_int) in - let* () = Sc_rollup_node.run sc_rollup_node sc_rollup_address [] in + let* () = Sc_rollup_node.run sc_rollup_node sc_rollup_address node_args in let sc_rollup_client = Sc_rollup_client.create ~protocol sc_rollup_node in let* level = Sc_rollup_node.wait_for_level ~timeout:30. sc_rollup_node init_level @@ -548,10 +600,11 @@ let test_tx_kernel_e2e protocol = in unit -let register_test ?(regression = false) ~__FILE__ ~tags ~title f = +let register_test ?supports ?(regression = false) ~__FILE__ ~tags ~title f = let tags = "tx_sc_rollup" :: tags in - if regression then Protocol.register_regression_test ~__FILE__ ~title ~tags f - else Protocol.register_test ~__FILE__ ~title ~tags f + if regression then + Protocol.register_regression_test ?supports ~__FILE__ ~title ~tags f + else Protocol.register_test ?supports ~__FILE__ ~title ~tags f let test_tx_kernel_e2e = register_test @@ -559,6 +612,18 @@ let test_tx_kernel_e2e = ~__FILE__ ~tags:["wasm"; "kernel"; "wasm_2_0_0"; "kernel_e2e"] ~title:(Printf.sprintf "wasm_2_0_0 - tx kernel should run e2e (kernel_e2e)") - test_tx_kernel_e2e + (tx_kernel_e2e setup_classic) -let register ~protocols = test_tx_kernel_e2e protocols +let test_bootstrapped_tx_kernel_e2e = + register_test + ~supports:(Protocol.From_protocol 018) + ~__FILE__ + ~tags:["wasm"; "kernel"; "wasm_2_0_0"; "kernel_e2e"; "bootstrap"] + ~title: + (Printf.sprintf + "wasm_2_0_0 - bootstrapped tx kernel should run e2e (kernel_e2e)") + (tx_kernel_e2e setup_bootstrap) + +let register ~protocols = + test_tx_kernel_e2e protocols ; + test_bootstrapped_tx_kernel_e2e protocols