diff --git a/src/proto_alpha/lib_protocol/raw_context.ml b/src/proto_alpha/lib_protocol/raw_context.ml index d2a7b1b8d3a8caecd7cd13267533746861a78855..0ce2a253f5f890ca3f2a013bcba9f1d452f6fb4f 100644 --- a/src/proto_alpha/lib_protocol/raw_context.ml +++ b/src/proto_alpha/lib_protocol/raw_context.ml @@ -155,10 +155,12 @@ module Raw_consensus = struct (fun () -> Double_inclusion_of_consensus_operation) let record_attestation t ~initial_slot ~power = - error_when - (Slot_repr.Set.mem initial_slot t.attestations_seen) - Double_inclusion_of_consensus_operation - >|? fun () -> + let open Result_syntax in + let+ () = + error_when + (Slot_repr.Set.mem initial_slot t.attestations_seen) + Double_inclusion_of_consensus_operation + in { t with current_attestation_power = t.current_attestation_power + power; @@ -166,10 +168,12 @@ module Raw_consensus = struct } let record_preattestation ~initial_slot ~power round t = - error_when - (Slot_repr.Set.mem initial_slot t.preattestations_seen) - Double_inclusion_of_consensus_operation - >|? fun () -> + let open Result_syntax in + let+ () = + error_when + (Slot_repr.Set.mem initial_slot t.preattestations_seen) + Double_inclusion_of_consensus_operation + in let locked_round_evidence = match t.locked_round_evidence with | None -> Some (round, power) @@ -460,10 +464,11 @@ let () = (fun c -> Sampler_already_set c) let fresh_internal_nonce ctxt = + let open Result_syntax in if Compare.Int.(internal_nonce ctxt >= 65_535) then - error Too_many_internal_operations + tzfail Too_many_internal_operations else - ok + return (update_internal_nonce ctxt (internal_nonce ctxt + 1), internal_nonce ctxt) let reset_internal_nonce ctxt = @@ -479,12 +484,16 @@ let internal_nonce_already_recorded ctxt k = let get_collected_fees ctxt = fees ctxt let credit_collected_fees_only_call_from_token ctxt fees' = + let open Result_syntax in let previous = get_collected_fees ctxt in - Tez_repr.(previous +? fees') >|? fun fees -> update_fees ctxt fees + let+ fees = Tez_repr.(previous +? fees') in + update_fees ctxt fees let spend_collected_fees_only_call_from_token ctxt fees' = + let open Result_syntax in let previous = get_collected_fees ctxt in - Tez_repr.(previous -? fees') >|? fun fees -> update_fees ctxt fees + let+ fees = Tez_repr.(previous -? fees') in + update_fees ctxt fees type error += Undefined_operation_nonce (* `Permanent *) @@ -505,19 +514,21 @@ let init_origination_nonce ctxt operation_hash = update_origination_nonce ctxt origination_nonce let increment_origination_nonce ctxt = + let open Result_syntax in match origination_nonce ctxt with - | None -> error Undefined_operation_nonce + | None -> tzfail Undefined_operation_nonce | Some cur_origination_nonce -> let origination_nonce = Some (Origination_nonce.incr cur_origination_nonce) in let ctxt = update_origination_nonce ctxt origination_nonce in - ok (ctxt, cur_origination_nonce) + return (ctxt, cur_origination_nonce) let get_origination_nonce ctxt = + let open Result_syntax in match origination_nonce ctxt with - | None -> error Undefined_operation_nonce - | Some origination_nonce -> ok origination_nonce + | None -> tzfail Undefined_operation_nonce + | Some origination_nonce -> return origination_nonce let unset_origination_nonce ctxt = update_origination_nonce ctxt None @@ -530,13 +541,16 @@ let block_gas_level = remaining_block_gas let consume_gas_limit_in_block ctxt gas_limit = let open Gas_limit_repr in - check_gas_limit - ~hard_gas_limit_per_operation:(constants ctxt).hard_gas_limit_per_operation - ~gas_limit - >>? fun () -> + let open Result_syntax in + let* () = + check_gas_limit + ~hard_gas_limit_per_operation: + (constants ctxt).hard_gas_limit_per_operation + ~gas_limit + in let block_gas = block_gas_level ctxt in let limit = Arith.fp gas_limit in - if Arith.(limit > block_gas) then error Block_quota_exceeded + if Arith.(limit > block_gas) then tzfail Block_quota_exceeded else let level = Arith.sub (block_gas_level ctxt) limit in let ctxt = update_remaining_block_gas ctxt level in @@ -551,14 +565,17 @@ let set_gas_limit ctxt (remaining : 'a Gas_limit_repr.Arith.t) = let set_gas_unlimited ctxt = update_unlimited_operation_gas ctxt true let consume_gas ctxt cost = + let open Result_syntax in match Gas_limit_repr.raw_consume (remaining_operation_gas ctxt) cost with | Some gas_counter -> Ok (update_remaining_operation_gas ctxt gas_counter) | None -> - if unlimited_operation_gas ctxt then ok ctxt - else error Operation_quota_exceeded + if unlimited_operation_gas ctxt then return ctxt + else tzfail Operation_quota_exceeded let check_enough_gas ctxt cost = - consume_gas ctxt cost >>? fun (_ : t) -> Result.return_unit + let open Result_syntax in + let* (_ : t) = consume_gas ctxt cost in + return_unit let gas_consumed ~since ~until = match (gas_level since, gas_level until) with @@ -659,7 +676,7 @@ let () = (function Storage_error err -> Some err | _ -> None) (fun err -> Storage_error err) -let storage_error err = error (Storage_error err) +let storage_error err = Result_syntax.tzfail (Storage_error err) (* Initialization *********************************************************) @@ -693,20 +710,24 @@ let constants_key = [Constants_repr.version; "constants"] let protocol_param_key = ["protocol_parameters"] let get_cycle_eras ctxt = - Context.find ctxt cycle_eras_key >|= function + let open Lwt_syntax in + let+ bytes_opt = Context.find ctxt cycle_eras_key in + match bytes_opt with | None -> storage_error (Missing_key (cycle_eras_key, Get)) | Some bytes -> ( match Data_encoding.Binary.of_bytes_opt Level_repr.cycle_eras_encoding bytes with | None -> storage_error (Corrupted_data cycle_eras_key) - | Some cycle_eras -> ok cycle_eras) + | Some cycle_eras -> Ok cycle_eras) let set_cycle_eras ctxt cycle_eras = + let open Lwt_result_syntax in let bytes = Data_encoding.Binary.to_bytes_exn Level_repr.cycle_eras_encoding cycle_eras in - Context.add ctxt cycle_eras_key bytes >|= ok + let*! ctxt = Context.add ctxt cycle_eras_key bytes in + return ctxt type error += Failed_to_parse_parameter of bytes @@ -744,13 +765,15 @@ let () = (fun (json, msg) -> Failed_to_decode_parameter (json, msg)) let get_proto_param ctxt = - Context.find ctxt protocol_param_key >>= function + let open Lwt_result_syntax in + let*! bytes_opt = Context.find ctxt protocol_param_key in + match bytes_opt with | None -> failwith "Missing protocol parameters." | Some bytes -> ( match Data_encoding.Binary.of_bytes_opt Data_encoding.json bytes with | None -> tzfail (Failed_to_parse_parameter bytes) | Some json -> ( - Context.remove ctxt protocol_param_key >|= fun ctxt -> + let*! ctxt = Context.remove ctxt protocol_param_key in match Data_encoding.Json.destruct Parameters_repr.encoding json with | exception (Data_encoding.Json.Cannot_destruct _ as exn) -> Format.kasprintf @@ -761,8 +784,8 @@ let get_proto_param ctxt = Data_encoding.Json.pp json | param -> - Parameters_repr.check_params param >>? fun () -> ok (param, ctxt)) - ) + let*? () = Parameters_repr.check_params param in + return (param, ctxt))) let add_constants ctxt constants = let bytes = @@ -773,7 +796,9 @@ let add_constants ctxt constants = Context.add ctxt constants_key bytes let get_constants ctxt = - Context.find ctxt constants_key >|= function + let open Lwt_result_syntax in + let*! bytes_opt = Context.find ctxt constants_key in + match bytes_opt with | None -> failwith "Internal error: cannot read constants in context." | Some bytes -> ( match @@ -782,16 +807,19 @@ let get_constants ctxt = bytes with | None -> failwith "Internal error: cannot parse constants in context." - | Some constants -> ok constants) + | Some constants -> return constants) let patch_constants ctxt f = + let open Lwt_syntax in let constants = f (constants ctxt) in - add_constants (context ctxt) constants >|= fun context -> + let+ context = add_constants (context ctxt) constants in let ctxt = update_context ctxt context in update_constants ctxt constants let check_inited ctxt = - Context.find ctxt version_key >|= function + let open Lwt_syntax in + let+ bytes_opt = Context.find ctxt version_key in + match bytes_opt with | None -> failwith "Internal error: un-initialized context." | Some bytes -> let s = Bytes.to_string bytes in @@ -810,14 +838,16 @@ let check_cycle_eras (cycle_eras : Level_repr.cycle_eras) let prepare ~level ~predecessor_timestamp ~timestamp ~adaptive_issuance_enable ctxt = - Raw_level_repr.of_int32 level >>?= fun level -> - check_inited ctxt >>=? fun () -> - get_constants ctxt >>=? fun constants -> - Round_repr.Durations.create - ~first_round_duration:constants.minimal_block_delay - ~delay_increment_per_round:constants.delay_increment_per_round - >>?= fun round_durations -> - get_cycle_eras ctxt >|=? fun cycle_eras -> + let open Lwt_result_syntax in + let*? level = Raw_level_repr.of_int32 level in + let* () = check_inited ctxt in + let* constants = get_constants ctxt in + let*? round_durations = + Round_repr.Durations.create + ~first_round_duration:constants.minimal_block_delay + ~delay_increment_per_round:constants.delay_increment_per_round + in + let+ cycle_eras = get_cycle_eras ctxt in check_cycle_eras cycle_eras constants ; let level = Level_repr.level_from_raw ~cycle_eras level in let sc_rollup_current_messages = @@ -864,24 +894,32 @@ let prepare ~level ~predecessor_timestamp ~timestamp ~adaptive_issuance_enable type previous_protocol = Genesis of Parameters_repr.t | Oxford_018 let check_and_update_protocol_version ctxt = - (Context.find ctxt version_key >>= function - | None -> - failwith "Internal error: un-initialized context in check_first_block." - | Some bytes -> - let s = Bytes.to_string bytes in - if Compare.String.(s = Constants_repr.version_value) then - failwith "Internal error: previously initialized context." - else if Compare.String.(s = "genesis") then - get_proto_param ctxt >|=? fun (param, ctxt) -> (Genesis param, ctxt) - else if Compare.String.(s = "oxford_018") then return (Oxford_018, ctxt) - else Lwt.return @@ storage_error (Incompatible_protocol_version s)) - >>=? fun (previous_proto, ctxt) -> - Context.add ctxt version_key (Bytes.of_string Constants_repr.version_value) - >|= fun ctxt -> ok (previous_proto, ctxt) + let open Lwt_result_syntax in + let* previous_proto, ctxt = + let*! bytes_opt = Context.find ctxt version_key in + match bytes_opt with + | None -> + failwith "Internal error: un-initialized context in check_first_block." + | Some bytes -> + let s = Bytes.to_string bytes in + if Compare.String.(s = Constants_repr.version_value) then + failwith "Internal error: previously initialized context." + else if Compare.String.(s = "genesis") then + let+ param, ctxt = get_proto_param ctxt in + (Genesis param, ctxt) + else if Compare.String.(s = "oxford_018") then return (Oxford_018, ctxt) + else Lwt.return @@ storage_error (Incompatible_protocol_version s) + in + let*! ctxt = + Context.add ctxt version_key (Bytes.of_string Constants_repr.version_value) + in + return (previous_proto, ctxt) (* only for the migration *) let[@warning "-32"] get_previous_protocol_constants ctxt = - Context.find ctxt constants_key >>= function + let open Lwt_syntax in + let* bytes_opt = Context.find ctxt constants_key in + match bytes_opt with | None -> failwith "Internal error: cannot read previous protocol constants in context." @@ -895,7 +933,7 @@ let[@warning "-32"] get_previous_protocol_constants ctxt = failwith "Internal error: cannot parse previous protocol constants in \ context." - | Some constants -> Lwt.return constants) + | Some constants -> return constants) (* You should ensure that if the type `Constants_parametric_repr.t` is different from `Constants_parametric_previous_repr.t` or the value of these @@ -909,215 +947,228 @@ let[@warning "-32"] get_previous_protocol_constants ctxt = protocol. However, by doing so, you do not change the value of these constants inside the context. *) let prepare_first_block ~level ~timestamp chain_id ctxt = - check_and_update_protocol_version ctxt >>=? fun (previous_proto, ctxt) -> - (match previous_proto with - | Genesis param -> - Raw_level_repr.of_int32 level >>?= fun first_level -> - let cycle_era = - { - Level_repr.first_level; - first_cycle = Cycle_repr.root; - blocks_per_cycle = param.constants.blocks_per_cycle; - blocks_per_commitment = param.constants.blocks_per_commitment; - } - in - Level_repr.create_cycle_eras [cycle_era] >>?= fun cycle_eras -> - set_cycle_eras ctxt cycle_eras >>=? fun ctxt -> - add_constants ctxt param.constants >|= ok - | Oxford_018 -> - get_previous_protocol_constants ctxt >>= fun c -> - let cryptobox_parameters = - { - Dal.page_size = c.dal.cryptobox_parameters.page_size; - number_of_shards = c.dal.cryptobox_parameters.number_of_shards; - slot_size = c.dal.cryptobox_parameters.slot_size; - redundancy_factor = c.dal.cryptobox_parameters.redundancy_factor; - } - in - let dal = - Constants_parametric_repr. + let open Lwt_result_syntax in + let* previous_proto, ctxt = check_and_update_protocol_version ctxt in + let* ctxt = + match previous_proto with + | Genesis param -> + let*? first_level = Raw_level_repr.of_int32 level in + let cycle_era = { - feature_enable = c.dal.feature_enable; - number_of_slots = c.dal.number_of_slots; - attestation_lag = 4; - attestation_threshold = c.dal.attestation_threshold; - blocks_per_epoch = c.dal.blocks_per_epoch; - cryptobox_parameters; + Level_repr.first_level; + first_cycle = Cycle_repr.root; + blocks_per_cycle = param.constants.blocks_per_cycle; + blocks_per_commitment = param.constants.blocks_per_commitment; } - in - (* When stitching from Oxford and after, [Raw_level_repr.root] - should be replaced by the previous value, that is - [c.reveal_activation_level.*]. *) - let reveal_activation_level : - Constants_parametric_repr.sc_rollup_reveal_activation_level = - { - raw_data = - {blake2B = c.sc_rollup.reveal_activation_level.raw_data.blake2B}; - metadata = c.sc_rollup.reveal_activation_level.metadata; - dal_page = - (if c.dal.feature_enable then - c.sc_rollup.reveal_activation_level.dal_page - else if dal.feature_enable then - (* First level of the protocol with dal activated. *) - Raw_level_repr.of_int32_exn (Int32.succ level) - else - (* Deactivate the reveal if the dal is not enabled. - - assert (not (c.dal.feature_enable || dal.feature_enable)) - - We set the activation level to [pred max_int] to deactivate - the feature. The [pred] is needed to not trigger an encoding - exception with the value [Int32.int_min] (see - tezt/tests/mockup.ml). *) - Raw_level_repr.of_int32_exn Int32.(pred max_int)); - } - in - let sc_rollup = - Constants_parametric_repr. + in + let*? cycle_eras = Level_repr.create_cycle_eras [cycle_era] in + let* ctxt = set_cycle_eras ctxt cycle_eras in + let*! result = add_constants ctxt param.constants in + return result + | Oxford_018 -> + let*! c = get_previous_protocol_constants ctxt in + let cryptobox_parameters = { - enable = c.sc_rollup.enable; - arith_pvm_enable = c.sc_rollup.arith_pvm_enable; - origination_size = c.sc_rollup.origination_size; - challenge_window_in_blocks = c.sc_rollup.challenge_window_in_blocks; - stake_amount = c.sc_rollup.stake_amount; - commitment_period_in_blocks = - c.sc_rollup.commitment_period_in_blocks; - max_lookahead_in_blocks = c.sc_rollup.max_lookahead_in_blocks; - max_active_outbox_levels = c.sc_rollup.max_active_outbox_levels; - max_outbox_messages_per_level = - c.sc_rollup.max_outbox_messages_per_level; - number_of_sections_in_dissection = - c.sc_rollup.number_of_sections_in_dissection; - timeout_period_in_blocks = c.sc_rollup.timeout_period_in_blocks; - max_number_of_stored_cemented_commitments = - c.sc_rollup.max_number_of_stored_cemented_commitments; - max_number_of_parallel_games = - c.sc_rollup.max_number_of_parallel_games; - reveal_activation_level; - private_enable = - (* Activate for testnets only. *) - (* TODO: https://gitlab.com/tezos/tezos/-/issues/6204 - Do not forget to activate private rollups on mainnet - (prior to protocol P's snapshot). *) - not (Chain_id.equal Constants_repr.mainnet_id chain_id); + Dal.page_size = c.dal.cryptobox_parameters.page_size; + number_of_shards = c.dal.cryptobox_parameters.number_of_shards; + slot_size = c.dal.cryptobox_parameters.slot_size; + redundancy_factor = c.dal.cryptobox_parameters.redundancy_factor; } - in - let zk_rollup = - Constants_parametric_repr. + in + let dal = + Constants_parametric_repr. + { + feature_enable = c.dal.feature_enable; + number_of_slots = c.dal.number_of_slots; + attestation_lag = 4; + attestation_threshold = c.dal.attestation_threshold; + blocks_per_epoch = c.dal.blocks_per_epoch; + cryptobox_parameters; + } + in + (* When stitching from Oxford and after, [Raw_level_repr.root] + should be replaced by the previous value, that is + [c.reveal_activation_level.*]. *) + let reveal_activation_level : + Constants_parametric_repr.sc_rollup_reveal_activation_level = { - enable = c.zk_rollup.enable; - origination_size = c.zk_rollup.origination_size; - min_pending_to_process = c.zk_rollup.min_pending_to_process; - max_ticket_payload_size = c.zk_rollup.max_ticket_payload_size; + raw_data = + {blake2B = c.sc_rollup.reveal_activation_level.raw_data.blake2B}; + metadata = c.sc_rollup.reveal_activation_level.metadata; + dal_page = + (if c.dal.feature_enable then + c.sc_rollup.reveal_activation_level.dal_page + else if dal.feature_enable then + (* First level of the protocol with dal activated. *) + Raw_level_repr.of_int32_exn (Int32.succ level) + else + (* Deactivate the reveal if the dal is not enabled. + + assert (not (c.dal.feature_enable || dal.feature_enable)) + + We set the activation level to [pred max_int] to deactivate + the feature. The [pred] is needed to not trigger an encoding + exception with the value [Int32.int_min] (see + tezt/tests/mockup.ml). *) + Raw_level_repr.of_int32_exn Int32.(pred max_int)); } - in + in + let sc_rollup = + Constants_parametric_repr. + { + enable = c.sc_rollup.enable; + arith_pvm_enable = c.sc_rollup.arith_pvm_enable; + origination_size = c.sc_rollup.origination_size; + challenge_window_in_blocks = + c.sc_rollup.challenge_window_in_blocks; + stake_amount = c.sc_rollup.stake_amount; + commitment_period_in_blocks = + c.sc_rollup.commitment_period_in_blocks; + max_lookahead_in_blocks = c.sc_rollup.max_lookahead_in_blocks; + max_active_outbox_levels = c.sc_rollup.max_active_outbox_levels; + max_outbox_messages_per_level = + c.sc_rollup.max_outbox_messages_per_level; + number_of_sections_in_dissection = + c.sc_rollup.number_of_sections_in_dissection; + timeout_period_in_blocks = c.sc_rollup.timeout_period_in_blocks; + max_number_of_stored_cemented_commitments = + c.sc_rollup.max_number_of_stored_cemented_commitments; + max_number_of_parallel_games = + c.sc_rollup.max_number_of_parallel_games; + reveal_activation_level; + private_enable = + (* Activate for testnets only. *) + (* TODO: https://gitlab.com/tezos/tezos/-/issues/6204 + Do not forget to activate private rollups on mainnet + (prior to protocol P's snapshot). *) + not (Chain_id.equal Constants_repr.mainnet_id chain_id); + } + in + let zk_rollup = + Constants_parametric_repr. + { + enable = c.zk_rollup.enable; + origination_size = c.zk_rollup.origination_size; + min_pending_to_process = c.zk_rollup.min_pending_to_process; + max_ticket_payload_size = c.zk_rollup.max_ticket_payload_size; + } + in - let issuance_weights = - Constants_parametric_repr. - { - base_total_issued_per_minute = - c.issuance_weights.base_total_issued_per_minute; - baking_reward_fixed_portion_weight = - c.issuance_weights.baking_reward_fixed_portion_weight; - baking_reward_bonus_weight = - c.issuance_weights.baking_reward_bonus_weight; - attesting_reward_weight = c.issuance_weights.attesting_reward_weight; - liquidity_baking_subsidy_weight = - c.issuance_weights.liquidity_baking_subsidy_weight; - seed_nonce_revelation_tip_weight = - c.issuance_weights.seed_nonce_revelation_tip_weight; - vdf_revelation_tip_weight = - c.issuance_weights.vdf_revelation_tip_weight; - } - in + let issuance_weights = + Constants_parametric_repr. + { + base_total_issued_per_minute = + c.issuance_weights.base_total_issued_per_minute; + baking_reward_fixed_portion_weight = + c.issuance_weights.baking_reward_fixed_portion_weight; + baking_reward_bonus_weight = + c.issuance_weights.baking_reward_bonus_weight; + attesting_reward_weight = + c.issuance_weights.attesting_reward_weight; + liquidity_baking_subsidy_weight = + c.issuance_weights.liquidity_baking_subsidy_weight; + seed_nonce_revelation_tip_weight = + c.issuance_weights.seed_nonce_revelation_tip_weight; + vdf_revelation_tip_weight = + c.issuance_weights.vdf_revelation_tip_weight; + } + in - let adaptive_rewards_params = - Constants_parametric_repr. - { - issuance_ratio_min = - c.adaptive_issuance.adaptive_rewards_params.issuance_ratio_min; - issuance_ratio_max = - c.adaptive_issuance.adaptive_rewards_params.issuance_ratio_max; - max_bonus = c.adaptive_issuance.adaptive_rewards_params.max_bonus; - growth_rate = - c.adaptive_issuance.adaptive_rewards_params.growth_rate; - center_dz = c.adaptive_issuance.adaptive_rewards_params.center_dz; - radius_dz = c.adaptive_issuance.adaptive_rewards_params.radius_dz; - } - in + let adaptive_rewards_params = + Constants_parametric_repr. + { + issuance_ratio_min = + c.adaptive_issuance.adaptive_rewards_params.issuance_ratio_min; + issuance_ratio_max = + c.adaptive_issuance.adaptive_rewards_params.issuance_ratio_max; + max_bonus = c.adaptive_issuance.adaptive_rewards_params.max_bonus; + growth_rate = + c.adaptive_issuance.adaptive_rewards_params.growth_rate; + center_dz = c.adaptive_issuance.adaptive_rewards_params.center_dz; + radius_dz = c.adaptive_issuance.adaptive_rewards_params.radius_dz; + } + in - let adaptive_issuance = - Constants_parametric_repr. - { - global_limit_of_staking_over_baking = - c.adaptive_issuance.global_limit_of_staking_over_baking; - edge_of_staking_over_delegation = - c.adaptive_issuance.edge_of_staking_over_delegation; - launch_ema_threshold = c.adaptive_issuance.launch_ema_threshold; - adaptive_rewards_params; - } - in + let adaptive_issuance = + Constants_parametric_repr. + { + global_limit_of_staking_over_baking = + c.adaptive_issuance.global_limit_of_staking_over_baking; + edge_of_staking_over_delegation = + c.adaptive_issuance.edge_of_staking_over_delegation; + launch_ema_threshold = c.adaptive_issuance.launch_ema_threshold; + adaptive_rewards_params; + } + in - let constants = - Constants_parametric_repr. - { - preserved_cycles = c.preserved_cycles; - blocks_per_cycle = c.blocks_per_cycle; - blocks_per_commitment = c.blocks_per_commitment; - nonce_revelation_threshold = c.nonce_revelation_threshold; - blocks_per_stake_snapshot = c.blocks_per_stake_snapshot; - cycles_per_voting_period = c.cycles_per_voting_period; - hard_gas_limit_per_operation = c.hard_gas_limit_per_operation; - hard_gas_limit_per_block = c.hard_gas_limit_per_block; - proof_of_work_threshold = c.proof_of_work_threshold; - minimal_stake = c.minimal_stake; - minimal_frozen_stake = c.minimal_frozen_stake; - vdf_difficulty = c.vdf_difficulty; - origination_size = c.origination_size; - max_operations_time_to_live = c.max_operations_time_to_live; - issuance_weights; - cost_per_byte = c.cost_per_byte; - hard_storage_limit_per_operation = - c.hard_storage_limit_per_operation; - quorum_min = c.quorum_min; - quorum_max = c.quorum_max; - min_proposal_quorum = c.min_proposal_quorum; - liquidity_baking_toggle_ema_threshold = - c.liquidity_baking_toggle_ema_threshold; - minimal_block_delay = c.minimal_block_delay; - delay_increment_per_round = c.delay_increment_per_round; - consensus_committee_size = c.consensus_committee_size; - consensus_threshold = c.consensus_threshold; - minimal_participation_ratio = c.minimal_participation_ratio; - max_slashing_period = c.max_slashing_period; - limit_of_delegation_over_baking = c.limit_of_delegation_over_baking; - percentage_of_frozen_deposits_slashed_per_double_baking = - c.percentage_of_frozen_deposits_slashed_per_double_baking; - percentage_of_frozen_deposits_slashed_per_double_attestation = - c.percentage_of_frozen_deposits_slashed_per_double_attestation; - (* The `testnet_dictator` should absolutely be None on mainnet *) - testnet_dictator = c.testnet_dictator; - initial_seed = c.initial_seed; - cache_script_size = c.cache_script_size; - cache_stake_distribution_cycles = c.cache_stake_distribution_cycles; - cache_sampler_state_cycles = c.cache_sampler_state_cycles; - dal; - sc_rollup; - zk_rollup; - adaptive_issuance; - } - in - add_constants ctxt constants >>= fun ctxt -> return ctxt) - >>=? fun ctxt -> - prepare - ctxt - ~level - ~predecessor_timestamp:timestamp - ~timestamp - ~adaptive_issuance_enable:false - >|=? fun ctxt -> (previous_proto, ctxt) + let constants = + Constants_parametric_repr. + { + preserved_cycles = c.preserved_cycles; + blocks_per_cycle = c.blocks_per_cycle; + blocks_per_commitment = c.blocks_per_commitment; + nonce_revelation_threshold = c.nonce_revelation_threshold; + blocks_per_stake_snapshot = c.blocks_per_stake_snapshot; + cycles_per_voting_period = c.cycles_per_voting_period; + hard_gas_limit_per_operation = c.hard_gas_limit_per_operation; + hard_gas_limit_per_block = c.hard_gas_limit_per_block; + proof_of_work_threshold = c.proof_of_work_threshold; + minimal_stake = c.minimal_stake; + minimal_frozen_stake = c.minimal_frozen_stake; + vdf_difficulty = c.vdf_difficulty; + origination_size = c.origination_size; + max_operations_time_to_live = c.max_operations_time_to_live; + issuance_weights; + cost_per_byte = c.cost_per_byte; + hard_storage_limit_per_operation = + c.hard_storage_limit_per_operation; + quorum_min = c.quorum_min; + quorum_max = c.quorum_max; + min_proposal_quorum = c.min_proposal_quorum; + liquidity_baking_toggle_ema_threshold = + c.liquidity_baking_toggle_ema_threshold; + minimal_block_delay = c.minimal_block_delay; + delay_increment_per_round = c.delay_increment_per_round; + consensus_committee_size = c.consensus_committee_size; + consensus_threshold = c.consensus_threshold; + minimal_participation_ratio = c.minimal_participation_ratio; + max_slashing_period = c.max_slashing_period; + limit_of_delegation_over_baking = + c.limit_of_delegation_over_baking; + percentage_of_frozen_deposits_slashed_per_double_baking = + c.percentage_of_frozen_deposits_slashed_per_double_baking; + percentage_of_frozen_deposits_slashed_per_double_attestation = + c.percentage_of_frozen_deposits_slashed_per_double_attestation; + (* The `testnet_dictator` should absolutely be None on mainnet *) + testnet_dictator = c.testnet_dictator; + initial_seed = c.initial_seed; + cache_script_size = c.cache_script_size; + cache_stake_distribution_cycles = + c.cache_stake_distribution_cycles; + cache_sampler_state_cycles = c.cache_sampler_state_cycles; + dal; + sc_rollup; + zk_rollup; + adaptive_issuance; + } + in + let*! ctxt = add_constants ctxt constants in + return ctxt + in + let+ ctxt = + prepare + ctxt + ~level + ~predecessor_timestamp:timestamp + ~timestamp + ~adaptive_issuance_enable:false + in + (previous_proto, ctxt) -let activate ctxt h = Updater.activate (context ctxt) h >|= update_context ctxt +let activate ctxt h = + let open Lwt_syntax in + let+ new_ctxt = Updater.activate (context ctxt) h in + update_context ctxt new_ctxt (* Generic context ********************************************************) @@ -1139,70 +1190,94 @@ let mem ctxt k = Context.mem (context ctxt) k let mem_tree ctxt k = Context.mem_tree (context ctxt) k let get ctxt k = - Context.find (context ctxt) k >|= function - | None -> storage_error (Missing_key (k, Get)) - | Some v -> ok v + let open Lwt_result_syntax in + let*! v_opt = Context.find (context ctxt) k in + match v_opt with + | None -> Lwt.return @@ storage_error (Missing_key (k, Get)) + | Some v -> return v let get_tree ctxt k = - Context.find_tree (context ctxt) k >|= function - | None -> storage_error (Missing_key (k, Get)) - | Some v -> ok v + let open Lwt_result_syntax in + let*! v_opt = Context.find_tree (context ctxt) k in + match v_opt with + | None -> Lwt.return @@ storage_error (Missing_key (k, Get)) + | Some v -> return v let find ctxt k = Context.find (context ctxt) k let find_tree ctxt k = Context.find_tree (context ctxt) k -let add ctxt k v = Context.add (context ctxt) k v >|= update_context ctxt +let add ctxt k v = + let open Lwt_syntax in + let+ new_ctxt = Context.add (context ctxt) k v in + update_context ctxt new_ctxt let add_tree ctxt k v = - Context.add_tree (context ctxt) k v >|= update_context ctxt + let open Lwt_syntax in + let+ new_ctxt = Context.add_tree (context ctxt) k v in + update_context ctxt new_ctxt let init ctxt k v = - Context.mem (context ctxt) k >>= function + let open Lwt_result_syntax in + let*! result = Context.mem (context ctxt) k in + match result with | true -> Lwt.return @@ storage_error (Existing_key k) | _ -> - Context.add (context ctxt) k v >|= fun context -> - ok (update_context ctxt context) + let*! context = Context.add (context ctxt) k v in + return (update_context ctxt context) let init_tree ctxt k v : _ tzresult Lwt.t = - Context.mem_tree (context ctxt) k >>= function + let open Lwt_result_syntax in + let*! result = Context.mem_tree (context ctxt) k in + match result with | true -> Lwt.return @@ storage_error (Existing_key k) | _ -> - Context.add_tree (context ctxt) k v >|= fun context -> - ok (update_context ctxt context) + let*! context = Context.add_tree (context ctxt) k v in + return (update_context ctxt context) let update ctxt k v = - Context.mem (context ctxt) k >>= function + let open Lwt_result_syntax in + let*! result = Context.mem (context ctxt) k in + match result with | false -> Lwt.return @@ storage_error (Missing_key (k, Set)) | _ -> - Context.add (context ctxt) k v >|= fun context -> - ok (update_context ctxt context) + let*! context = Context.add (context ctxt) k v in + return (update_context ctxt context) let update_tree ctxt k v = - Context.mem_tree (context ctxt) k >>= function + let open Lwt_result_syntax in + let*! result = Context.mem_tree (context ctxt) k in + match result with | false -> Lwt.return @@ storage_error (Missing_key (k, Set)) | _ -> - Context.add_tree (context ctxt) k v >|= fun context -> - ok (update_context ctxt context) + let*! context = Context.add_tree (context ctxt) k v in + return (update_context ctxt context) (* Verify that the key is present before deleting *) let remove_existing ctxt k = - Context.mem (context ctxt) k >>= function + let open Lwt_result_syntax in + let*! result = Context.mem (context ctxt) k in + match result with | false -> Lwt.return @@ storage_error (Missing_key (k, Del)) | _ -> - Context.remove (context ctxt) k >|= fun context -> - ok (update_context ctxt context) + let*! context = Context.remove (context ctxt) k in + return (update_context ctxt context) (* Verify that the key is present before deleting *) let remove_existing_tree ctxt k = - Context.mem_tree (context ctxt) k >>= function + let open Lwt_result_syntax in + let*! result = Context.mem_tree (context ctxt) k in + match result with | false -> Lwt.return @@ storage_error (Missing_key (k, Del)) | _ -> - Context.remove (context ctxt) k >|= fun context -> - ok (update_context ctxt context) + let*! context = Context.remove (context ctxt) k in + return (update_context ctxt context) (* Do not verify before deleting *) -let remove ctxt k = Context.remove (context ctxt) k >|= update_context ctxt +let remove ctxt k = + let open Lwt_syntax in + let+ new_ctxt = Context.remove (context ctxt) k in + update_context ctxt new_ctxt let add_or_remove ctxt k = function | None -> remove ctxt k @@ -1234,46 +1309,74 @@ module Tree : let empty ctxt = Context.Tree.empty (context ctxt) let get t k = - find t k >|= function - | None -> storage_error (Missing_key (k, Get)) - | Some v -> ok v + let open Lwt_result_syntax in + let*! result = find t k in + match result with + | None -> Lwt.return @@ storage_error (Missing_key (k, Get)) + | Some v -> return v let get_tree t k = - find_tree t k >|= function - | None -> storage_error (Missing_key (k, Get)) - | Some v -> ok v + let open Lwt_result_syntax in + let*! result = find_tree t k in + match result with + | None -> Lwt.return @@ storage_error (Missing_key (k, Get)) + | Some v -> return v let init t k v = - mem t k >>= function + let open Lwt_result_syntax in + let*! result = mem t k in + match result with | true -> Lwt.return @@ storage_error (Existing_key k) - | _ -> add t k v >|= ok + | _ -> + let*! tree = add t k v in + return tree let init_tree t k v = - mem_tree t k >>= function + let open Lwt_result_syntax in + let*! result = mem_tree t k in + match result with | true -> Lwt.return @@ storage_error (Existing_key k) - | _ -> add_tree t k v >|= ok + | _ -> + let*! tree = add_tree t k v in + return tree let update t k v = - mem t k >>= function + let open Lwt_result_syntax in + let*! result = mem t k in + match result with | false -> Lwt.return @@ storage_error (Missing_key (k, Set)) - | _ -> add t k v >|= ok + | _ -> + let*! tree = add t k v in + return tree let update_tree t k v = - mem_tree t k >>= function + let open Lwt_result_syntax in + let*! result = mem_tree t k in + match result with | false -> Lwt.return @@ storage_error (Missing_key (k, Set)) - | _ -> add_tree t k v >|= ok + | _ -> + let*! tree = add_tree t k v in + return tree (* Verify that the key is present before deleting *) let remove_existing t k = - mem t k >>= function + let open Lwt_result_syntax in + let*! result = mem t k in + match result with | false -> Lwt.return @@ storage_error (Missing_key (k, Del)) - | _ -> remove t k >|= ok + | _ -> + let*! tree = remove t k in + return tree (* Verify that the key is present before deleting *) let remove_existing_tree t k = - mem_tree t k >>= function + let open Lwt_result_syntax in + let*! result = mem_tree t k in + match result with | false -> Lwt.return @@ storage_error (Missing_key (k, Del)) - | _ -> remove t k >|= ok + | _ -> + let*! tree = remove t k in + return tree let add_or_remove t k = function None -> remove t k | Some v -> add t k v @@ -1299,8 +1402,8 @@ let fold_map_temporary_lazy_storage_ids ctxt f = (update_temporary_lazy_storage_ids ctxt temporary_lazy_storage_ids, x) let map_temporary_lazy_storage_ids_s ctxt f = - f (temporary_lazy_storage_ids ctxt) - >|= fun (ctxt, temporary_lazy_storage_ids) -> + let open Lwt_syntax in + let+ ctxt, temporary_lazy_storage_ids = f (temporary_lazy_storage_ids ctxt) in update_temporary_lazy_storage_ids ctxt temporary_lazy_storage_ids module Cache = struct @@ -1317,14 +1420,16 @@ module Cache = struct let find c k = Context.Cache.find (context c) k let set_cache_layout c layout = - Context.Cache.set_cache_layout (context c) layout >>= fun ctxt -> - Lwt.return (update_context c ctxt) + let open Lwt_syntax in + let+ ctxt = Context.Cache.set_cache_layout (context c) layout in + update_context c ctxt let update c k v = Context.Cache.update (context c) k v |> update_context c let sync c cache_nonce = - Context.Cache.sync (context c) ~cache_nonce >>= fun ctxt -> - Lwt.return (update_context c ctxt) + let open Lwt_syntax in + let+ ctxt = Context.Cache.sync (context c) ~cache_nonce in + update_context c ctxt let clear c = Context.Cache.clear (context c) |> update_context c @@ -1356,27 +1461,30 @@ let record_dictator_proposal_seen ctxt = update_dictator_proposal_seen ctxt true let dictator_proposal_seen ctxt = dictator_proposal_seen ctxt let init_sampler_for_cycle ctxt cycle seed state = + let open Result_syntax in let map = sampler_state ctxt in - if Cycle_repr.Map.mem cycle map then error (Sampler_already_set cycle) + if Cycle_repr.Map.mem cycle map then tzfail (Sampler_already_set cycle) else let map = Cycle_repr.Map.add cycle (seed, state) map in let ctxt = update_sampler_state ctxt map in - ok ctxt + return ctxt let sampler_for_cycle ~read ctxt cycle = + let open Lwt_result_syntax in let map = sampler_state ctxt in match Cycle_repr.Map.find cycle map with | Some (seed, state) -> return (ctxt, seed, state) | None -> - read ctxt >>=? fun (seed, state) -> + let* seed, state = read ctxt in let map = Cycle_repr.Map.add cycle (seed, state) map in let ctxt = update_sampler_state ctxt map in return (ctxt, seed, state) let stake_distribution_for_current_cycle ctxt = + let open Result_syntax in match ctxt.back.stake_distribution_for_current_cycle with - | None -> error Stake_distribution_not_set - | Some s -> ok s + | None -> tzfail Stake_distribution_not_set + | Some s -> return s let init_stake_distribution_for_current_cycle ctxt stake_distribution_for_current_cycle = @@ -1469,7 +1577,8 @@ module Consensus : {ctxt with back = {ctxt.back with consensus = f ctxt.back.consensus}} let[@inline] update_consensus_with_tzresult ctxt f = - f ctxt.back.consensus >|? fun consensus -> + let open Result_syntax in + let+ consensus = f ctxt.back.consensus in {ctxt with back = {ctxt.back with consensus}} let[@inline] allowed_attestations ctxt = @@ -1564,7 +1673,7 @@ module Dal = struct match Dal.make cryptobox_parameters with | Ok cryptobox -> return cryptobox | Error (`Fail explanation) -> - error (Dal_errors_repr.Dal_cryptobox_error {explanation}) + tzfail (Dal_errors_repr.Dal_cryptobox_error {explanation}) let number_of_slots ctxt = ctxt.back.constants.dal.number_of_slots @@ -1578,6 +1687,7 @@ module Dal = struct {ctxt with back = {ctxt.back with dal_attestation_slot_accountability}} let register_slot_header ctxt slot_header = + let open Result_syntax in match Dal_slot_repr.Slot_market.register ctxt.back.dal_slot_fee_market @@ -1587,14 +1697,14 @@ module Dal = struct let length = Dal_slot_repr.Slot_market.length ctxt.back.dal_slot_fee_market in - error + tzfail (Dal_errors_repr.Dal_register_invalid_slot_header {length; slot_header}) | Some (dal_slot_fee_market, updated) -> if not updated then - error + tzfail (Dal_errors_repr.Dal_publish_slot_header_duplicate {slot_header}) - else ok {ctxt with back = {ctxt.back with dal_slot_fee_market}} + else return {ctxt with back = {ctxt.back with dal_slot_fee_market}} let candidates ctxt = Dal_slot_repr.Slot_market.candidates ctxt.back.dal_slot_fee_market @@ -1634,6 +1744,7 @@ module Dal = struct and/or we take into account for the model of DAL that at every level, a percentage of DAL attestations cannot be received. *) let compute_committee ctxt pkh_from_tenderbake_slot = + let open Lwt_result_syntax in let Constants_parametric_repr. { dal = {cryptobox_parameters = {number_of_shards; _}; _}; @@ -1669,8 +1780,8 @@ module Dal = struct if Compare.Int.(index < 0) then return committee else let shard_index = index mod consensus_committee_size in - Slot_repr.of_int shard_index >>?= fun slot -> - pkh_from_tenderbake_slot slot >>=? fun (_ctxt, pkh) -> + let*? slot = Slot_repr.of_int shard_index in + let* _ctxt, pkh = pkh_from_tenderbake_slot slot in (* The [Slot_repr] module is related to the Tenderbake committee. *) let slot_index = Slot_repr.to_int slot in (* An optimisation could be to return only [pkh_to_shards] map @@ -1683,8 +1794,9 @@ module Dal = struct committee. This one only projects the Tenderbake committee into the DAL committee. The next one reorders the slots so that they are grouped by public key hash. *) - compute_power (number_of_shards - 1) empty_dal_committee - >>=? fun unordered_committee -> + let* unordered_committee = + compute_power (number_of_shards - 1) empty_dal_committee + in let dal_committee = Signature.Public_key_hash.Map.fold (fun pkh (_, power) (total_power, committee) -> @@ -1724,8 +1836,11 @@ type local_context = { } let with_local_context ctxt key f = - (find_tree ctxt key >|= function None -> Tree.empty ctxt | Some tree -> tree) - >>= fun tree -> + let open Lwt_result_syntax in + let*! tree_opt = find_tree ctxt key in + let tree = + match tree_opt with None -> Tree.empty ctxt | Some tree -> tree + in let local_ctxt = { tree; @@ -1734,12 +1849,12 @@ let with_local_context ctxt key f = unlimited_operation_gas = unlimited_operation_gas ctxt; } in - f local_ctxt >>=? fun (local_ctxt, res) -> - add_tree ctxt key local_ctxt.tree >|= fun ctxt -> + let* local_ctxt, res = f local_ctxt in + let*! ctxt = add_tree ctxt key local_ctxt.tree in update_remaining_operation_gas ctxt local_ctxt.remaining_operation_gas |> fun ctxt -> update_unlimited_operation_gas ctxt local_ctxt.unlimited_operation_gas - |> fun ctxt -> ok (ctxt, res) + |> fun ctxt -> return (ctxt, res) module Local_context : sig include @@ -1757,11 +1872,12 @@ end = struct type t = local_context let consume_gas local cost = + let open Result_syntax in match Gas_limit_repr.raw_consume local.remaining_operation_gas cost with | Some gas_counter -> Ok {local with remaining_operation_gas = gas_counter} | None -> - if local.unlimited_operation_gas then ok local - else error Operation_quota_exceeded + if local.unlimited_operation_gas then return local + else tzfail Operation_quota_exceeded let tree local = local.tree @@ -1782,35 +1898,59 @@ end = struct let get_tree local = Tree.get_tree (tree local) let update local key b = - Tree.update (tree local) key b >|=? update_root_tree local + let open Lwt_result_syntax in + let+ tree = Tree.update (tree local) key b in + update_root_tree local tree let update_tree local key b = - Tree.update_tree (tree local) key b >|=? update_root_tree local + let open Lwt_result_syntax in + let+ tree = Tree.update_tree (tree local) key b in + update_root_tree local tree let init local key b = - Tree.init (tree local) key b >|=? update_root_tree local + let open Lwt_result_syntax in + let+ tree = Tree.init (tree local) key b in + update_root_tree local tree let init_tree local key t = - Tree.init_tree (tree local) key t >|=? update_root_tree local + let open Lwt_result_syntax in + let+ tree = Tree.init_tree (tree local) key t in + update_root_tree local tree - let add local i b = Tree.add (tree local) i b >|= update_root_tree local + let add local i b = + let open Lwt_syntax in + let+ tree = Tree.add (tree local) i b in + update_root_tree local tree let add_tree local i t = - Tree.add_tree (tree local) i t >|= update_root_tree local + let open Lwt_syntax in + let+ tree = Tree.add_tree (tree local) i t in + update_root_tree local tree - let remove local i = Tree.remove (tree local) i >|= update_root_tree local + let remove local i = + let open Lwt_syntax in + let+ tree = Tree.remove (tree local) i in + update_root_tree local tree let remove_existing local key = - Tree.remove_existing (tree local) key >|=? update_root_tree local + let open Lwt_result_syntax in + let+ tree = Tree.remove_existing (tree local) key in + update_root_tree local tree let remove_existing_tree local key = - Tree.remove_existing_tree (tree local) key >|=? update_root_tree local + let open Lwt_result_syntax in + let+ tree = Tree.remove_existing_tree (tree local) key in + update_root_tree local tree let add_or_remove local key vopt = - Tree.add_or_remove (tree local) key vopt >|= update_root_tree local + let open Lwt_syntax in + let+ tree = Tree.add_or_remove (tree local) key vopt in + update_root_tree local tree let add_or_remove_tree local key topt = - Tree.add_or_remove_tree (tree local) key topt >|= update_root_tree local + let open Lwt_syntax in + let+ tree = Tree.add_or_remove_tree (tree local) key topt in + update_root_tree local tree let fold ?depth local key ~order ~init ~f = Tree.fold ?depth (tree local) key ~order ~init ~f diff --git a/src/proto_alpha/lib_protocol/raw_context_intf.ml b/src/proto_alpha/lib_protocol/raw_context_intf.ml index fa4789f7c8bd1d5a34a4ecfe40be50ea9c6c65ba..ff7bc662044a44e62995461db88e93b26f11e27c 100644 --- a/src/proto_alpha/lib_protocol/raw_context_intf.ml +++ b/src/proto_alpha/lib_protocol/raw_context_intf.ml @@ -189,7 +189,7 @@ module type VIEW = sig (** [length t key] is an Lwt promise that resolves to the number of files and sub-nodes stored under [k] in [t]. - It is equivalent to [list t k >|= List.length] but has a constant-time + It is equivalent to [let+ l = list t k in List.length l] but has a constant-time complexity. Most of the time, this function does not perform any I/O as the length is