diff --git a/src/proto_alpha/lib_protocol/block_header_repr.ml b/src/proto_alpha/lib_protocol/block_header_repr.ml index 514bb50c69d5e25325f4ddf89f924e53de71d2ce..c56f721baf2937a063e3c5b2642c5bfe02747b61 100644 --- a/src/proto_alpha/lib_protocol/block_header_repr.ml +++ b/src/proto_alpha/lib_protocol/block_header_repr.ml @@ -331,6 +331,7 @@ let () = let check_signature (block : t) (chain_id : Chain_id.t) (key : Signature.Public_key.t) = + let open Result_syntax in let check_signature key ({shell; protocol_data = {contents; signature}} : t) = let unsigned_header = Data_encoding.Binary.to_bytes_exn unsigned_encoding (shell, contents) @@ -341,9 +342,9 @@ let check_signature (block : t) (chain_id : Chain_id.t) signature unsigned_header in - if check_signature key block then ok () + if check_signature key block then return_unit else - error (Invalid_block_signature (hash block, Signature.Public_key.hash key)) + tzfail (Invalid_block_signature (hash block, Signature.Public_key.hash key)) let check_payload_round ~round ~payload_round = error_when @@ -352,14 +353,16 @@ let check_payload_round ~round ~payload_round = let check_timestamp round_durations ~timestamp ~round ~predecessor_timestamp ~predecessor_round = - Round_repr.timestamp_of_round - round_durations - ~predecessor_timestamp - ~predecessor_round - ~round - >>? fun expected_timestamp -> - if Time_repr.(expected_timestamp = timestamp) then Error_monad.ok () - else error (Wrong_timestamp (timestamp, expected_timestamp)) + let open Result_syntax in + let* expected_timestamp = + Round_repr.timestamp_of_round + round_durations + ~predecessor_timestamp + ~predecessor_round + ~round + in + if Time_repr.(expected_timestamp = timestamp) then return_unit + else tzfail (Wrong_timestamp (timestamp, expected_timestamp)) module Proof_of_work = struct let check_hash hash stamp_threshold = @@ -374,13 +377,14 @@ module Proof_of_work = struct check_hash hash stamp_threshold let check_proof_of_work_stamp ~proof_of_work_threshold block = + let open Result_syntax in if check_header_proof_of_work_stamp block.shell block.protocol_data.contents proof_of_work_threshold - then ok () - else error Invalid_stamp + then return_unit + else tzfail Invalid_stamp end let begin_validate_block_header ~(block_header : t) ~(chain_id : Chain_id.t) @@ -389,6 +393,7 @@ let begin_validate_block_header ~(block_header : t) ~(chain_id : Chain_id.t) ~(delegate_pk : Signature.Public_key.t) ~(round_durations : Round_repr.Durations.t) ~(proof_of_work_threshold : int64) ~(expected_commitment : bool) = + let open Result_syntax in (* Level relationship between current node and the predecessor is done by the shell. We know that level is predecessor level + 1. The predecessor block hash is guaranteed by the shell to be the @@ -398,21 +403,26 @@ let begin_validate_block_header ~(block_header : t) ~(chain_id : Chain_id.t) block_header.protocol_data.contents in let raw_level = block_header.shell.level in - Proof_of_work.check_proof_of_work_stamp ~proof_of_work_threshold block_header - >>? fun () -> - Raw_level_repr.of_int32 raw_level >>? fun level -> - check_signature block_header chain_id delegate_pk >>? fun () -> + let* () = + Proof_of_work.check_proof_of_work_stamp + ~proof_of_work_threshold + block_header + in + let* level = Raw_level_repr.of_int32 raw_level in + let* () = check_signature block_header chain_id delegate_pk in let round = Fitness_repr.round fitness in - check_payload_round ~round ~payload_round >>? fun () -> - check_timestamp - round_durations - ~predecessor_timestamp - ~predecessor_round - ~timestamp - ~round - >>? fun () -> - Fitness_repr.check_except_locked_round fitness ~level ~predecessor_round - >>? fun () -> + let* () = check_payload_round ~round ~payload_round in + let* () = + check_timestamp + round_durations + ~predecessor_timestamp + ~predecessor_round + ~timestamp + ~round + in + let* () = + Fitness_repr.check_except_locked_round fitness ~level ~predecessor_round + in let has_commitment = match seed_nonce_hash with None -> false | Some _ -> true in diff --git a/src/proto_alpha/lib_protocol/bond_id_repr.ml b/src/proto_alpha/lib_protocol/bond_id_repr.ml index d366769ed2a44f22bc4916a151b31c11aedaa99f..82d9f444c9e78b6699e8f0cca203802bcb25bfde 100644 --- a/src/proto_alpha/lib_protocol/bond_id_repr.ml +++ b/src/proto_alpha/lib_protocol/bond_id_repr.ml @@ -73,9 +73,9 @@ let destruct id = in if starts_with ~prefix:Sc_rollup_repr.Address.prefix id then match Sc_rollup_repr.Address.of_b58check_opt id with - | Some id -> Result.ok (Sc_rollup_bond_id id) - | None -> Result.error "Cannot parse smart rollup id" - else Result.error "Cannot parse rollup id" + | Some id -> Ok (Sc_rollup_bond_id id) + | None -> Error "Cannot parse smart rollup id" + else Error "Cannot parse rollup id" let construct = function | Sc_rollup_bond_id id -> Sc_rollup_repr.Address.to_b58check id diff --git a/src/proto_alpha/lib_protocol/bounded_history_repr.ml b/src/proto_alpha/lib_protocol/bounded_history_repr.ml index d5cf89fea002e022cb33b92f3233792001baa221..c3d6a3daaf8d1934a3b0dc82720b13c783450fa1 100644 --- a/src/proto_alpha/lib_protocol/bounded_history_repr.ml +++ b/src/proto_alpha/lib_protocol/bounded_history_repr.ml @@ -210,7 +210,7 @@ module Make (Name : NAME) (Key : KEY) (Value : VALUE) : else match Map.find key t.events with | Some value' when not (Value.equal value value') -> - error + tzfail @@ Key_bound_to_different_value {key; existing_value = value'; given_value = value} | _ -> ( diff --git a/src/proto_alpha/lib_protocol/cache_repr.ml b/src/proto_alpha/lib_protocol/cache_repr.ml index 909b87fb31575d154cef675ff57bf9aff5b7e844..1b05444ffa173a1ba4184fb0f292a01fd987d83f 100644 --- a/src/proto_alpha/lib_protocol/cache_repr.ml +++ b/src/proto_alpha/lib_protocol/cache_repr.ml @@ -124,6 +124,7 @@ module Admin = struct include Raw_context.Cache let future_cache_expectation ?blocks_before_activation ctxt ~time_in_blocks = + let open Lwt_result_syntax in let time_in_blocks' = Int32.of_int time_in_blocks in let blocks_per_voting_period = Int32.( @@ -131,10 +132,12 @@ module Admin = struct (Constants_storage.cycles_per_voting_period ctxt) (Constants_storage.blocks_per_cycle ctxt)) in - (match blocks_before_activation with - | None -> Voting_period_storage.blocks_before_activation ctxt - | Some block -> return_some block) - >>=? function + let* block_opt = + match blocks_before_activation with + | None -> Voting_period_storage.blocks_before_activation ctxt + | Some block -> return_some block + in + match block_opt with | Some block when Compare.Int32.( (Compare.Int32.(block >= 0l) && block <= time_in_blocks') @@ -217,6 +220,7 @@ end let register_exn (type cvalue) (module C : CLIENT with type cached_value = cvalue) : (module INTERFACE with type cached_value = cvalue) = + let open Lwt_result_syntax in if Compare.Int.(C.cache_index < 0) || Compare.Int.(Constants_repr.cache_layout_size <= C.cache_index) @@ -229,7 +233,8 @@ let register_exn (type cvalue) let () = let voi ctxt i = - C.value_of_identifier ctxt i >>=? fun v -> return (K v) + let* v = C.value_of_identifier ctxt i in + return (K v) in value_of_key_handlers := NamespaceMap.add C.namespace voi !value_of_key_handlers @@ -243,21 +248,27 @@ let register_exn (type cvalue) @@ Admin.cache_size_limit ctxt ~cache_index:C.cache_index let update ctxt id v = + let open Result_syntax in let cache_size_in_bytes = size ctxt in - Raw_context.consume_gas - ctxt - (Cache_costs.cache_update ~cache_size_in_bytes) - >|? fun ctxt -> + let+ ctxt = + Raw_context.consume_gas + ctxt + (Cache_costs.cache_update ~cache_size_in_bytes) + in let v = Option.map (fun (v, size) -> (K v, size)) v in Admin.update ctxt (mk ~id) v let find ctxt id = let cache_size_in_bytes = size ctxt in - Raw_context.consume_gas ctxt (Cache_costs.cache_find ~cache_size_in_bytes) - >>?= fun ctxt -> - Admin.find ctxt (mk ~id) >>= function - | None -> return None - | Some (K v) -> return (Some v) + let*? ctxt = + Raw_context.consume_gas + ctxt + (Cache_costs.cache_find ~cache_size_in_bytes) + in + let*! value_opt = Admin.find ctxt (mk ~id) in + match value_opt with + | None -> return_none + | Some (K v) -> return_some v | _ -> (* This execution path is impossible because all the keys of C's namespace (which is unique to C) are constructed with diff --git a/src/proto_alpha/lib_protocol/constants_repr.ml b/src/proto_alpha/lib_protocol/constants_repr.ml index 3d1dc9e80362a603addb6776c4bc7a7aaeac67a8..e2363dc4b51be9e1cd5c5a8a7c3062429f98b909 100644 --- a/src/proto_alpha/lib_protocol/constants_repr.ml +++ b/src/proto_alpha/lib_protocol/constants_repr.ml @@ -178,181 +178,209 @@ let () = (fun reason -> Invalid_protocol_constants reason) let check_constants constants = + let open Result_syntax in let open Constants_parametric_repr in - error_unless - Period_repr.(constants.minimal_block_delay > zero) - (Invalid_protocol_constants - "The minimal block delay must be greater than zero") - >>? fun () -> - error_unless - Period_repr.(constants.delay_increment_per_round > zero) - (Invalid_protocol_constants - "The delay increment per round must be greater than zero") - >>? fun () -> - error_unless - Compare.Int.(constants.consensus_committee_size > 0) - (Invalid_protocol_constants - "The consensus committee size must be strictly greater than 0.") - >>? fun () -> - error_unless - Compare.Int.( - constants.consensus_threshold >= 0 - && constants.consensus_threshold <= constants.consensus_committee_size) - (Invalid_protocol_constants - "The consensus threshold must be greater than or equal to 0 and less \ - than or equal to the consensus commitee size.") - >>? fun () -> - error_unless - (let Ratio_repr.{numerator; denominator} = - constants.minimal_participation_ratio - in - Compare.Int.(numerator >= 0 && denominator > 0)) - (Invalid_protocol_constants - "The minimal participation ratio must be a non-negative valid ratio.") - >>? fun () -> - error_unless - Compare.Int.( - constants.minimal_participation_ratio.numerator - <= constants.minimal_participation_ratio.denominator) - (Invalid_protocol_constants - "The minimal participation ratio must be less than or equal to 100%.") - >>? fun () -> - error_unless - Compare.Int.(constants.max_slashing_period > 0) - (Invalid_protocol_constants - "The unfreeze delay must be strictly greater than 0.") - >>? fun () -> + let* () = + error_unless + Period_repr.(constants.minimal_block_delay > zero) + (Invalid_protocol_constants + "The minimal block delay must be greater than zero") + in + let* () = + error_unless + Period_repr.(constants.delay_increment_per_round > zero) + (Invalid_protocol_constants + "The delay increment per round must be greater than zero") + in + let* () = + error_unless + Compare.Int.(constants.consensus_committee_size > 0) + (Invalid_protocol_constants + "The consensus committee size must be strictly greater than 0.") + in + let* () = + error_unless + Compare.Int.( + constants.consensus_threshold >= 0 + && constants.consensus_threshold <= constants.consensus_committee_size) + (Invalid_protocol_constants + "The consensus threshold must be greater than or equal to 0 and less \ + than or equal to the consensus commitee size.") + in + let* () = + error_unless + (let Ratio_repr.{numerator; denominator} = + constants.minimal_participation_ratio + in + Compare.Int.(numerator >= 0 && denominator > 0)) + (Invalid_protocol_constants + "The minimal participation ratio must be a non-negative valid ratio.") + in + let* () = + error_unless + Compare.Int.( + constants.minimal_participation_ratio.numerator + <= constants.minimal_participation_ratio.denominator) + (Invalid_protocol_constants + "The minimal participation ratio must be less than or equal to 100%.") + in + let* () = + error_unless + Compare.Int.(constants.max_slashing_period > 0) + (Invalid_protocol_constants + "The unfreeze delay must be strictly greater than 0.") + in (* The [limit_of_delegation_over_baking] should be non-negative. *) - error_unless - Compare.Int.(constants.limit_of_delegation_over_baking >= 0) - (Invalid_protocol_constants - "The delegation over baking limit must be greater than or equal to 0.") - >>? fun () -> - error_unless - Compare.Int.( - constants.percentage_of_frozen_deposits_slashed_per_double_baking >= 0 - && constants.percentage_of_frozen_deposits_slashed_per_double_baking - <= 100) - (Invalid_protocol_constants - "The percentage of frozen deposits slashed per double baking must be \ - between 0 and 100 included.") - >>? fun () -> - error_unless - Compare.Int.( - constants.percentage_of_frozen_deposits_slashed_per_double_attestation - >= 0 - && constants.percentage_of_frozen_deposits_slashed_per_double_attestation - <= 100) - (Invalid_protocol_constants - "The percentage of frozen deposits slashed per double attestation must \ - be between 0 and 100 included.") - >>? fun () -> - error_unless - (let snapshot_frequence = - Int32.div constants.blocks_per_cycle constants.blocks_per_stake_snapshot - in - Compare.Int32.( - snapshot_frequence > Int32.zero - && snapshot_frequence < Int32.of_int (1 lsl 16))) - (Invalid_protocol_constants - "The ratio blocks_per_cycle per blocks_per_stake_snapshot should be \ - between 1 and 65535") - >>? fun () -> - error_unless - Compare.Int32.( - constants.nonce_revelation_threshold > Int32.zero - && constants.nonce_revelation_threshold < constants.blocks_per_cycle) - (Invalid_protocol_constants - "The nonce revelation threshold must be strictly smaller than \ - blocks_per_cycle and strictly positive.") - >>? fun () -> - error_unless - Compare.Int64.( - let threshold = Int64.of_int32 constants.nonce_revelation_threshold in - let block = Period_repr.to_seconds constants.minimal_block_delay in - let ips = - (* We reduce the ips for short blocks_per_commitment so that we have - low difficulty during tests *) - if Compare.Int32.(constants.blocks_per_commitment > 32l) then - Int64.of_int 200_000 - else Int64.one - in - let factor = Int64.of_int 5 in - let difficulty = Int64.(mul (mul ips factor) (mul threshold block)) in - constants.vdf_difficulty > difficulty) - (Invalid_protocol_constants - "The VDF difficulty must be strictly greater than the product of the \ - nonce_revelation_threshold, the minimial_block_delay, a benchmark of \ - modulo squaring in class groups and a security threshold.") - >>? fun () -> - error_unless - Compare.Int.(constants.sc_rollup.origination_size >= 0) - (Invalid_protocol_constants - "The smart rollup origination size must be non-negative.") - >>? fun () -> - error_unless - Compare.Int.(constants.sc_rollup.challenge_window_in_blocks >= 0) - (Invalid_protocol_constants - "The smart rollup challenge window in blocks must be non-negative.") - >>? fun () -> - error_unless - Tez_repr.(constants.sc_rollup.stake_amount >= zero) - (Invalid_protocol_constants - "The smart rollup max stake amount must be non-negative.") - >>? fun () -> - error_unless - Compare.Int.(constants.sc_rollup.commitment_period_in_blocks > 0) - (Invalid_protocol_constants - "The smart rollup commitment period in blocks must be strictly greater \ - than 0.") - >>? fun () -> - error_unless - (let sc_rollup_max_lookahead_in_blocks = - constants.sc_rollup.max_lookahead_in_blocks - in - Compare.Int32.( - sc_rollup_max_lookahead_in_blocks - > Int32.of_int constants.sc_rollup.commitment_period_in_blocks - && (* Check that [smart_rollup_challenge_window_in_blocks < - smart_rollup_max_lookahead_in_blocks]. Otherwise committers would be - forced to commit at an artificially slow rate, affecting the - throughput of the rollup. *) - sc_rollup_max_lookahead_in_blocks - > Int32.of_int constants.sc_rollup.challenge_window_in_blocks)) - (Invalid_protocol_constants - "The smart rollup max lookahead in blocks must be greater than \ - [smart_rollup_commitment_period_in_blocks] and \ - [smart_rollup_challenge_window_in_blocks].") - >>? fun () -> - error_unless - Compare.Int.( - constants.dal.number_of_slots > 0 && constants.dal.number_of_slots <= 256) - (Invalid_protocol_constants - "The number of data availability slot must be between 1 and 256") - >>? fun () -> - error_unless - Compare.Int32.( - constants.dal.blocks_per_epoch > 0l - && constants.dal.blocks_per_epoch <= constants.blocks_per_cycle - && Int32.rem constants.blocks_per_cycle constants.dal.blocks_per_epoch - = 0l) - (Invalid_protocol_constants - "The epoch length must be between 1 and blocks_per_cycle, and \ - blocks_per_epoch must divide blocks_per_cycle.") - >>? fun () -> - error_unless - Compare.Int.(constants.dal.attestation_lag > 1) - (Invalid_protocol_constants - "The attestation_lag must be strictly greater than 1, because only slot \ - headers in finalized blocks are attested.") - >>? fun () -> - error_unless - Compare.Int.( - constants.sc_rollup.max_number_of_stored_cemented_commitments > 0) - (Invalid_protocol_constants - "The number of maximum stored cemented commitments must be strictly \ - positive") - >>? fun () -> Result.return_unit + let* () = + error_unless + Compare.Int.(constants.limit_of_delegation_over_baking >= 0) + (Invalid_protocol_constants + "The delegation over baking limit must be greater than or equal to 0.") + in + let* () = + error_unless + Compare.Int.( + constants.percentage_of_frozen_deposits_slashed_per_double_baking >= 0 + && constants.percentage_of_frozen_deposits_slashed_per_double_baking + <= 100) + (Invalid_protocol_constants + "The percentage of frozen deposits slashed per double baking must be \ + between 0 and 100 included.") + in + let* () = + error_unless + Compare.Int.( + constants.percentage_of_frozen_deposits_slashed_per_double_attestation + >= 0 + && constants + .percentage_of_frozen_deposits_slashed_per_double_attestation + <= 100) + (Invalid_protocol_constants + "The percentage of frozen deposits slashed per double attestation \ + must be between 0 and 100 included.") + in + let* () = + error_unless + (let snapshot_frequence = + Int32.div + constants.blocks_per_cycle + constants.blocks_per_stake_snapshot + in + Compare.Int32.( + snapshot_frequence > Int32.zero + && snapshot_frequence < Int32.of_int (1 lsl 16))) + (Invalid_protocol_constants + "The ratio blocks_per_cycle per blocks_per_stake_snapshot should be \ + between 1 and 65535") + in + let* () = + error_unless + Compare.Int32.( + constants.nonce_revelation_threshold > Int32.zero + && constants.nonce_revelation_threshold < constants.blocks_per_cycle) + (Invalid_protocol_constants + "The nonce revelation threshold must be strictly smaller than \ + blocks_per_cycle and strictly positive.") + in + let* () = + error_unless + Compare.Int64.( + let threshold = Int64.of_int32 constants.nonce_revelation_threshold in + let block = Period_repr.to_seconds constants.minimal_block_delay in + let ips = + (* We reduce the ips for short blocks_per_commitment so that we have + low difficulty during tests *) + if Compare.Int32.(constants.blocks_per_commitment > 32l) then + Int64.of_int 200_000 + else Int64.one + in + let factor = Int64.of_int 5 in + let difficulty = Int64.(mul (mul ips factor) (mul threshold block)) in + constants.vdf_difficulty > difficulty) + (Invalid_protocol_constants + "The VDF difficulty must be strictly greater than the product of the \ + nonce_revelation_threshold, the minimial_block_delay, a benchmark of \ + modulo squaring in class groups and a security threshold.") + in + let* () = + error_unless + Compare.Int.(constants.sc_rollup.origination_size >= 0) + (Invalid_protocol_constants + "The smart rollup origination size must be non-negative.") + in + let* () = + error_unless + Compare.Int.(constants.sc_rollup.challenge_window_in_blocks >= 0) + (Invalid_protocol_constants + "The smart rollup challenge window in blocks must be non-negative.") + in + let* () = + error_unless + Tez_repr.(constants.sc_rollup.stake_amount >= zero) + (Invalid_protocol_constants + "The smart rollup max stake amount must be non-negative.") + in + let* () = + error_unless + Compare.Int.(constants.sc_rollup.commitment_period_in_blocks > 0) + (Invalid_protocol_constants + "The smart rollup commitment period in blocks must be strictly \ + greater than 0.") + in + let* () = + error_unless + (let sc_rollup_max_lookahead_in_blocks = + constants.sc_rollup.max_lookahead_in_blocks + in + Compare.Int32.( + sc_rollup_max_lookahead_in_blocks + > Int32.of_int constants.sc_rollup.commitment_period_in_blocks + && (* Check that [smart_rollup_challenge_window_in_blocks < + smart_rollup_max_lookahead_in_blocks]. Otherwise committers would be + forced to commit at an artificially slow rate, affecting the + throughput of the rollup. *) + sc_rollup_max_lookahead_in_blocks + > Int32.of_int constants.sc_rollup.challenge_window_in_blocks)) + (Invalid_protocol_constants + "The smart rollup max lookahead in blocks must be greater than \ + [smart_rollup_commitment_period_in_blocks] and \ + [smart_rollup_challenge_window_in_blocks].") + in + let* () = + error_unless + Compare.Int.( + constants.dal.number_of_slots > 0 + && constants.dal.number_of_slots <= 256) + (Invalid_protocol_constants + "The number of data availability slot must be between 1 and 256") + in + let* () = + error_unless + Compare.Int32.( + constants.dal.blocks_per_epoch > 0l + && constants.dal.blocks_per_epoch <= constants.blocks_per_cycle + && Int32.rem constants.blocks_per_cycle constants.dal.blocks_per_epoch + = 0l) + (Invalid_protocol_constants + "The epoch length must be between 1 and blocks_per_cycle, and \ + blocks_per_epoch must divide blocks_per_cycle.") + in + let* () = + error_unless + Compare.Int.(constants.dal.attestation_lag > 1) + (Invalid_protocol_constants + "The attestation_lag must be strictly greater than 1, because only \ + slot headers in finalized blocks are attested.") + in + let* () = + error_unless + Compare.Int.( + constants.sc_rollup.max_number_of_stored_cemented_commitments > 0) + (Invalid_protocol_constants + "The number of maximum stored cemented commitments must be strictly \ + positive") + in + Result.return_unit module Generated = struct type t = { diff --git a/src/proto_alpha/lib_protocol/destination_repr.ml b/src/proto_alpha/lib_protocol/destination_repr.ml index eb40182cce862ab9797575adc0e8203ef863d3d0..b2e2a865a1cc78431064d6bcd7410350d904b058 100644 --- a/src/proto_alpha/lib_protocol/destination_repr.ml +++ b/src/proto_alpha/lib_protocol/destination_repr.ml @@ -89,9 +89,10 @@ let of_b58data data = let of_b58check_opt s = Option.bind (Base58.decode s) of_b58data let of_b58check s = + let open Result_syntax in match of_b58check_opt s with - | None -> error (Invalid_destination_b58check s) - | Some dest -> Ok dest + | None -> tzfail (Invalid_destination_b58check s) + | Some dest -> return dest let encoding = let open Data_encoding in diff --git a/src/proto_alpha/lib_protocol/entrypoint_repr.ml b/src/proto_alpha/lib_protocol/entrypoint_repr.ml index f005430e6b2ac13c2714c73202527aa079970eba..29fc395bb252e4ebdde9fa5702f96bd724bf47d9 100644 --- a/src/proto_alpha/lib_protocol/entrypoint_repr.ml +++ b/src/proto_alpha/lib_protocol/entrypoint_repr.ml @@ -101,9 +101,10 @@ let of_string str = | Some str -> of_non_empty_string str let of_string_strict ~loc str = + let open Result_syntax in match of_string str with - | Too_long -> error (Name_too_long str) - | Got_default -> error (Unexpected_default loc) + | Too_long -> tzfail (Name_too_long str) + | Got_default -> tzfail (Unexpected_default loc) | Ok name -> Ok name let of_string_strict' str = @@ -116,9 +117,10 @@ let of_string_strict_exn str = match of_string_strict' str with Ok v -> v | Error err -> invalid_arg err let of_annot_strict ~loc a = + let open Result_syntax in match of_non_empty_string a with - | Too_long -> error (Name_too_long (a :> string)) - | Got_default -> error (Unexpected_default loc) + | Too_long -> tzfail (Name_too_long (a :> string)) + | Got_default -> tzfail (Unexpected_default loc) | Ok name -> Ok name let of_annot_lax_opt a = @@ -135,12 +137,12 @@ let of_string_lax_opt str = let of_string_lax str = match of_string_lax_opt str with - | None -> error (Name_too_long str) + | None -> Result_syntax.tzfail (Name_too_long str) | Some name -> Ok name let of_annot_lax a = match of_non_empty_string a with - | Too_long -> error (Name_too_long (a :> string)) + | Too_long -> Result_syntax.tzfail (Name_too_long (a :> string)) | Got_default -> Ok default | Ok name -> Ok name diff --git a/src/proto_alpha/lib_protocol/fitness_repr.ml b/src/proto_alpha/lib_protocol/fitness_repr.ml index 8600d416499cec6b948988178ab7e0f8979e0b62..892e9c102d471d3cb43229a5402991f5eda17052 100644 --- a/src/proto_alpha/lib_protocol/fitness_repr.ml +++ b/src/proto_alpha/lib_protocol/fitness_repr.ml @@ -33,6 +33,7 @@ type t = { let encoding = let open Data_encoding in + let open Result_syntax in def "fitness" (conv_with_guard @@ -40,11 +41,11 @@ let encoding = (level, locked_round, predecessor_round, round)) (fun (level, locked_round, predecessor_round, round) -> match locked_round with - | None -> ok {level; locked_round; predecessor_round; round} + | None -> return {level; locked_round; predecessor_round; round} | Some locked_round_val -> if Round_repr.(round <= locked_round_val) then Error "Locked round must be smaller than round." - else ok {level; locked_round; predecessor_round; round}) + else return {level; locked_round; predecessor_round; round}) (obj4 (req "level" Raw_level_repr.encoding) (req "locked_round" (option Round_repr.encoding)) @@ -141,14 +142,17 @@ let create_without_locked_round ~level ~predecessor_round ~round = {level; locked_round = None; predecessor_round; round} let create ~level ~locked_round ~predecessor_round ~round = + let open Result_syntax in match locked_round with - | None -> ok {level; locked_round; predecessor_round; round} + | None -> return {level; locked_round; predecessor_round; round} | Some locked_round_val -> - error_when - Round_repr.(round <= locked_round_val) - (Locked_round_not_less_than_round - {round; locked_round = locked_round_val}) - >>? fun () -> ok {level; locked_round; predecessor_round; round} + let* () = + error_when + Round_repr.(round <= locked_round_val) + (Locked_round_not_less_than_round + {round; locked_round = locked_round_val}) + in + return {level; locked_round; predecessor_round; round} let int32_to_bytes i = let b = Bytes.make 4 '\000' in @@ -156,8 +160,9 @@ let int32_to_bytes i = b let int32_of_bytes b = - if Compare.Int.(Bytes.length b <> 4) then error Invalid_fitness - else ok (TzEndian.get_int32 b 0) + let open Result_syntax in + if Compare.Int.(Bytes.length b <> 4) then tzfail Invalid_fitness + else return (TzEndian.get_int32 b 0) (* Locked round is an option. And we want None to be smaller than any other value. The way the shell handles the order makes the empty Bytes smaller @@ -167,16 +172,23 @@ let locked_round_to_bytes = function | Some locked_round -> int32_to_bytes (Round_repr.to_int32 locked_round) let locked_round_of_bytes b = + let open Result_syntax in match Bytes.length b with - | 0 -> ok None - | 4 -> Round_repr.of_int32 (TzEndian.get_int32 b 0) >>? fun r -> ok (Some r) - | _ -> error Invalid_fitness + | 0 -> return_none + | 4 -> + let* r = Round_repr.of_int32 (TzEndian.get_int32 b 0) in + return_some r + | _ -> tzfail Invalid_fitness let predecessor_round_of_bytes neg_predecessor_round = - int32_of_bytes neg_predecessor_round >>? fun neg_predecessor_round -> + let open Result_syntax in + let* neg_predecessor_round = int32_of_bytes neg_predecessor_round in Round_repr.of_int32 @@ Int32.pred (Int32.neg neg_predecessor_round) -let round_of_bytes round = int32_of_bytes round >>? Round_repr.of_int32 +let round_of_bytes round = + let open Result_syntax in + let* value = int32_of_bytes round in + Round_repr.of_int32 value let to_raw {level; locked_round; predecessor_round; round} = [ @@ -188,24 +200,32 @@ let to_raw {level; locked_round; predecessor_round; round} = int32_to_bytes (Round_repr.to_int32 round); ] -let from_raw = function +let from_raw = + let open Result_syntax in + function | [version; level; locked_round; neg_predecessor_round; round] when Compare.String.( Bytes.to_string version = Constants_repr.fitness_version_number) -> - int32_of_bytes level >>? Raw_level_repr.of_int32 >>? fun level -> - locked_round_of_bytes locked_round >>? fun locked_round -> - predecessor_round_of_bytes neg_predecessor_round - >>? fun predecessor_round -> - round_of_bytes round >>? fun round -> + let* level = + let* value = int32_of_bytes level in + Raw_level_repr.of_int32 value + in + let* locked_round = locked_round_of_bytes locked_round in + let* predecessor_round = + predecessor_round_of_bytes neg_predecessor_round + in + let* round = round_of_bytes round in create ~level ~locked_round ~predecessor_round ~round | [version; _] when Compare.String.( Bytes.to_string version < Constants_repr.fitness_version_number) -> - error Outdated_fitness - | [] (* genesis fitness *) -> error Outdated_fitness - | _ -> error Invalid_fitness + tzfail Outdated_fitness + | [] (* genesis fitness *) -> tzfail Outdated_fitness + | _ -> tzfail Invalid_fitness -let round_from_raw = function +let round_from_raw = + let open Result_syntax in + function | [version; _level; _locked_round; _neg_predecessor_round; round] when Compare.String.( Bytes.to_string version = Constants_repr.fitness_version_number) -> @@ -213,11 +233,13 @@ let round_from_raw = function | [version; _] when Compare.String.( Bytes.to_string version < Constants_repr.fitness_version_number) -> - ok Round_repr.zero - | [] (* genesis fitness *) -> ok Round_repr.zero - | _ -> error Invalid_fitness + return Round_repr.zero + | [] (* genesis fitness *) -> return Round_repr.zero + | _ -> tzfail Invalid_fitness -let predecessor_round_from_raw = function +let predecessor_round_from_raw = + let open Result_syntax in + function | [version; _level; _locked_round; neg_predecessor_round; _round] when Compare.String.( Bytes.to_string version = Constants_repr.fitness_version_number) -> @@ -225,11 +247,13 @@ let predecessor_round_from_raw = function | [version; _] when Compare.String.( Bytes.to_string version < Constants_repr.fitness_version_number) -> - ok Round_repr.zero - | [] (* genesis fitness *) -> ok Round_repr.zero - | _ -> error Invalid_fitness + return Round_repr.zero + | [] (* genesis fitness *) -> return Round_repr.zero + | _ -> tzfail Invalid_fitness -let locked_round_from_raw = function +let locked_round_from_raw = + let open Result_syntax in + function | [version; _level; locked_round; _neg_predecessor_round; _round] when Compare.String.( Bytes.to_string version = Constants_repr.fitness_version_number) -> @@ -237,9 +261,9 @@ let locked_round_from_raw = function | [version; _] when Compare.String.( Bytes.to_string version < Constants_repr.fitness_version_number) -> - ok None - | [] (* former genesis fitness *) -> ok None - | _ -> error Invalid_fitness + return_none + | [] (* former genesis fitness *) -> return_none + | _ -> tzfail Invalid_fitness let check_except_locked_round fitness ~level ~predecessor_round = let { diff --git a/src/proto_alpha/lib_protocol/level_repr.ml b/src/proto_alpha/lib_protocol/level_repr.ml index f4cb006b83177b6e8107f31e027f50cbe711b51c..f3daac4d0d5ec87649d484fab32c89e0ff2efbac 100644 --- a/src/proto_alpha/lib_protocol/level_repr.ml +++ b/src/proto_alpha/lib_protocol/level_repr.ml @@ -127,8 +127,9 @@ let () = (fun () -> Invalid_cycle_eras) let create_cycle_eras cycle_eras = + let open Result_syntax in match cycle_eras with - | [] -> error Invalid_cycle_eras + | [] -> tzfail Invalid_cycle_eras | newest_era :: older_eras -> let rec aux {first_level; first_cycle; _} older_eras = match older_eras with @@ -142,10 +143,11 @@ let create_cycle_eras cycle_eras = Raw_level_repr.(first_level > first_level_of_previous_era) && Cycle_repr.(first_cycle > first_cycle_of_previous_era) then aux previous_era even_older_eras - else error Invalid_cycle_eras - | [] -> ok () + else tzfail Invalid_cycle_eras + | [] -> return_unit in - aux newest_era older_eras >>? fun () -> ok cycle_eras + let* () = aux newest_era older_eras in + return cycle_eras let add_cycle_era new_era cycle_eras = create_cycle_eras (new_era :: cycle_eras) @@ -278,15 +280,17 @@ let () = (fun level -> Level_not_in_alpha level) let level_from_raw_aux ~cycle_eras level = + let open Result_syntax in let first_level_in_alpha_family = match List.rev cycle_eras with | [] -> assert false | {first_level; _} :: _ -> first_level in - error_when - Raw_level_repr.(level < first_level_in_alpha_family) - (Level_not_in_alpha level) - >|? fun () -> + let+ () = + error_when + Raw_level_repr.(level < first_level_in_alpha_family) + (Level_not_in_alpha level) + in let era = era_of_level ~cycle_eras level in level_from_raw_with_era era ~first_level_in_alpha_family level @@ -315,7 +319,7 @@ let level_from_raw_with_offset ~cycle_eras ~offset raw_level = match res with | Ok level -> level_from_raw_aux ~cycle_eras level | Error _ -> - error + Result_syntax.tzfail (Negative_level_and_offset_sum (Raw_level_repr.to_int32 raw_level, offset)) diff --git a/src/proto_alpha/lib_protocol/operation_repr.ml b/src/proto_alpha/lib_protocol/operation_repr.ml index fbd6060eaf52b352cab1701286a6e1c184dbe18b..366918d0d8e9b06cc2d64508fe95b48acbb5769c 100644 --- a/src/proto_alpha/lib_protocol/operation_repr.ml +++ b/src/proto_alpha/lib_protocol/operation_repr.ml @@ -476,7 +476,7 @@ type error += Contents_list_error of string (* `Permanent *) let of_list l = match of_list_internal l with | Ok contents -> Ok contents - | Error s -> error @@ Contents_list_error s + | Error s -> Result_syntax.tzfail @@ Contents_list_error s let tx_rollup_operation_tag_offset = 150 @@ -1679,6 +1679,7 @@ module Encoding = struct (packed_contents, prefix) let protocol_data_binary_encoding = + let open Result_syntax in conv_with_guard (fun (Operation_data {contents; signature}) -> let contents_list = @@ -1699,7 +1700,6 @@ module Encoding = struct in (contents_and_signature_prefix, sig_suffix)) (fun (contents_and_signature_prefix, suffix) -> - let open Result_syntax in let* Contents_list contents, prefix = of_contents_and_signature_prefix contents_and_signature_prefix in @@ -1929,13 +1929,15 @@ let unsigned_operation_length (type kind) (shell, Contents_list protocol_data.contents) let check_signature (type kind) key chain_id (op : kind operation) = + let open Result_syntax in let serialized_operation = serialize_unsigned_operation op in let check ~watermark signature = - if Signature.check ~watermark key signature serialized_operation then Ok () - else error Invalid_signature + if Signature.check ~watermark key signature serialized_operation then + return_unit + else tzfail Invalid_signature in match op.protocol_data.signature with - | None -> error Missing_signature + | None -> tzfail Missing_signature | Some signature -> let watermark = match op.protocol_data.contents with diff --git a/src/proto_alpha/lib_protocol/period_repr.ml b/src/proto_alpha/lib_protocol/period_repr.ml index 1f2de5752be8f7b2b1b8a571fff948620bbfec7b..d777907559ac74b96f1ddeab422e8221cd73ae05 100644 --- a/src/proto_alpha/lib_protocol/period_repr.ml +++ b/src/proto_alpha/lib_protocol/period_repr.ml @@ -93,7 +93,7 @@ module Internal : INTERNAL = struct Data_encoding.( with_decoding_guard (fun t -> - if Compare.Int64.(t >= 0L) then Ok () + if Compare.Int64.(t >= 0L) then Result_syntax.return_unit else Error "Positive int64 required") int64) @@ -133,9 +133,10 @@ type period = Internal.t let to_seconds (t : Internal.t) = (t :> int64) let of_seconds secs = + let open Result_syntax in match Internal.create secs with - | Some v -> ok v - | None -> error (Malformed_period secs) + | Some v -> return v + | None -> tzfail (Malformed_period secs) let of_seconds_exn t = match Internal.create t with @@ -143,17 +144,19 @@ let of_seconds_exn t = | None -> invalid_arg "Period.of_seconds_exn" let mult i p = + let open Result_syntax in match Internal.create (Int64.of_int32 i) with - | None -> error Invalid_arg + | None -> tzfail Invalid_arg | Some iper -> ( match Internal.mult_ iper p with - | None -> error Period_overflow - | Some res -> ok res) + | None -> tzfail Period_overflow + | Some res -> return res) let add p1 p2 = + let open Result_syntax in match Internal.add_ p1 p2 with - | None -> error Period_overflow - | Some res -> ok res + | None -> tzfail Period_overflow + | Some res -> return res let ( +? ) = add diff --git a/src/proto_alpha/lib_protocol/ratio_repr.ml b/src/proto_alpha/lib_protocol/ratio_repr.ml index 463ab0667f228de93630986d303f25b36fbceea4..cabd42bacbde928a8ddee497d7a873b9ed7997c5 100644 --- a/src/proto_alpha/lib_protocol/ratio_repr.ml +++ b/src/proto_alpha/lib_protocol/ratio_repr.ml @@ -30,7 +30,7 @@ let encoding = conv_with_guard (fun r -> (r.numerator, r.denominator)) (fun (numerator, denominator) -> - if Compare.Int.(denominator > 0) then ok {numerator; denominator} + if Compare.Int.(denominator > 0) then Ok {numerator; denominator} else Error "The denominator must be greater than 0.") (obj2 (req "numerator" uint16) (req "denominator" uint16)) diff --git a/src/proto_alpha/lib_protocol/raw_level_repr.ml b/src/proto_alpha/lib_protocol/raw_level_repr.ml index a585672ab3ed6d98fe8db63db2b70db62725929e..d83e08738c4d56ab684c6c7c83e4f2e909b6edbe 100644 --- a/src/proto_alpha/lib_protocol/raw_level_repr.ml +++ b/src/proto_alpha/lib_protocol/raw_level_repr.ml @@ -90,7 +90,8 @@ let () = (fun l -> Unexpected_level l) let of_int32 l = - if Compare.Int32.(l >= 0l) then ok l else error (Unexpected_level l) + let open Result_syntax in + if Compare.Int32.(l >= 0l) then return l else tzfail (Unexpected_level l) let of_int32_exn l = match of_int32 l with diff --git a/src/proto_alpha/lib_protocol/receipt_repr.ml b/src/proto_alpha/lib_protocol/receipt_repr.ml index 640b9dbdc956fef5e007b30fa214cdafdf8ce053..e0a42a4f09cfe0bd78eedd4bb7b4479971796a56 100644 --- a/src/proto_alpha/lib_protocol/receipt_repr.ml +++ b/src/proto_alpha/lib_protocol/receipt_repr.ml @@ -438,40 +438,44 @@ module BalanceMap = struct end) let update_r key (f : 'a option -> 'b option tzresult) map = - f (find key map) >>? function - | Some v -> ok (add key v map) - | None -> ok (remove key map) + let open Result_syntax in + let* v_opt = f (find key map) in + match v_opt with + | Some v -> return (add key v map) + | None -> return (remove key map) end let group_balance_updates balance_updates = - List.fold_left_e - (fun acc (b, update, o) -> - (* Do not do anything if the update is zero *) - if is_zero_update update then ok acc - else - BalanceMap.update_r - (b, o) - (function - | None -> ok (Some update) - | Some balance -> ( - match (balance, update) with - | Credited a, Debited b | Debited b, Credited a -> - (* Remove the binding since it just fell down to zero *) - if Tez_repr.(a = b) then ok None - else if Tez_repr.(a > b) then - Tez_repr.(a -? b) >>? fun update -> - ok (Some (Credited update)) - else - Tez_repr.(b -? a) >>? fun update -> - ok (Some (Debited update)) - | Credited a, Credited b -> - Tez_repr.(a +? b) >>? fun update -> - ok (Some (Credited update)) - | Debited a, Debited b -> - Tez_repr.(a +? b) >>? fun update -> - ok (Some (Debited update)))) - acc) - BalanceMap.empty - balance_updates - >>? fun map -> - ok (BalanceMap.fold (fun (b, o) u acc -> (b, u, o) :: acc) map []) + let open Result_syntax in + let* map = + List.fold_left_e + (fun acc (b, update, o) -> + (* Do not do anything if the update is zero *) + if is_zero_update update then return acc + else + BalanceMap.update_r + (b, o) + (function + | None -> return_some update + | Some balance -> ( + match (balance, update) with + | Credited a, Debited b | Debited b, Credited a -> + (* Remove the binding since it just fell down to zero *) + if Tez_repr.(a = b) then return_none + else if Tez_repr.(a > b) then + let* update = Tez_repr.(a -? b) in + return_some (Credited update) + else + let* update = Tez_repr.(b -? a) in + return_some (Debited update) + | Credited a, Credited b -> + let* update = Tez_repr.(a +? b) in + return_some (Credited update) + | Debited a, Debited b -> + let* update = Tez_repr.(a +? b) in + return_some (Debited update))) + acc) + BalanceMap.empty + balance_updates + in + return (BalanceMap.fold (fun (b, o) u acc -> (b, u, o) :: acc) map []) diff --git a/src/proto_alpha/lib_protocol/round_repr.ml b/src/proto_alpha/lib_protocol/round_repr.ml index 4f8c5c7b20eec2f0e55ad77ac757c9848a27e19b..2fb0de39c21dd032fa681cf9bca4c1ed55a2ba65 100644 --- a/src/proto_alpha/lib_protocol/round_repr.ml +++ b/src/proto_alpha/lib_protocol/round_repr.ml @@ -76,7 +76,8 @@ let () = (fun i -> Round_overflow (Int64.to_int i)) let of_int32 i = - if i >= 0l then Ok i else error (Negative_round (Int32.to_int i)) + let open Result_syntax in + if i >= 0l then return i else tzfail (Negative_round (Int32.to_int i)) [@@inline] let pred r = @@ -84,21 +85,24 @@ let pred r = of_int32 p let of_int i = - if Compare.Int.(i < 0) then error (Negative_round i) + let open Result_syntax in + if Compare.Int.(i < 0) then tzfail (Negative_round i) else (* i is positive *) let i32 = Int32.of_int i in if Compare.Int.(Int32.to_int i32 = i) then Ok i32 - else error (Round_overflow i) + else tzfail (Round_overflow i) let to_int i32 = + let open Result_syntax in let i = Int32.to_int i32 in - if Int32.(equal (of_int i) i32) then ok i else error (Round_overflow i) + if Int32.(equal (of_int i) i32) then return i else tzfail (Round_overflow i) let to_int32 t = t [@@inline] let to_slot round ~committee_size = - to_int round >>? fun r -> + let open Result_syntax in + let* r = to_int round in let slot = r mod committee_size in Slot_repr.of_int slot @@ -148,15 +152,19 @@ module Durations = struct t.delay_increment_per_round let create ~first_round_duration ~delay_increment_per_round = - error_when - Compare.Int64.(Period_repr.to_seconds first_round_duration < 1L) - (Round_durations_must_be_at_least_one_second - {round = first_round_duration}) - >>? fun () -> - error_when - Compare.Int64.(Period_repr.to_seconds delay_increment_per_round < 1L) - (Non_increasing_rounds {increment = delay_increment_per_round}) - >>? fun () -> ok {first_round_duration; delay_increment_per_round} + let open Result_syntax in + let* () = + error_when + Compare.Int64.(Period_repr.to_seconds first_round_duration < 1L) + (Round_durations_must_be_at_least_one_second + {round = first_round_duration}) + in + let* () = + error_when + Compare.Int64.(Period_repr.to_seconds delay_increment_per_round < 1L) + (Non_increasing_rounds {increment = delay_increment_per_round}) + in + return {first_round_duration; delay_increment_per_round} let create_opt ~first_round_duration ~delay_increment_per_round = match create ~first_round_duration ~delay_increment_per_round with @@ -236,7 +244,8 @@ let () = + 1/2 * r * (r - 1) * delay_increment_per_round *) let raw_level_offset_of_round round_durations ~round = - if Compare.Int32.(round = zero) then ok Int64.zero + let open Result_syntax in + if Compare.Int32.(round = zero) then return Int64.zero else let sum_durations = let Durations.{first_round_duration; delay_increment_per_round} = @@ -254,8 +263,8 @@ let raw_level_offset_of_round round_durations ~round = (Z.of_int64 @@ Period_repr.to_seconds first_round_duration))) in if Compare.Z.(sum_durations > Z.of_int64 Int64.max_int) then - error (Round_too_high round) - else ok (Z.to_int64 sum_durations) + tzfail (Round_too_high round) + else return (Z.to_int64 sum_durations) type error += Level_offset_too_high of Period_repr.t @@ -280,6 +289,7 @@ type round_and_offset = {round : int32; offset : Period_repr.t} (** Complexity: O(log level_offset). *) let round_and_offset round_durations ~level_offset = + let open Result_syntax in let level_offset_in_seconds = Period_repr.to_seconds level_offset in (* We set the bound as 2^53 to prevent overflows when computing the variable [discr] for reasonable values of [first_round_duration] and @@ -287,7 +297,7 @@ let round_and_offset round_durations ~level_offset = from the inequation [discr] < Int64.max_int. *) let overflow_bound = Int64.shift_right Int64.max_int 10 in if Compare.Int64.(overflow_bound < level_offset_in_seconds) then - error (Level_offset_too_high level_offset) + tzfail (Level_offset_too_high level_offset) else let Durations.{first_round_duration; delay_increment_per_round} = round_durations @@ -299,7 +309,7 @@ let round_and_offset round_durations ~level_offset = (* If [level_offset] is lower than the first round duration, then the solution straightforward. *) if Compare.Int64.(level_offset_in_seconds < first_round_duration) then - ok {round = 0l; offset = level_offset} + return {round = 0l; offset = level_offset} else let round = if Compare.Int64.(delay_increment_per_round = Int64.zero) then @@ -363,9 +373,10 @@ let round_and_offset round_durations ~level_offset = (sqrt discr)) (double delay_increment_per_round) in - raw_level_offset_of_round round_durations ~round:(Int64.to_int32 round) - >>? fun current_level_offset -> - ok + let* current_level_offset = + raw_level_offset_of_round round_durations ~round:(Int64.to_int32 round) + in + return { round = Int64.to_int32 round; offset = @@ -378,6 +389,7 @@ let round_and_offset round_durations ~level_offset = (** Complexity: O(|round_durations|). *) let timestamp_of_round round_durations ~predecessor_timestamp ~predecessor_round ~round = + let open Result_syntax in let pred_round_duration = Durations.round_duration round_durations predecessor_round in @@ -385,11 +397,12 @@ let timestamp_of_round round_durations ~predecessor_timestamp ~predecessor_round to start. This is given by adding to the timestamp of the round of predecessor level l-1 [predecessor_timestamp], the duration of its last round [predecessor_round]. *) - Time_repr.(predecessor_timestamp +? pred_round_duration) - >>? fun start_of_current_level -> + let* start_of_current_level = + Time_repr.(predecessor_timestamp +? pred_round_duration) + in (* Finally, we sum the durations of the rounds at the current level l until reaching current [round]. *) - raw_level_offset_of_round round_durations ~round >>? fun level_offset -> + let* level_offset = raw_level_offset_of_round round_durations ~round in let level_offset = Period_repr.of_seconds_exn level_offset in Time_repr.(start_of_current_level +? level_offset) @@ -404,11 +417,14 @@ let timestamp_of_round round_durations ~predecessor_timestamp ~predecessor_round Complexity: O(|round_durations|). *) let timestamp_of_another_round_same_level round_durations ~current_timestamp ~current_round ~considered_round = - raw_level_offset_of_round round_durations ~round:considered_round - >>? fun target_offset -> - raw_level_offset_of_round round_durations ~round:current_round - >>? fun current_offset -> - ok + let open Result_syntax in + let* target_offset = + raw_level_offset_of_round round_durations ~round:considered_round + in + let* current_offset = + raw_level_offset_of_round round_durations ~round:current_round + in + return @@ Time_repr.of_seconds Int64.( add @@ -455,31 +471,36 @@ let () = let round_of_timestamp round_durations ~predecessor_timestamp ~predecessor_round ~timestamp = + let open Result_syntax in let round_duration = Durations.round_duration round_durations predecessor_round in - Time_repr.(predecessor_timestamp +? round_duration) - >>? fun start_of_current_level -> - Period_repr.of_seconds (Time_repr.diff timestamp start_of_current_level) - |> Error_monad.record_trace - (Round_of_past_timestamp - { - predecessor_timestamp; - provided_timestamp = timestamp; - predecessor_round; - }) - >>? fun diff -> - round_and_offset round_durations ~level_offset:diff - >>? fun round_and_offset -> ok round_and_offset.round + let* start_of_current_level = + Time_repr.(predecessor_timestamp +? round_duration) + in + let* diff = + Period_repr.of_seconds (Time_repr.diff timestamp start_of_current_level) + |> Error_monad.record_trace + (Round_of_past_timestamp + { + predecessor_timestamp; + provided_timestamp = timestamp; + predecessor_round; + }) + in + let* round_and_offset = round_and_offset round_durations ~level_offset:diff in + return round_and_offset.round let level_offset_of_round round_durations ~round = - raw_level_offset_of_round round_durations ~round >>? fun offset -> - ok (Period_repr.of_seconds_exn offset) + let open Result_syntax in + let* offset = raw_level_offset_of_round round_durations ~round in + return (Period_repr.of_seconds_exn offset) module Internals_for_test = struct type round_and_offset_raw = {round : round; offset : Period_repr.t} let round_and_offset round_durations ~level_offset = - round_and_offset round_durations ~level_offset >|? fun v -> + let open Result_syntax in + let+ v = round_and_offset round_durations ~level_offset in {round = v.round; offset = v.offset} end diff --git a/src/proto_alpha/lib_protocol/slot_repr.ml b/src/proto_alpha/lib_protocol/slot_repr.ml index 9e72811663ce30729583ad2ee874e0c9d0e17e7c..a8e9193120a60670a2ba3a43d7f546ad3fac09ec 100644 --- a/src/proto_alpha/lib_protocol/slot_repr.ml +++ b/src/proto_alpha/lib_protocol/slot_repr.ml @@ -61,7 +61,9 @@ let max_value = (1 lsl 16) - 1 let of_int_do_not_use_except_for_parameters i = i let of_int i = - if Compare.Int.(i < 0 || i > max_value) then error (Invalid_slot i) else ok i + let open Result_syntax in + if Compare.Int.(i < 0 || i > max_value) then tzfail (Invalid_slot i) + else return i let succ slot = of_int (slot + 1) @@ -75,13 +77,14 @@ module Range = struct type t = Interval of {lo : int; hi : int} let create ~min ~count = - error_when (min < 0) (Invalid_slot min) >>? fun () -> - error_when (min > max_value) (Invalid_slot min) >>? fun () -> - error_when (count < 1) (Invalid_slot count) >>? fun () -> - error_when (count > max_value) (Invalid_slot count) >>? fun () -> + let open Result_syntax in + let* () = error_when (min < 0) (Invalid_slot min) in + let* () = error_when (min > max_value) (Invalid_slot min) in + let* () = error_when (count < 1) (Invalid_slot count) in + let* () = error_when (count > max_value) (Invalid_slot count) in let max = min + count - 1 in - error_when (max > max_value) (Invalid_slot max) >>? fun () -> - ok (Interval {lo = min; hi = max}) + let* () = error_when (max > max_value) (Invalid_slot max) in + return (Interval {lo = min; hi = max}) let fold f init (Interval {lo; hi}) = let rec loop ~acc ~next = @@ -91,18 +94,26 @@ module Range = struct loop ~acc:(f init lo) ~next:(lo + 1) let fold_es f init (Interval {lo; hi}) = + let open Lwt_result_syntax in let rec loop ~acc ~next = if Compare.Int.(next > hi) then return acc - else f acc next >>=? fun acc -> loop ~acc ~next:(next + 1) + else + let* acc = f acc next in + loop ~acc ~next:(next + 1) in - f init lo >>=? fun acc -> loop ~acc ~next:(lo + 1) + let* acc = f init lo in + loop ~acc ~next:(lo + 1) let rev_fold_es f init (Interval {lo; hi}) = + let open Lwt_result_syntax in let rec loop ~acc ~next = if Compare.Int.(next < lo) then return acc - else f acc next >>=? fun acc -> loop ~acc ~next:(next - 1) + else + let* acc = f acc next in + loop ~acc ~next:(next - 1) in - f init hi >>=? fun acc -> loop ~acc ~next:(hi - 1) + let* acc = f init hi in + loop ~acc ~next:(hi - 1) end module Internal_for_tests = struct diff --git a/src/proto_alpha/lib_protocol/tez_repr.ml b/src/proto_alpha/lib_protocol/tez_repr.ml index 16de8176f24c9b6a4657caa90f12b2f580c5892d..81ca1249dbe6e82e3dc80069f522f48654cc2637 100644 --- a/src/proto_alpha/lib_protocol/tez_repr.ml +++ b/src/proto_alpha/lib_protocol/tez_repr.ml @@ -121,32 +121,36 @@ let pp ppf (Tez_tag amount) = let to_string t = Format.asprintf "%a" pp t let ( -? ) tez1 tez2 = + let open Result_syntax in let (Tez_tag t1) = tez1 in let (Tez_tag t2) = tez2 in - if t2 <= t1 then ok (Tez_tag (Int64.sub t1 t2)) - else error (Subtraction_underflow (tez1, tez2)) + if t2 <= t1 then return (Tez_tag (Int64.sub t1 t2)) + else tzfail (Subtraction_underflow (tez1, tez2)) let sub_opt (Tez_tag t1) (Tez_tag t2) = if t2 <= t1 then Some (Tez_tag (Int64.sub t1 t2)) else None let ( +? ) tez1 tez2 = + let open Result_syntax in let (Tez_tag t1) = tez1 in let (Tez_tag t2) = tez2 in let t = Int64.add t1 t2 in - if t < t1 then error (Addition_overflow (tez1, tez2)) else ok (Tez_tag t) + if t < t1 then tzfail (Addition_overflow (tez1, tez2)) else return (Tez_tag t) let ( *? ) tez m = + let open Result_syntax in let (Tez_tag t) = tez in - if m < 0L then error (Negative_multiplicator (tez, m)) - else if m = 0L then ok (Tez_tag 0L) + if m < 0L then tzfail (Negative_multiplicator (tez, m)) + else if m = 0L then return (Tez_tag 0L) else if t > Int64.(div max_int m) then - error (Multiplication_overflow (tez, m)) - else ok (Tez_tag (Int64.mul t m)) + tzfail (Multiplication_overflow (tez, m)) + else return (Tez_tag (Int64.mul t m)) let ( /? ) tez d = + let open Result_syntax in let (Tez_tag t) = tez in - if d <= 0L then error (Invalid_divisor (tez, d)) - else ok (Tez_tag (Int64.div t d)) + if d <= 0L then tzfail (Invalid_divisor (tez, d)) + else return (Tez_tag (Int64.div t d)) let div2_sub tez = let (Tez_tag t) = tez in @@ -168,14 +172,15 @@ let div_exn t d = | Error _ -> invalid_arg "div_exn" let mul_ratio tez ~num ~den = + let open Result_syntax in let (Tez_tag t) = tez in - if num < 0L then error (Negative_multiplicator (tez, num)) - else if den <= 0L then error (Invalid_divisor (tez, den)) - else if num = 0L then ok zero + if num < 0L then tzfail (Negative_multiplicator (tez, num)) + else if den <= 0L then tzfail (Invalid_divisor (tez, den)) + else if num = 0L then return zero else let z = Z.(div (mul (of_int64 t) (of_int64 num)) (of_int64 den)) in - if Z.fits_int64 z then ok (Tez_tag (Z.to_int64 z)) - else error (Multiplication_overflow (tez, num)) + if Z.fits_int64 z then return (Tez_tag (Z.to_int64 z)) + else tzfail (Multiplication_overflow (tez, num)) let of_mutez t = if t < 0L then None else Some (Tez_tag t) diff --git a/src/proto_alpha/lib_protocol/time_repr.ml b/src/proto_alpha/lib_protocol/time_repr.ml index d19897b7122e0a71997b8e04ddcd56fa4d4cfda9..724458095f2e3726a1a01c3da1e1fad65df507be 100644 --- a/src/proto_alpha/lib_protocol/time_repr.ml +++ b/src/proto_alpha/lib_protocol/time_repr.ml @@ -58,13 +58,14 @@ let to_seconds_string s = Int64.to_string (to_seconds s) let pp = pp_hum let ( +? ) x y = + let open Result_syntax in let span = Period_repr.to_seconds y in let t64 = Time.add x span in (* As long as span and time representations are int64, we cannont overflow if x is negative. *) - if x < Time.of_seconds 0L then ok t64 - else if t64 < Time.of_seconds 0L then error Timestamp_add - else ok t64 + if x < Time.of_seconds 0L then return t64 + else if t64 < Time.of_seconds 0L then tzfail Timestamp_add + else return t64 let ( -? ) x y = record_trace Timestamp_sub (Period_repr.of_seconds (Time.diff x y))