diff --git a/docs/alpha/proof_of_stake.rst b/docs/alpha/proof_of_stake.rst index 25883f5accae91efdd571ad5276e4f6a18cf879c..9dfa96aaf8df3a4271ed43e9c6604f2bd42a9d7b 100644 --- a/docs/alpha/proof_of_stake.rst +++ b/docs/alpha/proof_of_stake.rst @@ -262,8 +262,8 @@ Endorsements ~~~~~~~~~~~~ To each level, we associate a list of ``ENDORSERS_PER_BLOCK`` = -32 *endorsers*. Endorsers are drawn similarly as bakers, by randomly -selecting 32 active rolls with replacement. +256 *endorsers*. Endorsers are drawn similarly as bakers, by randomly +selecting 256 active rolls with replacement. Each endorser verifies the last block that was baked, say at the level ``n``, and emits an endorsement operation. The endorsement operations @@ -279,22 +279,34 @@ endorsement slots covered by the contained endorsement operations. (In the code base, the number of filled endorsement slots is called the block's endorsing power.) -Minimal block delays -~~~~~~~~~~~~~~~~~~~~ +Minimal block delay formula +~~~~~~~~~~~~~~~~~~~~~~~~~~~ -A block is valid only if its timestamp has a minimal delay with -respect to the previous block’s timestamp. The minimal delay is given -by the following expression: ``TIME_BETWEEN_BLOCKS[0] + -TIME_BETWEEN_BLOCKS[1] * p +`` ``DELAY_PER_MISSING_ENDORSEMENT * MAX -(0, INITIAL_ENDORSERS - e)`` where ``TIME_BETWEEN_BLOCKS[0]`` = 60 +A block is valid only if its timestamp has a minimal delay with respect to the +previous block’s timestamp. For a block with priority ``p`` and containing ``e`` +endorsements, the minimal delay is given by the following formula: + +``if p = 0 and e >= 3*ENDORSERS_PER_BLOCK/5`` +``then MINIMAL_BLOCK_DELAY`` +``else TIME_BETWEEN_BLOCKS[0] + TIME_BETWEEN_BLOCKS[1] * p`` +``+ DELAY_PER_MISSING_ENDORSEMENT * MAX +(0, INITIAL_ENDORSERS - e)`` + +where ``MINIMAL_BLOCK_DELAY`` = 30 seconds, ``TIME_BETWEEN_BLOCKS[0]`` = 60 seconds, ``TIME_BETWEEN_BLOCKS[1]`` = 40 seconds, -``DELAY_PER_MISSING_ENDORSEMENT`` = 8 seconds, ``INITIAL_ENDORSERS`` = -24, ``p`` is the block's priority at which the block was baked, and -``e`` is the number of endorsements the block contains. That is, the -higher the priority and the fewer endorsements a block carries the -longer it takes before it can be considered valid. However, if the -block contains more than ``INITIAL_ENDORSERS`` then there is no time -penalty. +``DELAY_PER_MISSING_ENDORSEMENT`` = 4 seconds, and ``INITIAL_ENDORSERS`` = +192. + +The formula says that: + +- if the block is baked at priority 0 and it contains at least 60% of + the endorsements (namely, at least 153 endorsements) then the + minimal delay is 30 seconds; +- otherwise, the higher the priority and the fewer endorsements a + block carries with respect to the 192 endorsements threshold, the + longer it takes before it can be considered valid, where the delay + of 60 seconds is incremented by 40 seconds with each missed priority + and with 4 seconds with each missed endorsement. Rewards ~~~~~~~ @@ -302,28 +314,28 @@ Rewards Baking a block gives a block reward of ``e * BAKING_REWARD_PER_ENDORSEMENT[p']`` plus all fees paid by the transactions contained in the block, where -``BAKING_REWARD_PER_ENDORSEMENT`` = ``[1.250ꜩ, 0.1875ꜩ]``, +``BAKING_REWARD_PER_ENDORSEMENT`` = ``[0.078125ꜩ, 0.011719ꜩ]``, ``e`` is the number of endorsements the block contains, ``p`` is the priority at which the block was baked, and ``p'`` is 0 if ``p`` is 0 and is 1 if ``p`` is bigger than 0. That is, a delegate -producing a block of priority 0 will be rewarded ``e * 1.25`` +producing a block of priority 0 will be rewarded ``e * 0.078125`` ꜩ. If a delegate produces a block at priority 1 or higher, then -the reward is ``e * 0.1875`` ꜩ. +the reward is ``e * 0.011719`` ꜩ. Endorsers also receive a reward (at the same time as block creators do). The reward is ``ENDORSEMENT_REWARD[p']``, where -``ENDORSEMENT_REWARD`` = ``[1.250ꜩ, 0.833333ꜩ]``, where ``p'`` +``ENDORSEMENT_REWARD`` = ``[0.078125ꜩ, 0.052083ꜩ]``, where ``p'`` is as above. That is, a delegate endorsing a block of priority 0 -will be rewarded ``e * 1.25`` ꜩ, with ``e`` the number of endorsement +will be rewarded ``e * 0.078125`` ꜩ, with ``e`` the number of endorsement slots attributed to the delegate for this level. Moreover, endorsing -blocks of priority 1 or higher will be rewarded ``e * 0.8333333`` +blocks of priority 1 or higher will be rewarded ``e * 0.052083`` ꜩ. Security deposits ~~~~~~~~~~~~~~~~~ -The cost of a security deposit is ``BLOCK_SECURITY_DEPOSIT`` = 512 ꜩ -per block created and ``ENDORSEMENT_SECURITY_DEPOSIT`` = 64 ꜩ per +The cost of a security deposit is ``BLOCK_SECURITY_DEPOSIT`` = 640 ꜩ +per block created and ``ENDORSEMENT_SECURITY_DEPOSIT`` = 2.5 ꜩ per endorsement slot. Each delegate key has an associated security deposit account. @@ -351,7 +363,7 @@ Inflation Inflation from block rewards and endorsement reward is at most ``ENDORSERS_PER_BLOCK`` \* (``ENDORSEMENT_REWARD[0]`` + ``BAKING_REWARD_PER_ENDORSEMENT[0]``) = -80 ꜩ. This means at most 5.51% annual inflation. +40 ꜩ. This means at most 5.51% annual inflation. Random seed ~~~~~~~~~~~ diff --git a/docs/protocols/alpha.rst b/docs/protocols/alpha.rst index 00a70fbb977cda78a130ed6f696e2f2fc1671f34..879bf3c0e51e8f1a3510ce4b052557ff54be7f5e 100644 --- a/docs/protocols/alpha.rst +++ b/docs/protocols/alpha.rst @@ -12,7 +12,51 @@ The code can be found in the ``src/proto_alpha`` directory of the This page documents the changes brought by protocol Alpha with respect to Florence. +The main novelties in the Alpha protocol are: + +- an upgrade of the consensus algorithm Emmy+ to Emmy*, which brings smaller block times and faster finality + +.. contents:: Here is the complete list of changes: + +Emmy* +----- + +Emmy* updates Emmy+ by: + +- a tweak in the definition of the minimal delay function, and +- an increase in the number of endorsement slots per block + +Concretely, in Emmy* a block can be produced with a delay of 30 seconds with respect to the previous block if it has priority 0 and more than 60% of the total endorsing power per block, which has been increased to ``256`` (from ``32``) endorsement slots per block. + +The baking and endorsing rewards are updated as follows: + +- The reward producing a block at priority 0 is updated from ``e * 1.25`` tez to ``e * 0.078125`` tez, and for producing a block at priority 1 or higher, is updated from ``e * 0.1875`` tez to ``e * 0.011719`` tez, where ``e`` is the endorsing power of the endorsements contained in the block. +- The reward for endorsing a block of priority 0 is updated from ``1.25`` tez to ``0.078125`` tez per endorsement slot, and for endorsing a block at priority 1 or higher is updated from ``0.833333`` tez to ``0.052083`` tez per endorsement slot. + +The values of the security deposits are updated from ``512`` tez to ``640`` tez for baking, and from ``64`` tez to ``2.5`` tez for endorsing. + +The constant ``hard_gas_limit_per_block`` is updated from ``10,400,000`` to ``5,200,000`` gas units. + +The Michelson `NOW` instruction keeps the same intuitive meaning, +namely it pushes the minimal injection time on the stack for the +current block. However, this minimal injection time is not 1 minute +after the previous block's timestamp as before, instead it is 30 +seconds after. + + + +Changelog +--------- .. contents:: Summary of changes - Fix handling of potential integer overflow in `Time_repr` addition `Protocol/time_repr: check for potential overflow on addition `_ + +- Emmy*, new block delay formula + partially solves issue: `tezos#1027 `__ + `tezos!2386 `__ + +RPC changes +~~~~~~~~~~~ + +The RPC ``..//required_endorsements`` has been removed. diff --git a/src/bin_sandbox/command_accusations.ml b/src/bin_sandbox/command_accusations.ml index 0acc10f4570b5ff0d37aabbdf46ce55d379a1fac..a55f66c13f0341a1ba07d5dbea40d9bcd28a8ef8 100644 --- a/src/bin_sandbox/command_accusations.ml +++ b/src/bin_sandbox/command_accusations.ml @@ -20,6 +20,7 @@ let little_mesh_with_bakers ?base_port ?generate_kiln_config state ~protocol ( { d with time_between_blocks = [block_interval; 0]; + minimal_block_delay = block_interval; bootstrap_accounts = List.map d.bootstrap_accounts ~f:(fun (n, v) -> if List.exists bakers ~f:(fun baker -> Poly.equal n (fst baker)) @@ -497,6 +498,7 @@ let with_accusers ~state ~protocol ~base_port node_exec accuser_exec ( { d with time_between_blocks = [block_interval; block_interval * 2]; + minimal_block_delay = block_interval; bootstrap_accounts = List.map d.bootstrap_accounts ~f:(fun (n, v) -> if Poly.(n = fst baker) then (n, v) else (n, 1_000L)); diff --git a/src/bin_sandbox/command_ledger_baking.ml b/src/bin_sandbox/command_ledger_baking.ml index cf28a5ef87daf98b80f7fa1f85b67b25510bacf8..5fda1a1be4b4f0087e0a602e6a009a7c26dbcfc6 100644 --- a/src/bin_sandbox/command_ledger_baking.ml +++ b/src/bin_sandbox/command_ledger_baking.ml @@ -316,6 +316,7 @@ let run state ~protocol ~node_exec ~client_exec ~admin_exec ~size ~base_port { protocol with time_between_blocks = [1; 2]; + minimal_block_delay = 1; bootstrap_accounts = (ledger_account, 1_000_000_000_000L) :: protocol.bootstrap_accounts; } diff --git a/src/bin_sandbox/command_ledger_wallet.ml b/src/bin_sandbox/command_ledger_wallet.ml index 745fb0817411807c1506e53a98a99b3141b96dfc..87c2d1fb28e527bccb76f0660372d4eaa57cc73e 100644 --- a/src/bin_sandbox/command_ledger_wallet.ml +++ b/src/bin_sandbox/command_ledger_wallet.ml @@ -1190,6 +1190,7 @@ let run state ~pp_error ~protocol ~protocol_kind ~node_exec ~client_exec d with kind = protocol_kind; time_between_blocks = [1; 0]; + minimal_block_delay = 1; bootstrap_accounts = List.map d.bootstrap_accounts ~f:(fun (n, v) -> if Poly.(fst baker = n) then (n, v) else (n, 1_000L)); diff --git a/src/bin_sandbox/command_node_synchronization.ml b/src/bin_sandbox/command_node_synchronization.ml index 42be581280d1d60b475b6de7a86c0cb1dde6c889..58d51d18e67136be4e21d33aa923c49fbb5f47f9 100644 --- a/src/bin_sandbox/command_node_synchronization.ml +++ b/src/bin_sandbox/command_node_synchronization.ml @@ -24,6 +24,7 @@ let run state ~node_exec ~client_exec ~primary_history_mode timestamp_delay = Some (-3600); expected_pow = 0; time_between_blocks = [block_interval; 0]; + minimal_block_delay = block_interval; } in let primary_node = diff --git a/src/bin_sandbox/command_voting.ml b/src/bin_sandbox/command_voting.ml index 90965feec76af19b26231e025cf2ac77a641bc3d..a3a71c9b7123bbdfb175f0576bb1975d2696ed8c 100644 --- a/src/bin_sandbox/command_voting.ml +++ b/src/bin_sandbox/command_voting.ml @@ -163,6 +163,7 @@ let run state ~winner_path ~demo_path ~protocol ~node_exec ~client_exec ( { protocol with time_between_blocks = [1; 0]; + minimal_block_delay = 1; bootstrap_accounts = List.map protocol.bootstrap_accounts ~f:(fun (n, v) -> if Poly.(fst baker = n) then (n, v) else (n, 1_000L)); diff --git a/src/proto_009_PsFLoren/lib_protocol/test/test_baking.ml b/src/proto_009_PsFLoren/lib_protocol/test/test_baking.ml index 5daa9183db5144f05c6edb1ecac28a3d8470e4b4..e2688c924a7dedd7ce01e6b076df70945ce4f49a 100644 --- a/src/proto_009_PsFLoren/lib_protocol/test/test_baking.ml +++ b/src/proto_009_PsFLoren/lib_protocol/test/test_baking.ml @@ -124,7 +124,10 @@ let test_rewards_retrieval () = let real_endorsers = List.sub endorsers endorsing_power in List.map_ep (fun endorser -> - Op.endorsement ~delegate:endorser.delegate (B good_b) () + Op.endorsement_with_slot + ~delegate:(endorser.delegate, endorser.slots) + (B good_b) + () >|=? fun operation -> Operation.pack operation) real_endorsers >>=? fun operations -> diff --git a/src/proto_alpha/lib_client/mockup.ml b/src/proto_alpha/lib_client/mockup.ml index 9979ee64e683682c5fa4b19ddd4ecef713bfca27..b372d00170e9b9213d1720bb4425e240d3cfc9f2 100644 --- a/src/proto_alpha/lib_client/mockup.ml +++ b/src/proto_alpha/lib_client/mockup.ml @@ -40,6 +40,7 @@ module Protocol_constants_overrides = struct blocks_per_roll_snapshot : int32 option; blocks_per_voting_period : int32 option; time_between_blocks : Period.t list option; + minimal_block_delay : Period.t option; endorsers_per_block : int option; hard_gas_limit_per_operation : Gas.Arith.integral option; hard_gas_limit_per_block : Gas.Arith.integral option; @@ -87,21 +88,21 @@ module Protocol_constants_overrides = struct c.endorsement_security_deposit, c.baking_reward_per_endorsement, c.endorsement_reward ), - ( c.cost_per_byte, - c.hard_storage_limit_per_operation, - Some 0L, - (* At this position in the encoding we used to have a test + ( ( c.cost_per_byte, + c.hard_storage_limit_per_operation, + Some 0L, + (* At this position in the encoding we used to have a test chain duration but it is not used anymore and should be removed when this encoding is updated. When the test chain was removed, we did not want to change the encoding for retrocompatibility. *) - c.quorum_min, - c.quorum_max, - c.min_proposal_quorum, - c.initial_endorsers, - c.delay_per_missing_endorsement, - c.chain_id, - c.timestamp ) ) )) + c.quorum_min, + c.quorum_max, + c.min_proposal_quorum, + c.initial_endorsers, + c.delay_per_missing_endorsement, + c.minimal_block_delay ), + (c.chain_id, c.timestamp) ) ) )) (fun ( ( preserved_cycles, blocks_per_cycle, blocks_per_commitment, @@ -120,16 +121,16 @@ module Protocol_constants_overrides = struct endorsement_security_deposit, baking_reward_per_endorsement, endorsement_reward ), - ( cost_per_byte, - hard_storage_limit_per_operation, - _test_chain_duration, - quorum_min, - quorum_max, - min_proposal_quorum, - initial_endorsers, - delay_per_missing_endorsement, - chain_id, - timestamp ) ) ) -> + ( ( cost_per_byte, + hard_storage_limit_per_operation, + _test_chain_duration, + quorum_min, + quorum_max, + min_proposal_quorum, + initial_endorsers, + delay_per_missing_endorsement, + minimal_block_delay ), + (chain_id, timestamp) ) ) ) -> { preserved_cycles; blocks_per_cycle; @@ -156,6 +157,7 @@ module Protocol_constants_overrides = struct min_proposal_quorum; initial_endorsers; delay_per_missing_endorsement; + minimal_block_delay; chain_id; timestamp; }) @@ -181,17 +183,20 @@ module Protocol_constants_overrides = struct (opt "endorsement_security_deposit" Tez.encoding) (opt "baking_reward_per_endorsement" (list Tez.encoding)) (opt "endorsement_reward" (list Tez.encoding))) - (obj10 - (opt "cost_per_byte" Tez.encoding) - (opt "hard_storage_limit_per_operation" z) - (opt "test_chain_duration" int64) - (opt "quorum_min" int32) - (opt "quorum_max" int32) - (opt "min_proposal_quorum" int32) - (opt "initial_endorsers" uint16) - (opt "delay_per_missing_endorsement" Period.encoding) - (opt "chain_id" Chain_id.encoding) - (opt "initial_timestamp" Time.Protocol.encoding)))) + (merge_objs + (obj9 + (opt "cost_per_byte" Tez.encoding) + (opt "hard_storage_limit_per_operation" z) + (opt "test_chain_duration" int64) + (opt "quorum_min" int32) + (opt "quorum_max" int32) + (opt "min_proposal_quorum" int32) + (opt "initial_endorsers" uint16) + (opt "delay_per_missing_endorsement" Period.encoding) + (opt "minimal_block_delay" Period.encoding)) + (obj2 + (opt "chain_id" Chain_id.encoding) + (opt "initial_timestamp" Time.Protocol.encoding))))) let default_value (cctxt : Tezos_client_base.Client_context.full) : t tzresult Lwt.t = @@ -213,6 +218,7 @@ module Protocol_constants_overrides = struct blocks_per_roll_snapshot = Some parametric.blocks_per_roll_snapshot; blocks_per_voting_period = Some parametric.blocks_per_voting_period; time_between_blocks = Some parametric.time_between_blocks; + minimal_block_delay = Some parametric.minimal_block_delay; endorsers_per_block = Some parametric.endorsers_per_block; hard_gas_limit_per_operation = Some parametric.hard_gas_limit_per_operation; @@ -251,6 +257,7 @@ module Protocol_constants_overrides = struct blocks_per_roll_snapshot = None; blocks_per_voting_period = None; time_between_blocks = None; + minimal_block_delay = None; endorsers_per_block = None; hard_gas_limit_per_operation = None; hard_gas_limit_per_block = None; @@ -332,6 +339,12 @@ module Protocol_constants_overrides = struct override_value = o.time_between_blocks; pp = pp_print_list Period.pp; }; + O + { + name = "minimal_block_delay"; + override_value = o.minimal_block_delay; + pp = Period.pp; + }; O { name = "endorsers_per_block"; @@ -486,6 +499,8 @@ module Protocol_constants_overrides = struct o.blocks_per_voting_period; time_between_blocks = Option.value ~default:c.time_between_blocks o.time_between_blocks; + minimal_block_delay = + Option.value ~default:c.minimal_block_delay o.minimal_block_delay; endorsers_per_block = Option.value ~default:c.endorsers_per_block o.endorsers_per_block; hard_gas_limit_per_operation = diff --git a/src/proto_alpha/lib_parameters/default_parameters.ml b/src/proto_alpha/lib_parameters/default_parameters.ml index 88537b786d65e98006919017a9ac7e2d843d868c..ee9e2286e7960a83c694bbdeab6b6ef8368d2024 100644 --- a/src/proto_alpha/lib_parameters/default_parameters.ml +++ b/src/proto_alpha/lib_parameters/default_parameters.ml @@ -34,28 +34,29 @@ let constants_mainnet = blocks_per_roll_snapshot = 256l; blocks_per_voting_period = 20480l; time_between_blocks = List.map Period.of_seconds_exn [60L; 40L]; - endorsers_per_block = 32; + minimal_block_delay = Period.of_seconds_exn 30L; + endorsers_per_block = 256; hard_gas_limit_per_operation = Gas.Arith.(integral_of_int_exn 1_040_000); - hard_gas_limit_per_block = Gas.Arith.(integral_of_int_exn 10_400_000); + hard_gas_limit_per_block = Gas.Arith.(integral_of_int_exn 5_200_000); proof_of_work_threshold = Int64.(sub (shift_left 1L 46) 1L); tokens_per_roll = Tez.(mul_exn one 8_000); michelson_maximum_type_size = 1000; seed_nonce_revelation_tip = (match Tez.(one /? 8L) with Ok c -> c | Error _ -> assert false); origination_size = 257; - block_security_deposit = Tez.(mul_exn one 512); - endorsement_security_deposit = Tez.(mul_exn one 64); + block_security_deposit = Tez.(mul_exn one 640); + endorsement_security_deposit = Tez.(mul_exn one_cent 250); baking_reward_per_endorsement = - Tez.[of_mutez_exn 1_250_000L; of_mutez_exn 187_500L]; - endorsement_reward = Tez.[of_mutez_exn 1_250_000L; of_mutez_exn 833_333L]; + Tez.[of_mutez_exn 78_125L; of_mutez_exn 11_719L]; + endorsement_reward = Tez.[of_mutez_exn 78_125L; of_mutez_exn 52_083L]; hard_storage_limit_per_operation = Z.of_int 60_000; cost_per_byte = Tez.of_mutez_exn 250L; quorum_min = 20_00l; (* quorum is in centile of a percentage *) quorum_max = 70_00l; min_proposal_quorum = 5_00l; - initial_endorsers = 24; - delay_per_missing_endorsement = Period.of_seconds_exn 8L; + initial_endorsers = 192; + delay_per_missing_endorsement = Period.of_seconds_exn 4L; } let constants_sandbox = @@ -68,6 +69,7 @@ let constants_sandbox = blocks_per_roll_snapshot = 4l; blocks_per_voting_period = 64l; time_between_blocks = List.map Period.of_seconds_exn [1L; 0L]; + minimal_block_delay = Period.of_seconds_exn 1L; proof_of_work_threshold = Int64.of_int (-1); initial_endorsers = 1; delay_per_missing_endorsement = Period.of_seconds_exn 1L; @@ -82,6 +84,7 @@ let constants_test = blocks_per_roll_snapshot = 32l; blocks_per_voting_period = 256l; time_between_blocks = List.map Period.of_seconds_exn [1L; 0L]; + minimal_block_delay = Period.of_seconds_exn 1L; proof_of_work_threshold = Int64.of_int (-1); initial_endorsers = 1; delay_per_missing_endorsement = Period.of_seconds_exn 1L; diff --git a/src/proto_alpha/lib_protocol/alpha_context.ml b/src/proto_alpha/lib_protocol/alpha_context.ml index a0e2c784b8dfba5f78e104ce4c682de259e8640d..99ca1e50dda97090e84821042ac8b9957c3aa896 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.ml +++ b/src/proto_alpha/lib_protocol/alpha_context.ml @@ -45,6 +45,8 @@ module Timestamp = struct include Time_repr let current = Raw_context.current_timestamp + + let predecessor = Raw_context.predecessor_timestamp end include Operation_repr @@ -77,15 +79,10 @@ module Script_timestamp = struct include Script_timestamp_repr let now ctxt = - let {Constants_repr.time_between_blocks; _} = Raw_context.constants ctxt in - match time_between_blocks with - | [] -> - failwith - "Internal error: 'time_between_block' constants is an empty list." - | first_delay :: _ -> - let current_timestamp = Raw_context.predecessor_timestamp ctxt in - Time.add current_timestamp (Period_repr.to_seconds first_delay) - |> Timestamp.to_seconds |> of_int64 + let {Constants_repr.minimal_block_delay; _} = Raw_context.constants ctxt in + let current_timestamp = Raw_context.predecessor_timestamp ctxt in + Time.add current_timestamp (Period_repr.to_seconds minimal_block_delay) + |> Timestamp.to_seconds |> of_int64 end module Script = struct diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index ac3cb8fcee904de5e3be8e37c92641623b1d89b6..26862a6d245db799ce60638002b4f7afba521a99 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -93,6 +93,8 @@ module Period : sig val to_seconds : period -> int64 + val add : period -> period -> period tzresult + val mult : int32 -> period -> period tzresult val zero : period @@ -102,6 +104,8 @@ module Period : sig val one_minute : period val one_hour : period + + val compare : period -> period -> int end module Timestamp : sig @@ -122,6 +126,8 @@ module Timestamp : sig val to_seconds_string : time -> string val current : context -> time + + val predecessor : context -> time end module Raw_level : sig @@ -495,6 +501,7 @@ module Constants : sig blocks_per_roll_snapshot : int32; blocks_per_voting_period : int32; time_between_blocks : Period.t list; + minimal_block_delay : Period.t; endorsers_per_block : int; hard_gas_limit_per_operation : Gas.Arith.integral; hard_gas_limit_per_block : Gas.Arith.integral; @@ -532,6 +539,8 @@ module Constants : sig val time_between_blocks : context -> Period.t list + val minimal_block_delay : context -> Period.t + val endorsers_per_block : context -> int val initial_endorsers : context -> int diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index 745b239fcf3b52c76d4a8913d45c8d896247e724..981b96d6995800758e39543787770f782216a833 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -121,14 +121,6 @@ type error += Gas_quota_exceeded_init_deserialize (* Permanent *) type error += (* `Permanent *) Inconsistent_sources -type error += - | Not_enough_endorsements_for_priority of { - required : int; - priority : int; - endorsements : int; - timestamp : Time.t; - } - type error += (* `Permanent *) Failing_noop_error let () = @@ -507,38 +499,6 @@ let () = Data_encoding.empty (function Inconsistent_sources -> Some () | _ -> None) (fun () -> Inconsistent_sources) ; - register_error_kind - `Permanent - ~id:"operation.not_enough_endorsements_for_priority" - ~title:"Not enough endorsements for priority" - ~description: - "The block being validated does not include the required minimum number \ - of endorsements for this priority." - ~pp:(fun ppf (required, endorsements, priority, timestamp) -> - Format.fprintf - ppf - "Wrong number of endorsements (%i) for priority (%i), %i are expected \ - at %a" - endorsements - priority - required - Time.pp_hum - timestamp) - Data_encoding.( - obj4 - (req "required" int31) - (req "endorsements" int31) - (req "priority" int31) - (req "timestamp" Time.encoding)) - (function - | Not_enough_endorsements_for_priority - {required; endorsements; priority; timestamp} -> - Some (required, endorsements, priority, timestamp) - | _ -> - None) - (fun (required, endorsements, priority, timestamp) -> - Not_enough_endorsements_for_priority - {required; endorsements; priority; timestamp}) ; register_error_kind `Permanent ~id:"operation.failing_noop" @@ -1465,13 +1425,13 @@ let apply_operation ctxt chain_id mode pred_block baker hash operation = (ctxt, {contents = result}) let may_snapshot_roll ctxt = - let level = Alpha_context.Level.current ctxt in + let level = Level.current ctxt in let blocks_per_roll_snapshot = Constants.blocks_per_roll_snapshot ctxt in if Compare.Int32.equal (Int32.rem level.cycle_position blocks_per_roll_snapshot) (Int32.pred blocks_per_roll_snapshot) - then Alpha_context.Roll.snapshot_rolls ctxt + then Roll.snapshot_rolls ctxt else return ctxt let may_start_new_cycle ctxt = @@ -1496,17 +1456,19 @@ let endorsement_rights_of_pred_level ctxt = Baking.endorsement_rights ctxt pred_level let begin_full_construction ctxt pred_timestamp protocol_data = - Alpha_context.Global.set_block_priority - ctxt - protocol_data.Block_header.priority + let priority = protocol_data.Block_header.priority in + Global.set_block_priority ctxt priority >>=? fun ctxt -> - Baking.check_baking_rights ctxt protocol_data pred_timestamp - >>=? fun (delegate_pk, block_delay) -> + Baking.check_timestamp ctxt ~priority pred_timestamp + >>?= fun () -> + let level = Level.current ctxt in + Roll.baking_rights_owner ctxt level ~priority + >>=? fun delegate_pk -> let ctxt = Fitness.increase ctxt in endorsement_rights_of_pred_level ctxt >|=? fun rights -> let ctxt = init_endorsements ctxt rights in - (ctxt, protocol_data, delegate_pk, block_delay) + (ctxt, protocol_data, delegate_pk) let begin_partial_construction ctxt = let ctxt = Fitness.increase ctxt in @@ -1514,20 +1476,18 @@ let begin_partial_construction ctxt = >|=? fun rights -> init_endorsements ctxt rights let begin_application ctxt chain_id block_header pred_timestamp = - Alpha_context.Global.set_block_priority - ctxt - block_header.Block_header.protocol_data.contents.priority + let priority = block_header.Block_header.protocol_data.contents.priority in + Global.set_block_priority ctxt priority >>=? fun ctxt -> - let current_level = Alpha_context.Level.current ctxt in + Baking.check_timestamp ctxt ~priority pred_timestamp + >>?= fun () -> Baking.check_proof_of_work_stamp ctxt block_header >>?= fun () -> Baking.check_fitness_gap ctxt block_header >>?= fun () -> - Baking.check_baking_rights - ctxt - block_header.protocol_data.contents - pred_timestamp - >>=? fun (delegate_pk, block_delay) -> + let current_level = Level.current ctxt in + Roll.baking_rights_owner ctxt current_level ~priority + >>=? fun delegate_pk -> Baking.check_signature block_header chain_id delegate_pk >>=? fun () -> let has_commitment = @@ -1541,29 +1501,33 @@ let begin_application ctxt chain_id block_header pred_timestamp = endorsement_rights_of_pred_level ctxt >|=? fun rights -> let ctxt = init_endorsements ctxt rights in - (ctxt, delegate_pk, block_delay) + (ctxt, delegate_pk) -let check_minimum_endorsements ctxt protocol_data block_delay - included_endorsements = - let minimum = Baking.minimum_allowed_endorsements ctxt ~block_delay in +let check_minimal_valid_time ctxt ~priority ~endorsing_power = + let predecessor_timestamp = Timestamp.predecessor ctxt in + Baking.minimal_valid_time + (Constants.parametric ctxt) + ~priority + ~endorsing_power + ~predecessor_timestamp + >>? fun minimum -> let timestamp = Timestamp.current ctxt in error_unless - Compare.Int.(included_endorsements >= minimum) - (Not_enough_endorsements_for_priority + Compare.Int64.(Time.to_seconds timestamp >= Time.to_seconds minimum) + (Baking.Timestamp_too_early { - required = minimum; - priority = protocol_data.Block_header.priority; - endorsements = included_endorsements; - timestamp; + minimal_time = minimum; + provided_time = timestamp; + priority; + endorsing_power_opt = Some endorsing_power; }) -let finalize_application ctxt protocol_data delegate ~block_delay - migration_balance_updates = +let finalize_application ctxt protocol_data delegate migration_balance_updates + = let included_endorsements = included_endorsements ctxt in - check_minimum_endorsements + check_minimal_valid_time ctxt - protocol_data - block_delay + protocol_data.Block_header.priority included_endorsements >>?= fun () -> let deposit = Constants.block_security_deposit ctxt in @@ -1617,16 +1581,16 @@ let finalize_application ctxt protocol_data delegate ~block_delay let consumed_gas = Gas.Arith.sub (Gas.Arith.fp @@ Constants.hard_gas_limit_per_block ctxt) - (Alpha_context.Gas.block_level ctxt) + (Gas.block_level ctxt) in (* This value is different than the new [voting_period_info] below for compatibility reasons, the field [voting_period_kind] is deprecated and will be removed in a future version. *) - Alpha_context.Voting_period.get_current_info ctxt + Voting_period.get_current_info ctxt >>=? fun {voting_period = {kind; _}; _} -> - Alpha_context.Voting_period.get_rpc_fixed_current_info ctxt + Voting_period.get_rpc_fixed_current_info ctxt >|=? fun ({voting_period; position; _} as voting_period_info) -> - let level_info = Alpha_context.Level.current ctxt in + let level_info = Level.current ctxt in let receipt = Apply_results. { diff --git a/src/proto_alpha/lib_protocol/apply.mli b/src/proto_alpha/lib_protocol/apply.mli index fbac491292c283bda50c67e81852496ff6794237..2c339d05cc1ac15c081f2f1ecdbac233599640e0 100644 --- a/src/proto_alpha/lib_protocol/apply.mli +++ b/src/proto_alpha/lib_protocol/apply.mli @@ -91,14 +91,6 @@ type error += Gas_quota_exceeded_init_deserialize type error += Inconsistent_sources -type error += - | Not_enough_endorsements_for_priority of { - required : int; - priority : int; - endorsements : int; - timestamp : Time.t; - } - type error += (* `Permanent *) Failing_noop_error val begin_partial_construction : t -> (t, error trace) result Lwt.t @@ -107,14 +99,14 @@ val begin_full_construction : t -> Time.t -> Block_header.contents -> - (t * Block_header.contents * public_key * Period.t, error trace) result Lwt.t + (t * Block_header.contents * public_key, error trace) result Lwt.t val begin_application : t -> Chain_id.t -> Block_header.t -> Time.t -> - (t * public_key * Period.t, error trace) result Lwt.t + (t * public_key, error trace) result Lwt.t val apply_operation : t -> @@ -130,7 +122,6 @@ val finalize_application : t -> Block_header.contents -> public_key_hash -> - block_delay:Period.t -> Receipt.balance_updates -> (t * block_metadata, error trace) result Lwt.t @@ -152,5 +143,5 @@ val apply_contents_list : 'kind contents_list -> (t * 'kind contents_result_list) tzresult Lwt.t -val check_minimum_endorsements : - t -> Block_header.contents -> Period.t -> int -> (unit, error trace) result +val check_minimal_valid_time : + t -> priority:int -> endorsing_power:int -> (unit, error trace) result diff --git a/src/proto_alpha/lib_protocol/baking.ml b/src/proto_alpha/lib_protocol/baking.ml index d6c18e551e9462a1e810258632f530b14e7da04b..b89abd54e3a8f0a4afa1e35e992ab05119d9e30a 100644 --- a/src/proto_alpha/lib_protocol/baking.ml +++ b/src/proto_alpha/lib_protocol/baking.ml @@ -28,7 +28,13 @@ open Misc type error += Invalid_fitness_gap of int64 * int64 (* `Permanent *) -type error += Timestamp_too_early of Timestamp.t * Timestamp.t +type error += + | Timestamp_too_early of { + minimal_time : Timestamp.t; + provided_time : Timestamp.t; + priority : int; + endorsing_power_opt : int option; + } (* `Permanent *) @@ -52,21 +58,40 @@ let () = `Permanent ~id:"baking.timestamp_too_early" ~title:"Block forged too early" - ~description: - "The block timestamp is before the first slot for this baker at this \ - level" - ~pp:(fun ppf (r, p) -> + ~description:"The block timestamp is before the minimal valid one." + ~pp:(fun ppf (minimal_time, provided_time, priority, endorsing_power) -> + let message_regarding_endorsements = + match endorsing_power with + | None -> + "" + | Some power -> + Format.asprintf " and endorsing power %d" power + in Format.fprintf ppf - "Block forged too early (%a is before %a)" + "Block forged too early: %a is before the minimal time %a for \ + priority %d%s)" Time.pp_hum - p + provided_time Time.pp_hum - r) + minimal_time + priority + message_regarding_endorsements) Data_encoding.( - obj2 (req "minimum" Time.encoding) (req "provided" Time.encoding)) - (function Timestamp_too_early (r, p) -> Some (r, p) | _ -> None) - (fun (r, p) -> Timestamp_too_early (r, p)) ; + obj4 + (req "minimal_time" Time.encoding) + (req "provided_time" Time.encoding) + (req "priority" int31) + (opt "endorsing_power" int31)) + (function + | Timestamp_too_early + {minimal_time; provided_time; priority; endorsing_power_opt} -> + Some (minimal_time, provided_time, priority, endorsing_power_opt) + | _ -> + None) + (fun (minimal_time, provided_time, priority, endorsing_power_opt) -> + Timestamp_too_early + {minimal_time; provided_time; priority; endorsing_power_opt}) ; register_error_kind `Permanent ~id:"baking.invalid_fitness_gap" @@ -155,8 +180,14 @@ let () = (function Unexpected_endorsement_slot v -> Some v | _ -> None) (fun v -> Unexpected_endorsement_slot v) -let minimal_time c priority pred_timestamp = - let priority = Int32.of_int priority in +(* The function implements the fast-path case in [minimal_time]. (See + [minimal_valid_time] for the definition of the fast-path.) *) +let minimal_time_fastpath_case minimal_block_delay pred_timestamp = + Timestamp.(pred_timestamp +? minimal_block_delay) + +(* The function implements the slow-path case in [minimal_time]. (See + [minimal_valid_time] for the definition of the slow-path.) *) +let minimal_time_slowpath_case time_between_blocks priority pred_timestamp = let rec cumsum_time_between_blocks acc durations p = if Compare.Int32.( <= ) p 0l then ok acc else @@ -173,35 +204,46 @@ let minimal_time c priority pred_timestamp = in cumsum_time_between_blocks pred_timestamp - (Constants.time_between_blocks c) + time_between_blocks (Int32.succ priority) +let minimal_time constants ~priority pred_timestamp = + let priority = Int32.of_int priority in + if Compare.Int32.(priority = 0l) then + minimal_time_fastpath_case + constants.Constants.minimal_block_delay + pred_timestamp + else + minimal_time_slowpath_case + constants.time_between_blocks + priority + pred_timestamp + let earlier_predecessor_timestamp ctxt level = let current = Level.current ctxt in let current_timestamp = Timestamp.current ctxt in let gap = Level.diff level current in - let step = List.hd (Constants.time_between_blocks ctxt) in + let step = Constants.minimal_block_delay ctxt in if Compare.Int32.(gap < 1l) then failwith "Baking.earlier_block_timestamp: past block." else Period.mult (Int32.pred gap) step >>? fun delay -> Timestamp.(current_timestamp +? delay) -let check_timestamp c priority pred_timestamp = - minimal_time c priority pred_timestamp +let check_timestamp c ~priority pred_timestamp = + minimal_time (Constants.parametric c) priority pred_timestamp >>? fun minimal_time -> - let timestamp = Alpha_context.Timestamp.current c in + let timestamp = Timestamp.current c in record_trace - (Timestamp_too_early (minimal_time, timestamp)) + (Timestamp_too_early + { + minimal_time; + provided_time = timestamp; + priority; + endorsing_power_opt = None; + }) Timestamp.(timestamp -? minimal_time) - -let check_baking_rights c {Block_header.priority; _} pred_timestamp = - let level = Level.current c in - Roll.baking_rights_owner c level ~priority - >>=? fun delegate -> - Lwt.return - ( check_timestamp c priority pred_timestamp - >|? fun block_delay -> (delegate, block_delay) ) + >>? fun _block_delay -> ok () type error += Incorrect_priority (* `Permanent *) @@ -404,29 +446,44 @@ let dawn_of_a_new_cycle ctxt = let level = Level.current ctxt in if last_of_a_cycle ctxt level then Some level.cycle else None -let minimum_allowed_endorsements ctxt ~block_delay = - let minimum = Constants.initial_endorsers ctxt in - let delay_per_missing_endorsement = - Period.to_seconds (Constants.delay_per_missing_endorsement ctxt) - in - let reduced_time_constraint = - let delay = Period.to_seconds block_delay in - if Compare.Int64.(delay_per_missing_endorsement = 0L) then delay - else Int64.div delay delay_per_missing_endorsement - in - if Compare.Int64.(Int64.of_int minimum < reduced_time_constraint) then 0 - else minimum - Int64.to_int reduced_time_constraint - -let minimal_valid_time ctxt ~priority ~endorsing_power = - let predecessor_timestamp = Timestamp.current ctxt in - minimal_time ctxt priority predecessor_timestamp - >>? fun minimal_time -> - let minimal_required_endorsements = Constants.initial_endorsers ctxt in - let delay_per_missing_endorsement = - Constants.delay_per_missing_endorsement ctxt - in - let missing_endorsements = - Compare.Int.max 0 (minimal_required_endorsements - endorsing_power) - in - Period.mult (Int32.of_int missing_endorsements) delay_per_missing_endorsement - >|? fun delay -> Time.add minimal_time (Period.to_seconds delay) +(* The minimal threshold on the endorsing power for the fast-path case + is 60% of the maximal endorsing power. *) +let fastpath_endorsing_power_threshold maximal_endorsing_power = + 3 * maximal_endorsing_power / 5 + +(* This function computes the minimal time at which a block is + valid. It distinguishes between the "fast-path" case, when the + priority is 0 and the endorsing power is at least 60% of the + maximal endorsing power, and the "slow-path" case, when this + condition is not satisfied. *) +let minimal_valid_time constants ~priority ~endorsing_power + ~predecessor_timestamp = + if + Compare.Int.(priority = 0) + && Compare.Int.( + endorsing_power + >= fastpath_endorsing_power_threshold + constants.Constants.endorsers_per_block) + then + minimal_time_fastpath_case + constants.minimal_block_delay + predecessor_timestamp + else + minimal_time_slowpath_case + constants.time_between_blocks + (Int32.of_int priority) + predecessor_timestamp + >>? fun minimal_time -> + let delay_per_missing_endorsement = + constants.Constants.delay_per_missing_endorsement + in + let missing_endorsements = + let minimal_required_endorsements = + constants.Constants.initial_endorsers + in + Compare.Int.max 0 (minimal_required_endorsements - endorsing_power) + in + Period.mult + (Int32.of_int missing_endorsements) + delay_per_missing_endorsement + >|? fun delay -> Time.add minimal_time (Period.to_seconds delay) diff --git a/src/proto_alpha/lib_protocol/baking.mli b/src/proto_alpha/lib_protocol/baking.mli index a6eaee1da518141a2d35f5203e59a7f7e9d90c68..99580f1ec2b49c494c6fb1ba6060f8885d4f9b74 100644 --- a/src/proto_alpha/lib_protocol/baking.mli +++ b/src/proto_alpha/lib_protocol/baking.mli @@ -28,7 +28,13 @@ open Misc type error += Invalid_fitness_gap of int64 * int64 (* `Permanent *) -type error += Timestamp_too_early of Timestamp.t * Timestamp.t +type error += + | Timestamp_too_early of { + minimal_time : Timestamp.t; + provided_time : Timestamp.t; + priority : int; + endorsing_power_opt : int option; + } (* `Permanent *) @@ -48,21 +54,16 @@ type error += Invalid_signature (* `Permanent *) type error += Invalid_stamp (* `Permanent *) (** [minimal_time ctxt priority pred_block_time] returns the minimal - time, given the predecessor block timestamp [pred_block_time], - after which a baker with priority [priority] is allowed to - bake. Fail with [Invalid_time_between_blocks_constant] if the minimal - time cannot be computed. *) -val minimal_time : context -> int -> Time.t -> Time.t tzresult - -(** [check_baking_rights ctxt block pred_timestamp] verifies that: - * the contract that owned the roll at cycle start has the block signer as delegate. - * the timestamp is coherent with the announced slot. -*) -val check_baking_rights : - context -> - Block_header.contents -> - Time.t -> - (public_key * Period.t) tzresult Lwt.t + time, given the predecessor block timestamp [pred_block_time], + after which a baker with priority [priority] is allowed to bake in + principle, that is, assuming the block will contain enough + endorsements. *) +val minimal_time : + Constants.parametric -> priority:int -> Time.t -> Time.t tzresult + +(** [check_timestamp ctxt priority pred_timestamp] verifies that + the timestamp is coherent with the announced baking slot. *) +val check_timestamp : context -> priority:int -> Time.t -> unit tzresult (** For a given level computes who has the right to include an endorsement in the next block. @@ -150,15 +151,12 @@ val earlier_predecessor_timestamp : context -> Level.t -> Timestamp.t tzresult such a decision, because the baker cannot publish a block too early. *) -(** Given a delay of a block's timestamp with respect to the minimum - time to bake at the block's priority (as returned by - `minimum_time`), it returns the minimum number of endorsements that - the block has to contain *) -val minimum_allowed_endorsements : context -> block_delay:Period.t -> int - -(** This is the somehow the dual of the previous function. Given a - block priority and a number of endorsement slots (given by the - `endorsing_power` argument), it returns the minimum time at which - the next block can be baked. *) +(** Given a block priority and a number of endorsement slots (given by + the `endorsing_power` argument), it returns the minimum time at + which the next block can be baked. *) val minimal_valid_time : - context -> priority:int -> endorsing_power:int -> Time.t tzresult + Constants.parametric -> + priority:int -> + endorsing_power:int -> + predecessor_timestamp:Time.t -> + Time.t tzresult diff --git a/src/proto_alpha/lib_protocol/constants_repr.ml b/src/proto_alpha/lib_protocol/constants_repr.ml index 1697fc966de404e112e36d00f530ec41fdf21921..8204257b92993fb92d88ce4b1b5b23e2c32fcbc2 100644 --- a/src/proto_alpha/lib_protocol/constants_repr.ml +++ b/src/proto_alpha/lib_protocol/constants_repr.ml @@ -96,6 +96,7 @@ type parametric = { blocks_per_roll_snapshot : int32; blocks_per_voting_period : int32; time_between_blocks : Period_repr.t list; + minimal_block_delay : Period_repr.t; endorsers_per_block : int; hard_gas_limit_per_operation : Gas_limit_repr.Arith.integral; hard_gas_limit_per_block : Gas_limit_repr.Arith.integral; @@ -151,7 +152,8 @@ let parametric_encoding = c.quorum_max, c.min_proposal_quorum, c.initial_endorsers, - c.delay_per_missing_endorsement ) ) )) + c.delay_per_missing_endorsement, + c.minimal_block_delay ) ) )) (fun ( ( preserved_cycles, blocks_per_cycle, blocks_per_commitment, @@ -177,7 +179,8 @@ let parametric_encoding = quorum_max, min_proposal_quorum, initial_endorsers, - delay_per_missing_endorsement ) ) ) -> + delay_per_missing_endorsement, + minimal_block_delay ) ) ) -> { preserved_cycles; blocks_per_cycle; @@ -204,6 +207,7 @@ let parametric_encoding = min_proposal_quorum; initial_endorsers; delay_per_missing_endorsement; + minimal_block_delay; }) (merge_objs (obj9 @@ -230,7 +234,7 @@ let parametric_encoding = (req "block_security_deposit" Tez_repr.encoding) (req "endorsement_security_deposit" Tez_repr.encoding) (req "baking_reward_per_endorsement" (list Tez_repr.encoding))) - (obj9 + (obj10 (req "endorsement_reward" (list Tez_repr.encoding)) (req "cost_per_byte" Tez_repr.encoding) (req "hard_storage_limit_per_operation" z) @@ -239,7 +243,8 @@ let parametric_encoding = (req "quorum_max" int32) (req "min_proposal_quorum" int32) (req "initial_endorsers" uint16) - (req "delay_per_missing_endorsement" Period_repr.encoding)))) + (req "delay_per_missing_endorsement" Period_repr.encoding) + (req "minimal_block_delay" Period_repr.encoding)))) type t = {fixed : fixed; parametric : parametric} @@ -249,3 +254,194 @@ let encoding = (fun {fixed; parametric} -> (fixed, parametric)) (fun (fixed, parametric) -> {fixed; parametric}) (merge_objs fixed_encoding parametric_encoding) + +type error += Invalid_protocol_constants of string (* `Permanent *) + +let () = + register_error_kind + `Permanent + ~id:"constants.invalid_protocol_constants" + ~title:"Invalid protocol constants" + ~description:"The provided protocol constants are not coherent." + ~pp:(fun ppf reason -> + Format.fprintf ppf "Invalid protocol constants: %s" reason) + Data_encoding.(obj1 (req "reason" string)) + (function Invalid_protocol_constants reason -> Some reason | _ -> None) + (fun reason -> Invalid_protocol_constants reason) + +let check_constants constants = + let min_time_between_blocks = + match constants.time_between_blocks with + | first_time_between_blocks :: _ -> + first_time_between_blocks + | [] -> + (* this constant is used in the Baking module *) + Period_repr.one_minute + in + error_unless + Compare.Int64.( + Period_repr.to_seconds min_time_between_blocks + >= Period_repr.to_seconds constants.minimal_block_delay) + (Invalid_protocol_constants + (Format.asprintf + "minimal_block_delay value (%Ld) should be smaller than \ + time_between_blocks[0] value (%Ld)" + (Period_repr.to_seconds constants.minimal_block_delay) + (Period_repr.to_seconds min_time_between_blocks))) + >>? fun () -> + error_unless + Compare.Int.(constants.endorsers_per_block >= constants.initial_endorsers) + (Invalid_protocol_constants + "initial_endorsers should be smaller than endorsers_per_block") + +module Proto_previous = struct + type parametric = { + preserved_cycles : int; + blocks_per_cycle : int32; + blocks_per_commitment : int32; + blocks_per_roll_snapshot : int32; + blocks_per_voting_period : int32; + time_between_blocks : Period_repr.t list; + endorsers_per_block : int; + hard_gas_limit_per_operation : Gas_limit_repr.Arith.integral; + hard_gas_limit_per_block : Gas_limit_repr.Arith.integral; + proof_of_work_threshold : int64; + tokens_per_roll : Tez_repr.t; + michelson_maximum_type_size : int; + seed_nonce_revelation_tip : Tez_repr.t; + origination_size : int; + block_security_deposit : Tez_repr.t; + endorsement_security_deposit : Tez_repr.t; + baking_reward_per_endorsement : Tez_repr.t list; + endorsement_reward : Tez_repr.t list; + cost_per_byte : Tez_repr.t; + hard_storage_limit_per_operation : Z.t; + test_chain_duration : int64; + (* in seconds *) + quorum_min : int32; + quorum_max : int32; + min_proposal_quorum : int32; + initial_endorsers : int; + delay_per_missing_endorsement : Period_repr.t; + } + + let parametric_encoding = + let open Data_encoding in + conv + (fun c -> + ( ( c.preserved_cycles, + c.blocks_per_cycle, + c.blocks_per_commitment, + c.blocks_per_roll_snapshot, + c.blocks_per_voting_period, + c.time_between_blocks, + c.endorsers_per_block, + c.hard_gas_limit_per_operation, + c.hard_gas_limit_per_block ), + ( ( c.proof_of_work_threshold, + c.tokens_per_roll, + c.michelson_maximum_type_size, + c.seed_nonce_revelation_tip, + c.origination_size, + c.block_security_deposit, + c.endorsement_security_deposit, + c.baking_reward_per_endorsement ), + ( c.endorsement_reward, + c.cost_per_byte, + c.hard_storage_limit_per_operation, + c.test_chain_duration, + c.quorum_min, + c.quorum_max, + c.min_proposal_quorum, + c.initial_endorsers, + c.delay_per_missing_endorsement ) ) )) + (fun ( ( preserved_cycles, + blocks_per_cycle, + blocks_per_commitment, + blocks_per_roll_snapshot, + blocks_per_voting_period, + time_between_blocks, + endorsers_per_block, + hard_gas_limit_per_operation, + hard_gas_limit_per_block ), + ( ( proof_of_work_threshold, + tokens_per_roll, + michelson_maximum_type_size, + seed_nonce_revelation_tip, + origination_size, + block_security_deposit, + endorsement_security_deposit, + baking_reward_per_endorsement ), + ( endorsement_reward, + cost_per_byte, + hard_storage_limit_per_operation, + test_chain_duration, + quorum_min, + quorum_max, + min_proposal_quorum, + initial_endorsers, + delay_per_missing_endorsement ) ) ) -> + { + preserved_cycles; + blocks_per_cycle; + blocks_per_commitment; + blocks_per_roll_snapshot; + blocks_per_voting_period; + time_between_blocks; + endorsers_per_block; + hard_gas_limit_per_operation; + hard_gas_limit_per_block; + proof_of_work_threshold; + tokens_per_roll; + michelson_maximum_type_size; + seed_nonce_revelation_tip; + origination_size; + block_security_deposit; + endorsement_security_deposit; + baking_reward_per_endorsement; + endorsement_reward; + cost_per_byte; + hard_storage_limit_per_operation; + test_chain_duration; + quorum_min; + quorum_max; + min_proposal_quorum; + initial_endorsers; + delay_per_missing_endorsement; + }) + (merge_objs + (obj9 + (req "preserved_cycles" uint8) + (req "blocks_per_cycle" int32) + (req "blocks_per_commitment" int32) + (req "blocks_per_roll_snapshot" int32) + (req "blocks_per_voting_period" int32) + (req "time_between_blocks" (list Period_repr.encoding)) + (req "endorsers_per_block" uint16) + (req + "hard_gas_limit_per_operation" + Gas_limit_repr.Arith.z_integral_encoding) + (req + "hard_gas_limit_per_block" + Gas_limit_repr.Arith.z_integral_encoding)) + (merge_objs + (obj8 + (req "proof_of_work_threshold" int64) + (req "tokens_per_roll" Tez_repr.encoding) + (req "michelson_maximum_type_size" uint16) + (req "seed_nonce_revelation_tip" Tez_repr.encoding) + (req "origination_size" int31) + (req "block_security_deposit" Tez_repr.encoding) + (req "endorsement_security_deposit" Tez_repr.encoding) + (req "baking_reward_per_endorsement" (list Tez_repr.encoding))) + (obj9 + (req "endorsement_reward" (list Tez_repr.encoding)) + (req "cost_per_byte" Tez_repr.encoding) + (req "hard_storage_limit_per_operation" z) + (req "test_chain_duration" int64) + (req "quorum_min" int32) + (req "quorum_max" int32) + (req "min_proposal_quorum" int32) + (req "initial_endorsers" uint16) + (req "delay_per_missing_endorsement" Period_repr.encoding)))) +end diff --git a/src/proto_alpha/lib_protocol/constants_repr.mli b/src/proto_alpha/lib_protocol/constants_repr.mli index 3d560ee1ba7afc0912706fe9c324a4c31db7e36c..4b928eb24122761c14426c5094a1658aa549ac6a 100644 --- a/src/proto_alpha/lib_protocol/constants_repr.mli +++ b/src/proto_alpha/lib_protocol/constants_repr.mli @@ -57,6 +57,7 @@ type parametric = { blocks_per_roll_snapshot : int32; blocks_per_voting_period : int32; time_between_blocks : Period_repr.t list; + minimal_block_delay : Period_repr.t; endorsers_per_block : int; hard_gas_limit_per_operation : Gas_limit_repr.Arith.integral; hard_gas_limit_per_block : Gas_limit_repr.Arith.integral; @@ -84,3 +85,40 @@ val parametric_encoding : parametric Data_encoding.encoding type t = {fixed : fixed; parametric : parametric} val encoding : t Data_encoding.encoding + +(** performs some consistency on the protocol parameters *) +val check_constants : parametric -> unit tzresult + +module Proto_previous : sig + type parametric = { + preserved_cycles : int; + blocks_per_cycle : int32; + blocks_per_commitment : int32; + blocks_per_roll_snapshot : int32; + blocks_per_voting_period : int32; + time_between_blocks : Period_repr.t list; + endorsers_per_block : int; + hard_gas_limit_per_operation : Gas_limit_repr.Arith.integral; + hard_gas_limit_per_block : Gas_limit_repr.Arith.integral; + proof_of_work_threshold : int64; + tokens_per_roll : Tez_repr.t; + michelson_maximum_type_size : int; + seed_nonce_revelation_tip : Tez_repr.t; + origination_size : int; + block_security_deposit : Tez_repr.t; + endorsement_security_deposit : Tez_repr.t; + baking_reward_per_endorsement : Tez_repr.t list; + endorsement_reward : Tez_repr.t list; + cost_per_byte : Tez_repr.t; + hard_storage_limit_per_operation : Z.t; + test_chain_duration : int64; + (* in seconds *) + quorum_min : int32; + quorum_max : int32; + min_proposal_quorum : int32; + initial_endorsers : int; + delay_per_missing_endorsement : Period_repr.t; + } + + val parametric_encoding : parametric Data_encoding.encoding +end diff --git a/src/proto_alpha/lib_protocol/constants_storage.ml b/src/proto_alpha/lib_protocol/constants_storage.ml index 772b11e875bc2ddda890b995375926f97da42e59..bb645bf19f465317a2567904bd7514fe45264de9 100644 --- a/src/proto_alpha/lib_protocol/constants_storage.ml +++ b/src/proto_alpha/lib_protocol/constants_storage.ml @@ -47,6 +47,10 @@ let time_between_blocks c = let constants = Raw_context.constants c in constants.time_between_blocks +let minimal_block_delay c = + let constants = Raw_context.constants c in + constants.minimal_block_delay + let endorsers_per_block c = let constants = Raw_context.constants c in constants.endorsers_per_block diff --git a/src/proto_alpha/lib_protocol/constants_storage.mli b/src/proto_alpha/lib_protocol/constants_storage.mli index 34fa2f6228b1bdad0a2dca6b8030321de072087e..5c7b043e76c64f4ea503616a8514feaf456a0a9b 100644 --- a/src/proto_alpha/lib_protocol/constants_storage.mli +++ b/src/proto_alpha/lib_protocol/constants_storage.mli @@ -36,6 +36,8 @@ val blocks_per_voting_period : Raw_context.t -> int32 val time_between_blocks : Raw_context.t -> Period_repr.t list +val minimal_block_delay : Raw_context.t -> Period_repr.t + val endorsers_per_block : Raw_context.t -> int val initial_endorsers : Raw_context.t -> int diff --git a/src/proto_alpha/lib_protocol/delegate_services.ml b/src/proto_alpha/lib_protocol/delegate_services.ml index 1c3a6a7b28975a56344d0f383a3954244ea9f457..c7b3135bb602e8029fcd15b7a2bac748be076c0b 100644 --- a/src/proto_alpha/lib_protocol/delegate_services.ml +++ b/src/proto_alpha/lib_protocol/delegate_services.ml @@ -406,7 +406,10 @@ module Baking_rights = struct | None -> ok_none | Some pred_timestamp -> - Baking.minimal_time ctxt priority pred_timestamp + Baking.minimal_time + (Constants.parametric ctxt) + priority + pred_timestamp >|? fun t -> Some t ) >>?= fun timestamp -> let acc = @@ -442,7 +445,10 @@ module Baking_rights = struct | None -> ok_none | Some pred_timestamp -> - Baking.minimal_time ctxt priority pred_timestamp + Baking.minimal_time + (Constants.parametric ctxt) + priority + pred_timestamp >|? fun t -> Some t ) >>?= fun timestamp -> let acc = @@ -660,44 +666,14 @@ module Endorsing_power = struct RPC_context.make_call0 S.endorsing_power ctxt block () (op, chain_id) end -module Required_endorsements = struct - let required_endorsements ctxt block_delay = - Baking.minimum_allowed_endorsements ctxt ~block_delay - - module S = struct - type t = {block_delay : Period.t} - - let required_endorsements_query = - let open RPC_query in - query (fun block_delay -> {block_delay}) - |+ field "block_delay" Period.rpc_arg Period.zero (fun t -> - t.block_delay) - |> seal - - let required_endorsements = - let open Data_encoding in - RPC_service.get_service - ~description: - "Minimum number of endorsements for a block to be valid, given a \ - delay of the block's timestamp with respect to the minimum time to \ - bake at the block's priority" - ~query:required_endorsements_query - ~output:int31 - RPC_path.(open_root / "required_endorsements") - end - - let register () = - let open Services_registration in - register0 S.required_endorsements (fun ctxt {block_delay} () -> - return @@ required_endorsements ctxt block_delay) - - let get ctxt block block_delay = - RPC_context.make_call0 S.required_endorsements ctxt block {block_delay} () -end - module Minimal_valid_time = struct - let minimal_valid_time ctxt ~priority ~endorsing_power = - Baking.minimal_valid_time ctxt ~priority ~endorsing_power + let minimal_valid_time ctxt ~priority ~endorsing_power ~predecessor_timestamp + = + Baking.minimal_valid_time + (Constants.parametric ctxt) + ~priority + ~endorsing_power + ~predecessor_timestamp module S = struct type t = {priority : int; endorsing_power : int} @@ -722,7 +698,13 @@ module Minimal_valid_time = struct let register () = let open Services_registration in register0 S.minimal_valid_time (fun ctxt {priority; endorsing_power} () -> - Lwt.return @@ minimal_valid_time ctxt ~priority ~endorsing_power) + let predecessor_timestamp = Timestamp.predecessor ctxt in + Lwt.return + @@ minimal_valid_time + ctxt + ~priority + ~endorsing_power + ~predecessor_timestamp) let get ctxt block priority endorsing_power = RPC_context.make_call0 @@ -738,7 +720,6 @@ let register () = Baking_rights.register () ; Endorsing_rights.register () ; Endorsing_power.register () ; - Required_endorsements.register () ; Minimal_valid_time.register () let endorsement_rights ctxt level = @@ -758,8 +739,9 @@ let baking_rights ctxt max_priority = let endorsing_power ctxt operation = Endorsing_power.endorsing_power ctxt operation -let required_endorsements ctxt delay = - Required_endorsements.required_endorsements ctxt delay - -let minimal_valid_time ctxt priority endorsing_power = - Minimal_valid_time.minimal_valid_time ctxt priority endorsing_power +let minimal_valid_time ctxt priority endorsing_power predecessor_timestamp = + Minimal_valid_time.minimal_valid_time + ctxt + ~priority + ~endorsing_power + ~predecessor_timestamp diff --git a/src/proto_alpha/lib_protocol/delegate_services.mli b/src/proto_alpha/lib_protocol/delegate_services.mli index f8ec3fd7426412e60ca1ba26ca66880bd9d1a642..8b2b13cc24530b29d86dab7e5b0fab9b21fe7e63 100644 --- a/src/proto_alpha/lib_protocol/delegate_services.mli +++ b/src/proto_alpha/lib_protocol/delegate_services.mli @@ -184,11 +184,6 @@ module Endorsing_power : sig int shell_tzresult Lwt.t end -module Required_endorsements : sig - val get : - 'a #RPC_context.simple -> 'a -> Period.t -> int shell_tzresult Lwt.t -end - module Minimal_valid_time : sig val get : 'a #RPC_context.simple -> 'a -> int -> int -> Time.t shell_tzresult Lwt.t @@ -208,8 +203,7 @@ val endorsing_power : Alpha_context.packed_operation * Chain_id.t -> int tzresult Lwt.t -val required_endorsements : Alpha_context.t -> Alpha_context.Period.t -> int - -val minimal_valid_time : Alpha_context.t -> int -> int -> Time.t tzresult +val minimal_valid_time : + Alpha_context.t -> int -> int -> Time.t -> Time.t tzresult val register : unit -> unit diff --git a/src/proto_alpha/lib_protocol/main.ml b/src/proto_alpha/lib_protocol/main.ml index 1439a430f337daeb8433ee7f0363fe32e2a58bbe..6176efd4bd4cb95c3cdbfbfe4a0188021f330c4b 100644 --- a/src/proto_alpha/lib_protocol/main.ml +++ b/src/proto_alpha/lib_protocol/main.ml @@ -92,19 +92,16 @@ type validation_mode = | Application of { block_header : Alpha_context.Block_header.t; baker : Alpha_context.public_key_hash; - block_delay : Alpha_context.Period.t; } | Partial_application of { block_header : Alpha_context.Block_header.t; baker : Alpha_context.public_key_hash; - block_delay : Alpha_context.Period.t; } | Partial_construction of {predecessor : Block_hash.t} | Full_construction of { predecessor : Block_hash.t; protocol_data : Alpha_context.Block_header.contents; baker : Alpha_context.public_key_hash; - block_delay : Alpha_context.Period.t; } type validation_state = { @@ -126,10 +123,9 @@ let begin_partial_application ~chain_id ~ancestor_context:ctxt Alpha_context.prepare ~level ~predecessor_timestamp ~timestamp ~fitness ctxt >>=? fun (ctxt, migration_balance_updates) -> Apply.begin_application ctxt chain_id block_header predecessor_timestamp - >|=? fun (ctxt, baker, block_delay) -> + >|=? fun (ctxt, baker) -> let mode = - Partial_application - {block_header; baker = Signature.Public_key.hash baker; block_delay} + Partial_application {block_header; baker = Signature.Public_key.hash baker} in {mode; chain_id; ctxt; op_count = 0; migration_balance_updates} @@ -142,10 +138,9 @@ let begin_application ~chain_id ~predecessor_context:ctxt Alpha_context.prepare ~level ~predecessor_timestamp ~timestamp ~fitness ctxt >>=? fun (ctxt, migration_balance_updates) -> Apply.begin_application ctxt chain_id block_header predecessor_timestamp - >|=? fun (ctxt, baker, block_delay) -> + >|=? fun (ctxt, baker) -> let mode = - Application - {block_header; baker = Signature.Public_key.hash baker; block_delay} + Application {block_header; baker = Signature.Public_key.hash baker} in {mode; chain_id; ctxt; op_count = 0; migration_balance_updates} @@ -168,10 +163,10 @@ let begin_construction ~chain_id ~predecessor_context:ctxt ctxt predecessor_timestamp proto_header.contents - >|=? fun (ctxt, protocol_data, baker, block_delay) -> + >|=? fun (ctxt, protocol_data, baker) -> let mode = let baker = Signature.Public_key.hash baker in - Full_construction {predecessor; baker; protocol_data; block_delay} + Full_construction {predecessor; baker; protocol_data} in (mode, ctxt) ) >|=? fun (mode, ctxt) -> @@ -248,13 +243,12 @@ let finalize_block {mode; ctxt; op_count; migration_balance_updates} = deactivated = []; balance_updates = migration_balance_updates; } ) - | Partial_application {block_header; baker; block_delay} -> + | Partial_application {block_header; baker} -> let included_endorsements = Alpha_context.included_endorsements ctxt in - Apply.check_minimum_endorsements + Apply.check_minimal_valid_time ctxt - block_header.protocol_data.contents - block_delay - included_endorsements + ~priority:block_header.protocol_data.contents.priority + ~endorsing_power:included_endorsements >>?= fun () -> Alpha_context.Voting_period.get_current_info ctxt >>=? fun {voting_period = {kind; _}; _} -> @@ -280,15 +274,12 @@ let finalize_block {mode; ctxt; op_count; migration_balance_updates} = balance_updates = migration_balance_updates; } ) | Application - { baker; - block_delay; - block_header = {protocol_data = {contents = protocol_data; _}; _} } - | Full_construction {protocol_data; baker; block_delay; _} -> + {baker; block_header = {protocol_data = {contents = protocol_data; _}; _}} + | Full_construction {protocol_data; baker; _} -> Apply.finalize_application ctxt protocol_data baker - ~block_delay migration_balance_updates >|=? fun (ctxt, receipt) -> let level = Alpha_context.Level.current ctxt in diff --git a/src/proto_alpha/lib_protocol/main.mli b/src/proto_alpha/lib_protocol/main.mli index 2128db498b606ca30cc935460250224df5823a25..82c2d70fde4ae29191c22867143abf5af103f0b7 100644 --- a/src/proto_alpha/lib_protocol/main.mli +++ b/src/proto_alpha/lib_protocol/main.mli @@ -29,19 +29,16 @@ type validation_mode = | Application of { block_header : Alpha_context.Block_header.t; baker : Alpha_context.public_key_hash; - block_delay : Alpha_context.Period.t; } | Partial_application of { block_header : Alpha_context.Block_header.t; baker : Alpha_context.public_key_hash; - block_delay : Alpha_context.Period.t; } | Partial_construction of {predecessor : Block_hash.t} | Full_construction of { predecessor : Block_hash.t; protocol_data : Alpha_context.Block_header.contents; baker : Alpha_context.public_key_hash; - block_delay : Alpha_context.Period.t; } type validation_state = { diff --git a/src/proto_alpha/lib_protocol/parameters_repr.ml b/src/proto_alpha/lib_protocol/parameters_repr.ml index d5869c641c12dbf0776ad999c556f89649045dd7..6a65a19a81fc501d9605a1ca57328816eec2a14b 100644 --- a/src/proto_alpha/lib_protocol/parameters_repr.ml +++ b/src/proto_alpha/lib_protocol/parameters_repr.ml @@ -125,3 +125,5 @@ let encoding = (opt "security_deposit_ramp_up_cycles" int31) (opt "no_reward_cycles" int31)) Constants_repr.parametric_encoding) + +let check_params params = Constants_repr.check_constants params.constants diff --git a/src/proto_alpha/lib_protocol/parameters_repr.mli b/src/proto_alpha/lib_protocol/parameters_repr.mli index 6f8436e719b916ed3050d6f86b4c939adc2ec7bd..6aca0f7561e806ba5dd86d9c7f582b9661fe7a0a 100644 --- a/src/proto_alpha/lib_protocol/parameters_repr.mli +++ b/src/proto_alpha/lib_protocol/parameters_repr.mli @@ -45,3 +45,5 @@ type t = { } val encoding : t Data_encoding.t + +val check_params : t -> unit tzresult diff --git a/src/proto_alpha/lib_protocol/period_repr.ml b/src/proto_alpha/lib_protocol/period_repr.ml index 2bd3e643b8cec528ada0c1d21b2501e411d25e72..75a01556ad4dcd0c9e331f8cce89dbb71d570bbe 100644 --- a/src/proto_alpha/lib_protocol/period_repr.ml +++ b/src/proto_alpha/lib_protocol/period_repr.ml @@ -23,20 +23,8 @@ (* *) (*****************************************************************************) -type t = Int64.t - -type period = t - -include (Compare.Int64 : Compare.S with type t := t) - -let encoding = Data_encoding.int64 - -let rpc_arg = RPC_arg.int64 - -let pp ppf v = Format.fprintf ppf "%Ld" v - -type error += (* `Permanent *) - Malformed_period | Invalid_arg +(* `Permanent *) +type error += Malformed_period | Invalid_arg | Period_overflow let () = let open Data_encoding in @@ -59,28 +47,117 @@ let () = ~pp:(fun ppf () -> Format.fprintf ppf "Invalid arg") empty (function Invalid_arg -> Some () | _ -> None) - (fun () -> Invalid_arg) + (fun () -> Invalid_arg) ; + let title = "Period overflow" in + register_error_kind + `Permanent + ~id:"period_overflow" + ~title + ~description:"Last operation generated an integer overflow." + ~pp:(fun ppf () -> Format.fprintf ppf "%s" title) + empty + (function Period_overflow -> Some () | _ -> None) + (fun () -> Period_overflow) + +(* Internal module implementing natural numbers using int64. These are different + from usual (wrapping up) unsigned integers in that if one overflows the + representation bounds for int64 through [add] or [mul], a [None] value is + returned *) +module Internal : sig + type t = private int64 + + val create : int64 -> t option + + val zero : t + + val one : t + + val mul : t -> t -> t option + + val add : t -> t -> t option + + val encoding : t Data_encoding.t + + val rpc_arg : t RPC_arg.arg -let of_seconds t = - if Compare.Int64.(t >= 0L) then ok t else error Malformed_period + val pp : Format.formatter -> t -> unit -let to_seconds t = t + include Compare.S with type t := t +end = struct + type t = Int64.t + + let encoding = Data_encoding.int64 + + let rpc_arg = RPC_arg.int64 + + let pp ppf v = Format.fprintf ppf "%Ld" v + + include (Compare.Int64 : Compare.S with type t := t) + + let zero = 0L + + let one = 1L + + let create t = if t >= zero then Some t else None + + (* The create function is not used in the [mul] and [add] below to not add + extra Some | None pattern matching to handle since the overflow checks are + generic and apply as well to negative as positive integers . + + To handle overflows, both [add] and [mul] return option types. [None] is + returned on detected overflow, [Some value] when everything went well. *) + let mul a b = + if a <> zero then + let res = Int64.mul a b in + if Int64.div res a <> b then None else Some res + else Some zero + + let add a b = + let res = Int64.add a b in + if res < a || res < b then None else Some res +end + +include Internal + +type period = Internal.t + +let to_seconds (t : Internal.t) = (t :> int64) + +let of_seconds secs = + match Internal.create secs with + | Some v -> + ok v + | None -> + error Malformed_period let of_seconds_exn t = - match of_seconds t with - | Ok t -> + match Internal.create t with + | Some t -> t - | _ -> + | None -> invalid_arg "Period.of_seconds_exn" let mult i p = - (* TODO check overflow *) - if Compare.Int32.(i < 0l) then error Invalid_arg - else ok (Int64.mul (Int64.of_int32 i) p) - -let zero = of_seconds_exn 0L - -let one_second = of_seconds_exn 1L + match Internal.create (Int64.of_int32 i) with + | None -> + error Invalid_arg + | Some iper -> ( + match Internal.mul iper p with + | None -> + error Period_overflow + | Some res -> + ok res ) + +let add p1 p2 = + match Internal.add p1 p2 with + | None -> + error Period_overflow + | Some res -> + ok res + +let ( +? ) = add + +let one_second = Internal.one let one_minute = of_seconds_exn 60L diff --git a/src/proto_alpha/lib_protocol/period_repr.mli b/src/proto_alpha/lib_protocol/period_repr.mli index 4fbd52db4507b555c498d13e82199923a0cd8d74..60c11fe3e59e4b4297aac6576d60f83733a44b7c 100644 --- a/src/proto_alpha/lib_protocol/period_repr.mli +++ b/src/proto_alpha/lib_protocol/period_repr.mli @@ -25,6 +25,7 @@ type t +(** A [period] is a non-negative integer. *) type period = t include Compare.S with type t := t @@ -44,6 +45,10 @@ val of_seconds : int64 -> period tzresult It should only be used at toplevel for constants. *) val of_seconds_exn : int64 -> period +val add : period -> period -> period tzresult + +val ( +? ) : period -> period -> period tzresult + val mult : int32 -> period -> period tzresult val zero : period @@ -53,3 +58,8 @@ val one_second : period val one_minute : period val one_hour : period + +(** [compare x y] returns [0] if [x] is equal to [y], a negative + integer if [x] is shorter than [y], and a positive integer if [x] + is longer than [y]. *) +val compare : period -> period -> int diff --git a/src/proto_alpha/lib_protocol/raw_context.ml b/src/proto_alpha/lib_protocol/raw_context.ml index e28fb8bb8f817f21074686b1e513acd6689be030..8b4471dfa0ff261716cf62773e651db370d708fb 100644 --- a/src/proto_alpha/lib_protocol/raw_context.ml +++ b/src/proto_alpha/lib_protocol/raw_context.ml @@ -668,7 +668,8 @@ let get_proto_param ctxt = Data_encoding.Json.pp json | param -> - ok (param, ctxt) ) ) + Parameters_repr.check_params param >>? fun () -> ok (param, ctxt) ) + ) let add_constants ctxt constants = let bytes = @@ -775,6 +776,25 @@ let check_and_update_protocol_version ctxt = Context.add ctxt version_key (Bytes.of_string version_value) >|= fun ctxt -> ok (previous_proto, ctxt) +(* only for the migration *) +let get_previous_protocol_constants ctxt = + Context.find ctxt constants_key + >>= function + | None -> + failwith + "Internal error: cannot read previous protocol constants in context." + | Some bytes -> ( + match + Data_encoding.Binary.of_bytes + Constants_repr.Proto_previous.parametric_encoding + bytes + with + | None -> + failwith + "Internal error: cannot parse previous protocol constants in context." + | Some constants -> + Lwt.return constants ) + (* You should ensure that if the type `Constant_repr.parametric` is different from the previous protocol or the value of these constants is modified, is changed from the previous protocol, then @@ -796,7 +816,60 @@ let prepare_first_block ~level ~timestamp ~fitness ctxt = set_first_level ctxt first_level >>=? fun ctxt -> add_constants ctxt param.constants >|= ok | Edo_008 -> - return ctxt ) + get_previous_protocol_constants ctxt + >>= fun c -> + let time_between_blocks_at_first_priority = + ( match c.time_between_blocks with + | [] -> + Period_repr.one_minute + | first_time_between_blocks :: _ -> + first_time_between_blocks ) + |> Period_repr.to_seconds + in + let mainnet_constants = Compare.Int.(c.initial_endorsers = 24) in + let constants = + Constants_repr. + { + minimal_block_delay = + Period_repr.of_seconds_exn + ( if Compare.Int64.(time_between_blocks_at_first_priority = 1L) + then 1L + else (Int64.div time_between_blocks_at_first_priority) 2L ); + preserved_cycles = c.preserved_cycles; + blocks_per_cycle = c.blocks_per_cycle; + blocks_per_commitment = c.blocks_per_commitment; + blocks_per_roll_snapshot = c.blocks_per_roll_snapshot; + blocks_per_voting_period = c.blocks_per_voting_period; + time_between_blocks = c.time_between_blocks; + endorsers_per_block = 256; + hard_gas_limit_per_operation = c.hard_gas_limit_per_operation; + hard_gas_limit_per_block = + Gas_limit_repr.Arith.(integral_of_int_exn 5_200_000); + proof_of_work_threshold = c.proof_of_work_threshold; + tokens_per_roll = c.tokens_per_roll; + michelson_maximum_type_size = c.michelson_maximum_type_size; + seed_nonce_revelation_tip = c.seed_nonce_revelation_tip; + origination_size = c.origination_size; + block_security_deposit = Tez_repr.(mul_exn one 640); + endorsement_security_deposit = Tez_repr.(mul_exn one_cent 250); + baking_reward_per_endorsement = + Tez_repr.[of_mutez_exn 78_125L; of_mutez_exn 11_719L]; + endorsement_reward = + Tez_repr.[of_mutez_exn 78_125L; of_mutez_exn 52_083L]; + hard_storage_limit_per_operation = + c.hard_storage_limit_per_operation; + cost_per_byte = c.cost_per_byte; + quorum_min = c.quorum_min; + quorum_max = c.quorum_max; + min_proposal_quorum = c.min_proposal_quorum; + initial_endorsers = + (if mainnet_constants then 192 else c.initial_endorsers); + delay_per_missing_endorsement = + ( if mainnet_constants then Period_repr.of_seconds_exn 4L + else c.delay_per_missing_endorsement ); + } + in + add_constants ctxt constants >|= ok ) >>=? fun ctxt -> prepare ctxt ~level ~predecessor_timestamp:timestamp ~timestamp ~fitness >|=? fun ctxt -> (previous_proto, ctxt) diff --git a/src/proto_alpha/lib_protocol/test/helpers/assert.ml b/src/proto_alpha/lib_protocol/test/helpers/assert.ml index 7ef41cd65766d99ce5a539ee04655d216475f1d6..bca4ae6686a9af15e477d6500f48ff9aa91db025 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/assert.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/assert.ml @@ -67,6 +67,25 @@ let equal_int ~loc (a : int) (b : int) = let not_equal_int ~loc (a : int) (b : int) = not_equal ~loc ( = ) "Integers are equal" Format.pp_print_int a b +(* int64 *) +let equal_int64 ~loc (a : int64) (b : int64) = + equal + ~loc + ( = ) + "Integers aren't equal" + Format.pp_print_string + (Int64.to_string a) + (Int64.to_string b) + +let not_equal_int64 ~loc (a : int64) (b : int64) = + not_equal + ~loc + ( = ) + "Integers are equal" + Format.pp_print_string + (Int64.to_string a) + (Int64.to_string b) + (* bool *) let equal_bool ~loc (a : bool) (b : bool) = equal ~loc ( = ) "Booleans aren't equal" Format.pp_print_bool a b diff --git a/src/proto_alpha/lib_protocol/test/helpers/block.ml b/src/proto_alpha/lib_protocol/test/helpers/block.ml index 6ee67bad2100a8e7d7b7b700d9f5919b097fe1de..07fbec41438f4e441dad2f6b89e956799f1300d4 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/block.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/block.ml @@ -244,6 +244,30 @@ let check_constants_consistency constants = failwith "Inconsistent constants : blocks per cycle must be superior than \ blocks per roll snapshot") + >>=? fun () -> + let min_time_between_blocks = + match constants.time_between_blocks with + | first_time_between_blocks :: _ -> + first_time_between_blocks + | [] -> + (* this constant is used in the Baking module *) + Period.one_minute + in + Error_monad.unless + Compare.Int64.( + Period.to_seconds min_time_between_blocks + >= Period.to_seconds constants.minimal_block_delay) + (fun () -> + failwith + "minimal_block_delay value (%Ld) should be smaller than \ + time_between_blocks[0] value (%Ld)" + (Period.to_seconds constants.minimal_block_delay) + (Period.to_seconds min_time_between_blocks)) + >>=? fun () -> + Error_monad.unless + Compare.Int.(constants.endorsers_per_block >= constants.initial_endorsers) + (fun () -> + failwith "initial_endorsers should be smaller than endorsers_per_block") let initial_context ?(with_commitments = false) constants header initial_accounts = @@ -308,7 +332,9 @@ let genesis_with_parameters parameters = (* if no parameter file is passed we check in the current directory where the test is run *) let genesis ?with_commitments ?endorsers_per_block ?initial_endorsers - ?min_proposal_quorum (initial_accounts : (Account.t * Tez.t) list) = + ?min_proposal_quorum ?time_between_blocks ?minimal_block_delay + ?delay_per_missing_endorsement + (initial_accounts : (Account.t * Tez.t) list) = if initial_accounts = [] then Stdlib.failwith "Must have one account with a roll to bake" ; let open Tezos_protocol_alpha_parameters in @@ -322,12 +348,26 @@ let genesis ?with_commitments ?endorsers_per_block ?initial_endorsers let min_proposal_quorum = Option.value ~default:constants.min_proposal_quorum min_proposal_quorum in + let time_between_blocks = + Option.value ~default:constants.time_between_blocks time_between_blocks + in + let minimal_block_delay = + Option.value ~default:constants.minimal_block_delay minimal_block_delay + in + let delay_per_missing_endorsement = + Option.value + ~default:constants.delay_per_missing_endorsement + delay_per_missing_endorsement + in let constants = { constants with endorsers_per_block; initial_endorsers; min_proposal_quorum; + time_between_blocks; + minimal_block_delay; + delay_per_missing_endorsement; } in (* Check there is at least one roll *) diff --git a/src/proto_alpha/lib_protocol/test/helpers/block.mli b/src/proto_alpha/lib_protocol/test/helpers/block.mli index 7d327b3fdf99544d227001c18d150ac74a6e9a4b..41225dff2c08a6e4a59a9f4b8dfac59890dc8cc1 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/block.mli +++ b/src/proto_alpha/lib_protocol/test/helpers/block.mli @@ -87,6 +87,8 @@ module Forge : sig val sign_header : header -> Block_header.block_header tzresult Lwt.t end +val check_constants_consistency : Constants.parametric -> unit tzresult Lwt.t + (** [genesis accounts] : generates an initial block with the given constants [] and initializes [accounts] with their associated amounts. @@ -96,6 +98,9 @@ val genesis : ?endorsers_per_block:int -> ?initial_endorsers:int -> ?min_proposal_quorum:int32 -> + ?time_between_blocks:Period.t list -> + ?minimal_block_delay:Period.t -> + ?delay_per_missing_endorsement:Period.t -> (Account.t * Tez.tez) list -> block tzresult Lwt.t diff --git a/src/proto_alpha/lib_protocol/test/helpers/context.ml b/src/proto_alpha/lib_protocol/test/helpers/context.ml index 7b18159b68a34d679be02299be7914a46c4ffb20..2894752c9afd0eb6818300293e52e1deaaf6fdc9 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/context.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/context.ml @@ -293,7 +293,8 @@ module Delegate = struct end let init ?endorsers_per_block ?with_commitments ?(initial_balances = []) - ?initial_endorsers ?min_proposal_quorum n = + ?initial_endorsers ?min_proposal_quorum ?time_between_blocks + ?minimal_block_delay ?delay_per_missing_endorsement n = let accounts = Account.generate_accounts ~initial_balances n in let contracts = List.map @@ -305,5 +306,8 @@ let init ?endorsers_per_block ?with_commitments ?(initial_balances = []) ?with_commitments ?initial_endorsers ?min_proposal_quorum + ?time_between_blocks + ?minimal_block_delay + ?delay_per_missing_endorsement accounts >|=? fun blk -> (blk, contracts) diff --git a/src/proto_alpha/lib_protocol/test/helpers/context.mli b/src/proto_alpha/lib_protocol/test/helpers/context.mli index 1a21dcd7cc92cd9a1b7b9cf050474f476d85c300..e03c434d12bc89df37fa17cfa8e7f655f22583d3 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/context.mli +++ b/src/proto_alpha/lib_protocol/test/helpers/context.mli @@ -134,5 +134,8 @@ val init : ?initial_balances:int64 list -> ?initial_endorsers:int -> ?min_proposal_quorum:int32 -> + ?time_between_blocks:Period.t list -> + ?minimal_block_delay:Period.t -> + ?delay_per_missing_endorsement:Period.t -> int -> (Block.t * Alpha_context.Contract.t list) tzresult Lwt.t diff --git a/src/proto_alpha/lib_protocol/test/helpers/rewards.ml b/src/proto_alpha/lib_protocol/test/helpers/rewards.ml index 55fab74541c79fe9b10adf33621a9397fc10be60..de2536e0e9db57152b63355290dbc4c2ac9598bc 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/rewards.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/rewards.ml @@ -1,7 +1,7 @@ (*****************************************************************************) (* *) (* Open Source License *) -(* Copyright (c) 2019 Nomadic Labs, *) +(* Copyright (c) 2019--2021 Nomadic Labs, *) (* Copyright (c) 2019 Cryptium Labs *) (* *) (* Permission is hereby granted, free of charge, to any person obtaining a *) @@ -26,11 +26,11 @@ (** The tables are precomputed using this the following formulas: -let max_endos = 32 -let max_reward = 80 +let max_endos = 256 +let max_reward = 40 let r = 0.5 -let a = 6. +let a = 3. let b = 1.5 let ( -- ) i j = List.init (j - i + 1) (fun x -> x + i) @@ -43,12 +43,12 @@ let baking_rewards = else a in - let r = r_aux *. (float_of_int e) /. (float_of_int max_endos) in + let r = r_aux /. (float_of_int max_endos) in let r = 1_000_000. *. r in - Float.to_int (floor r) in + Float.to_int ((float_of_int e) *. (ceil r)) in let ps = 0 -- 2 in - let es = 0 -- 32 in + let es = 0 -- max_endos in List.map (fun p -> List.map (fun e -> @@ -68,7 +68,7 @@ let endorsing_rewards = Float.to_int ((float_of_int e) *. (floor r)) in let ps = 0 -- 2 in - let es = 0 -- 32 in + let es = 0 -- max_endos in List.map (fun p -> List.map (fun e -> @@ -80,202 +80,1546 @@ let endorsing_rewards = let baking_rewards : int array array = [| [| 0; + 78125; + 156250; + 234375; + 312500; + 390625; + 468750; + 546875; + 625000; + 703125; + 781250; + 859375; + 937500; + 1015625; + 1093750; + 1171875; 1250000; + 1328125; + 1406250; + 1484375; + 1562500; + 1640625; + 1718750; + 1796875; + 1875000; + 1953125; + 2031250; + 2109375; + 2187500; + 2265625; + 2343750; + 2421875; 2500000; + 2578125; + 2656250; + 2734375; + 2812500; + 2890625; + 2968750; + 3046875; + 3125000; + 3203125; + 3281250; + 3359375; + 3437500; + 3515625; + 3593750; + 3671875; 3750000; + 3828125; + 3906250; + 3984375; + 4062500; + 4140625; + 4218750; + 4296875; + 4375000; + 4453125; + 4531250; + 4609375; + 4687500; + 4765625; + 4843750; + 4921875; 5000000; + 5078125; + 5156250; + 5234375; + 5312500; + 5390625; + 5468750; + 5546875; + 5625000; + 5703125; + 5781250; + 5859375; + 5937500; + 6015625; + 6093750; + 6171875; 6250000; + 6328125; + 6406250; + 6484375; + 6562500; + 6640625; + 6718750; + 6796875; + 6875000; + 6953125; + 7031250; + 7109375; + 7187500; + 7265625; + 7343750; + 7421875; 7500000; + 7578125; + 7656250; + 7734375; + 7812500; + 7890625; + 7968750; + 8046875; + 8125000; + 8203125; + 8281250; + 8359375; + 8437500; + 8515625; + 8593750; + 8671875; 8750000; + 8828125; + 8906250; + 8984375; + 9062500; + 9140625; + 9218750; + 9296875; + 9375000; + 9453125; + 9531250; + 9609375; + 9687500; + 9765625; + 9843750; + 9921875; 10000000; + 10078125; + 10156250; + 10234375; + 10312500; + 10390625; + 10468750; + 10546875; + 10625000; + 10703125; + 10781250; + 10859375; + 10937500; + 11015625; + 11093750; + 11171875; 11250000; + 11328125; + 11406250; + 11484375; + 11562500; + 11640625; + 11718750; + 11796875; + 11875000; + 11953125; + 12031250; + 12109375; + 12187500; + 12265625; + 12343750; + 12421875; 12500000; + 12578125; + 12656250; + 12734375; + 12812500; + 12890625; + 12968750; + 13046875; + 13125000; + 13203125; + 13281250; + 13359375; + 13437500; + 13515625; + 13593750; + 13671875; 13750000; + 13828125; + 13906250; + 13984375; + 14062500; + 14140625; + 14218750; + 14296875; + 14375000; + 14453125; + 14531250; + 14609375; + 14687500; + 14765625; + 14843750; + 14921875; 15000000; + 15078125; + 15156250; + 15234375; + 15312500; + 15390625; + 15468750; + 15546875; + 15625000; + 15703125; + 15781250; + 15859375; + 15937500; + 16015625; + 16093750; + 16171875; 16250000; + 16328125; + 16406250; + 16484375; + 16562500; + 16640625; + 16718750; + 16796875; + 16875000; + 16953125; + 17031250; + 17109375; + 17187500; + 17265625; + 17343750; + 17421875; 17500000; + 17578125; + 17656250; + 17734375; + 17812500; + 17890625; + 17968750; + 18046875; + 18125000; + 18203125; + 18281250; + 18359375; + 18437500; + 18515625; + 18593750; + 18671875; 18750000; - 20000000; - 21250000; - 22500000; - 23750000; - 25000000; - 26250000; - 27500000; - 28750000; - 30000000; - 31250000; - 32500000; - 33750000; - 35000000; - 36250000; - 37500000; - 38750000; - 40000000 |]; + 18828125; + 18906250; + 18984375; + 19062500; + 19140625; + 19218750; + 19296875; + 19375000; + 19453125; + 19531250; + 19609375; + 19687500; + 19765625; + 19843750; + 19921875; + 20000000 |]; [| 0; - 187500; - 375000; - 562500; - 750000; - 937500; - 1125000; - 1312500; - 1500000; - 1687500; - 1875000; - 2062500; - 2250000; - 2437500; - 2625000; - 2812500; - 3000000; - 3187500; - 3375000; - 3562500; - 3750000; - 3937500; - 4125000; - 4312500; - 4500000; - 4687500; - 4875000; - 5062500; - 5250000; - 5437500; - 5625000; - 5812500; - 6000000 |]; + 11719; + 23438; + 35157; + 46876; + 58595; + 70314; + 82033; + 93752; + 105471; + 117190; + 128909; + 140628; + 152347; + 164066; + 175785; + 187504; + 199223; + 210942; + 222661; + 234380; + 246099; + 257818; + 269537; + 281256; + 292975; + 304694; + 316413; + 328132; + 339851; + 351570; + 363289; + 375008; + 386727; + 398446; + 410165; + 421884; + 433603; + 445322; + 457041; + 468760; + 480479; + 492198; + 503917; + 515636; + 527355; + 539074; + 550793; + 562512; + 574231; + 585950; + 597669; + 609388; + 621107; + 632826; + 644545; + 656264; + 667983; + 679702; + 691421; + 703140; + 714859; + 726578; + 738297; + 750016; + 761735; + 773454; + 785173; + 796892; + 808611; + 820330; + 832049; + 843768; + 855487; + 867206; + 878925; + 890644; + 902363; + 914082; + 925801; + 937520; + 949239; + 960958; + 972677; + 984396; + 996115; + 1007834; + 1019553; + 1031272; + 1042991; + 1054710; + 1066429; + 1078148; + 1089867; + 1101586; + 1113305; + 1125024; + 1136743; + 1148462; + 1160181; + 1171900; + 1183619; + 1195338; + 1207057; + 1218776; + 1230495; + 1242214; + 1253933; + 1265652; + 1277371; + 1289090; + 1300809; + 1312528; + 1324247; + 1335966; + 1347685; + 1359404; + 1371123; + 1382842; + 1394561; + 1406280; + 1417999; + 1429718; + 1441437; + 1453156; + 1464875; + 1476594; + 1488313; + 1500032; + 1511751; + 1523470; + 1535189; + 1546908; + 1558627; + 1570346; + 1582065; + 1593784; + 1605503; + 1617222; + 1628941; + 1640660; + 1652379; + 1664098; + 1675817; + 1687536; + 1699255; + 1710974; + 1722693; + 1734412; + 1746131; + 1757850; + 1769569; + 1781288; + 1793007; + 1804726; + 1816445; + 1828164; + 1839883; + 1851602; + 1863321; + 1875040; + 1886759; + 1898478; + 1910197; + 1921916; + 1933635; + 1945354; + 1957073; + 1968792; + 1980511; + 1992230; + 2003949; + 2015668; + 2027387; + 2039106; + 2050825; + 2062544; + 2074263; + 2085982; + 2097701; + 2109420; + 2121139; + 2132858; + 2144577; + 2156296; + 2168015; + 2179734; + 2191453; + 2203172; + 2214891; + 2226610; + 2238329; + 2250048; + 2261767; + 2273486; + 2285205; + 2296924; + 2308643; + 2320362; + 2332081; + 2343800; + 2355519; + 2367238; + 2378957; + 2390676; + 2402395; + 2414114; + 2425833; + 2437552; + 2449271; + 2460990; + 2472709; + 2484428; + 2496147; + 2507866; + 2519585; + 2531304; + 2543023; + 2554742; + 2566461; + 2578180; + 2589899; + 2601618; + 2613337; + 2625056; + 2636775; + 2648494; + 2660213; + 2671932; + 2683651; + 2695370; + 2707089; + 2718808; + 2730527; + 2742246; + 2753965; + 2765684; + 2777403; + 2789122; + 2800841; + 2812560; + 2824279; + 2835998; + 2847717; + 2859436; + 2871155; + 2882874; + 2894593; + 2906312; + 2918031; + 2929750; + 2941469; + 2953188; + 2964907; + 2976626; + 2988345; + 3000064 |]; [| 0; - 187500; - 375000; - 562500; - 750000; - 937500; - 1125000; - 1312500; - 1500000; - 1687500; - 1875000; - 2062500; - 2250000; - 2437500; - 2625000; - 2812500; - 3000000; - 3187500; - 3375000; - 3562500; - 3750000; - 3937500; - 4125000; - 4312500; - 4500000; - 4687500; - 4875000; - 5062500; - 5250000; - 5437500; - 5625000; - 5812500; - 6000000 |] |] + 11719; + 23438; + 35157; + 46876; + 58595; + 70314; + 82033; + 93752; + 105471; + 117190; + 128909; + 140628; + 152347; + 164066; + 175785; + 187504; + 199223; + 210942; + 222661; + 234380; + 246099; + 257818; + 269537; + 281256; + 292975; + 304694; + 316413; + 328132; + 339851; + 351570; + 363289; + 375008; + 386727; + 398446; + 410165; + 421884; + 433603; + 445322; + 457041; + 468760; + 480479; + 492198; + 503917; + 515636; + 527355; + 539074; + 550793; + 562512; + 574231; + 585950; + 597669; + 609388; + 621107; + 632826; + 644545; + 656264; + 667983; + 679702; + 691421; + 703140; + 714859; + 726578; + 738297; + 750016; + 761735; + 773454; + 785173; + 796892; + 808611; + 820330; + 832049; + 843768; + 855487; + 867206; + 878925; + 890644; + 902363; + 914082; + 925801; + 937520; + 949239; + 960958; + 972677; + 984396; + 996115; + 1007834; + 1019553; + 1031272; + 1042991; + 1054710; + 1066429; + 1078148; + 1089867; + 1101586; + 1113305; + 1125024; + 1136743; + 1148462; + 1160181; + 1171900; + 1183619; + 1195338; + 1207057; + 1218776; + 1230495; + 1242214; + 1253933; + 1265652; + 1277371; + 1289090; + 1300809; + 1312528; + 1324247; + 1335966; + 1347685; + 1359404; + 1371123; + 1382842; + 1394561; + 1406280; + 1417999; + 1429718; + 1441437; + 1453156; + 1464875; + 1476594; + 1488313; + 1500032; + 1511751; + 1523470; + 1535189; + 1546908; + 1558627; + 1570346; + 1582065; + 1593784; + 1605503; + 1617222; + 1628941; + 1640660; + 1652379; + 1664098; + 1675817; + 1687536; + 1699255; + 1710974; + 1722693; + 1734412; + 1746131; + 1757850; + 1769569; + 1781288; + 1793007; + 1804726; + 1816445; + 1828164; + 1839883; + 1851602; + 1863321; + 1875040; + 1886759; + 1898478; + 1910197; + 1921916; + 1933635; + 1945354; + 1957073; + 1968792; + 1980511; + 1992230; + 2003949; + 2015668; + 2027387; + 2039106; + 2050825; + 2062544; + 2074263; + 2085982; + 2097701; + 2109420; + 2121139; + 2132858; + 2144577; + 2156296; + 2168015; + 2179734; + 2191453; + 2203172; + 2214891; + 2226610; + 2238329; + 2250048; + 2261767; + 2273486; + 2285205; + 2296924; + 2308643; + 2320362; + 2332081; + 2343800; + 2355519; + 2367238; + 2378957; + 2390676; + 2402395; + 2414114; + 2425833; + 2437552; + 2449271; + 2460990; + 2472709; + 2484428; + 2496147; + 2507866; + 2519585; + 2531304; + 2543023; + 2554742; + 2566461; + 2578180; + 2589899; + 2601618; + 2613337; + 2625056; + 2636775; + 2648494; + 2660213; + 2671932; + 2683651; + 2695370; + 2707089; + 2718808; + 2730527; + 2742246; + 2753965; + 2765684; + 2777403; + 2789122; + 2800841; + 2812560; + 2824279; + 2835998; + 2847717; + 2859436; + 2871155; + 2882874; + 2894593; + 2906312; + 2918031; + 2929750; + 2941469; + 2953188; + 2964907; + 2976626; + 2988345; + 3000064 |] |] let endorsing_rewards : int array array = [| [| 0; + 78125; + 156250; + 234375; + 312500; + 390625; + 468750; + 546875; + 625000; + 703125; + 781250; + 859375; + 937500; + 1015625; + 1093750; + 1171875; 1250000; + 1328125; + 1406250; + 1484375; + 1562500; + 1640625; + 1718750; + 1796875; + 1875000; + 1953125; + 2031250; + 2109375; + 2187500; + 2265625; + 2343750; + 2421875; 2500000; + 2578125; + 2656250; + 2734375; + 2812500; + 2890625; + 2968750; + 3046875; + 3125000; + 3203125; + 3281250; + 3359375; + 3437500; + 3515625; + 3593750; + 3671875; 3750000; + 3828125; + 3906250; + 3984375; + 4062500; + 4140625; + 4218750; + 4296875; + 4375000; + 4453125; + 4531250; + 4609375; + 4687500; + 4765625; + 4843750; + 4921875; 5000000; + 5078125; + 5156250; + 5234375; + 5312500; + 5390625; + 5468750; + 5546875; + 5625000; + 5703125; + 5781250; + 5859375; + 5937500; + 6015625; + 6093750; + 6171875; 6250000; + 6328125; + 6406250; + 6484375; + 6562500; + 6640625; + 6718750; + 6796875; + 6875000; + 6953125; + 7031250; + 7109375; + 7187500; + 7265625; + 7343750; + 7421875; 7500000; + 7578125; + 7656250; + 7734375; + 7812500; + 7890625; + 7968750; + 8046875; + 8125000; + 8203125; + 8281250; + 8359375; + 8437500; + 8515625; + 8593750; + 8671875; 8750000; + 8828125; + 8906250; + 8984375; + 9062500; + 9140625; + 9218750; + 9296875; + 9375000; + 9453125; + 9531250; + 9609375; + 9687500; + 9765625; + 9843750; + 9921875; 10000000; + 10078125; + 10156250; + 10234375; + 10312500; + 10390625; + 10468750; + 10546875; + 10625000; + 10703125; + 10781250; + 10859375; + 10937500; + 11015625; + 11093750; + 11171875; 11250000; + 11328125; + 11406250; + 11484375; + 11562500; + 11640625; + 11718750; + 11796875; + 11875000; + 11953125; + 12031250; + 12109375; + 12187500; + 12265625; + 12343750; + 12421875; 12500000; + 12578125; + 12656250; + 12734375; + 12812500; + 12890625; + 12968750; + 13046875; + 13125000; + 13203125; + 13281250; + 13359375; + 13437500; + 13515625; + 13593750; + 13671875; 13750000; + 13828125; + 13906250; + 13984375; + 14062500; + 14140625; + 14218750; + 14296875; + 14375000; + 14453125; + 14531250; + 14609375; + 14687500; + 14765625; + 14843750; + 14921875; 15000000; + 15078125; + 15156250; + 15234375; + 15312500; + 15390625; + 15468750; + 15546875; + 15625000; + 15703125; + 15781250; + 15859375; + 15937500; + 16015625; + 16093750; + 16171875; 16250000; + 16328125; + 16406250; + 16484375; + 16562500; + 16640625; + 16718750; + 16796875; + 16875000; + 16953125; + 17031250; + 17109375; + 17187500; + 17265625; + 17343750; + 17421875; 17500000; + 17578125; + 17656250; + 17734375; + 17812500; + 17890625; + 17968750; + 18046875; + 18125000; + 18203125; + 18281250; + 18359375; + 18437500; + 18515625; + 18593750; + 18671875; 18750000; - 20000000; - 21250000; - 22500000; - 23750000; - 25000000; - 26250000; - 27500000; - 28750000; - 30000000; - 31250000; - 32500000; - 33750000; - 35000000; - 36250000; - 37500000; - 38750000; - 40000000 |]; + 18828125; + 18906250; + 18984375; + 19062500; + 19140625; + 19218750; + 19296875; + 19375000; + 19453125; + 19531250; + 19609375; + 19687500; + 19765625; + 19843750; + 19921875; + 20000000 |]; [| 0; - 833333; - 1666666; - 2499999; - 3333332; - 4166665; - 4999998; - 5833331; - 6666664; - 7499997; - 8333330; - 9166663; - 9999996; - 10833329; - 11666662; - 12499995; - 13333328; - 14166661; - 14999994; - 15833327; - 16666660; - 17499993; - 18333326; - 19166659; - 19999992; - 20833325; - 21666658; - 22499991; - 23333324; - 24166657; - 24999990; - 25833323; - 26666656 |]; + 52083; + 104166; + 156249; + 208332; + 260415; + 312498; + 364581; + 416664; + 468747; + 520830; + 572913; + 624996; + 677079; + 729162; + 781245; + 833328; + 885411; + 937494; + 989577; + 1041660; + 1093743; + 1145826; + 1197909; + 1249992; + 1302075; + 1354158; + 1406241; + 1458324; + 1510407; + 1562490; + 1614573; + 1666656; + 1718739; + 1770822; + 1822905; + 1874988; + 1927071; + 1979154; + 2031237; + 2083320; + 2135403; + 2187486; + 2239569; + 2291652; + 2343735; + 2395818; + 2447901; + 2499984; + 2552067; + 2604150; + 2656233; + 2708316; + 2760399; + 2812482; + 2864565; + 2916648; + 2968731; + 3020814; + 3072897; + 3124980; + 3177063; + 3229146; + 3281229; + 3333312; + 3385395; + 3437478; + 3489561; + 3541644; + 3593727; + 3645810; + 3697893; + 3749976; + 3802059; + 3854142; + 3906225; + 3958308; + 4010391; + 4062474; + 4114557; + 4166640; + 4218723; + 4270806; + 4322889; + 4374972; + 4427055; + 4479138; + 4531221; + 4583304; + 4635387; + 4687470; + 4739553; + 4791636; + 4843719; + 4895802; + 4947885; + 4999968; + 5052051; + 5104134; + 5156217; + 5208300; + 5260383; + 5312466; + 5364549; + 5416632; + 5468715; + 5520798; + 5572881; + 5624964; + 5677047; + 5729130; + 5781213; + 5833296; + 5885379; + 5937462; + 5989545; + 6041628; + 6093711; + 6145794; + 6197877; + 6249960; + 6302043; + 6354126; + 6406209; + 6458292; + 6510375; + 6562458; + 6614541; + 6666624; + 6718707; + 6770790; + 6822873; + 6874956; + 6927039; + 6979122; + 7031205; + 7083288; + 7135371; + 7187454; + 7239537; + 7291620; + 7343703; + 7395786; + 7447869; + 7499952; + 7552035; + 7604118; + 7656201; + 7708284; + 7760367; + 7812450; + 7864533; + 7916616; + 7968699; + 8020782; + 8072865; + 8124948; + 8177031; + 8229114; + 8281197; + 8333280; + 8385363; + 8437446; + 8489529; + 8541612; + 8593695; + 8645778; + 8697861; + 8749944; + 8802027; + 8854110; + 8906193; + 8958276; + 9010359; + 9062442; + 9114525; + 9166608; + 9218691; + 9270774; + 9322857; + 9374940; + 9427023; + 9479106; + 9531189; + 9583272; + 9635355; + 9687438; + 9739521; + 9791604; + 9843687; + 9895770; + 9947853; + 9999936; + 10052019; + 10104102; + 10156185; + 10208268; + 10260351; + 10312434; + 10364517; + 10416600; + 10468683; + 10520766; + 10572849; + 10624932; + 10677015; + 10729098; + 10781181; + 10833264; + 10885347; + 10937430; + 10989513; + 11041596; + 11093679; + 11145762; + 11197845; + 11249928; + 11302011; + 11354094; + 11406177; + 11458260; + 11510343; + 11562426; + 11614509; + 11666592; + 11718675; + 11770758; + 11822841; + 11874924; + 11927007; + 11979090; + 12031173; + 12083256; + 12135339; + 12187422; + 12239505; + 12291588; + 12343671; + 12395754; + 12447837; + 12499920; + 12552003; + 12604086; + 12656169; + 12708252; + 12760335; + 12812418; + 12864501; + 12916584; + 12968667; + 13020750; + 13072833; + 13124916; + 13176999; + 13229082; + 13281165; + 13333248 |]; [| 0; - 833333; - 1666666; - 2499999; - 3333332; - 4166665; - 4999998; - 5833331; - 6666664; - 7499997; - 8333330; - 9166663; - 9999996; - 10833329; - 11666662; - 12499995; - 13333328; - 14166661; - 14999994; - 15833327; - 16666660; - 17499993; - 18333326; - 19166659; - 19999992; - 20833325; - 21666658; - 22499991; - 23333324; - 24166657; - 24999990; - 25833323; - 26666656 |] |] + 52083; + 104166; + 156249; + 208332; + 260415; + 312498; + 364581; + 416664; + 468747; + 520830; + 572913; + 624996; + 677079; + 729162; + 781245; + 833328; + 885411; + 937494; + 989577; + 1041660; + 1093743; + 1145826; + 1197909; + 1249992; + 1302075; + 1354158; + 1406241; + 1458324; + 1510407; + 1562490; + 1614573; + 1666656; + 1718739; + 1770822; + 1822905; + 1874988; + 1927071; + 1979154; + 2031237; + 2083320; + 2135403; + 2187486; + 2239569; + 2291652; + 2343735; + 2395818; + 2447901; + 2499984; + 2552067; + 2604150; + 2656233; + 2708316; + 2760399; + 2812482; + 2864565; + 2916648; + 2968731; + 3020814; + 3072897; + 3124980; + 3177063; + 3229146; + 3281229; + 3333312; + 3385395; + 3437478; + 3489561; + 3541644; + 3593727; + 3645810; + 3697893; + 3749976; + 3802059; + 3854142; + 3906225; + 3958308; + 4010391; + 4062474; + 4114557; + 4166640; + 4218723; + 4270806; + 4322889; + 4374972; + 4427055; + 4479138; + 4531221; + 4583304; + 4635387; + 4687470; + 4739553; + 4791636; + 4843719; + 4895802; + 4947885; + 4999968; + 5052051; + 5104134; + 5156217; + 5208300; + 5260383; + 5312466; + 5364549; + 5416632; + 5468715; + 5520798; + 5572881; + 5624964; + 5677047; + 5729130; + 5781213; + 5833296; + 5885379; + 5937462; + 5989545; + 6041628; + 6093711; + 6145794; + 6197877; + 6249960; + 6302043; + 6354126; + 6406209; + 6458292; + 6510375; + 6562458; + 6614541; + 6666624; + 6718707; + 6770790; + 6822873; + 6874956; + 6927039; + 6979122; + 7031205; + 7083288; + 7135371; + 7187454; + 7239537; + 7291620; + 7343703; + 7395786; + 7447869; + 7499952; + 7552035; + 7604118; + 7656201; + 7708284; + 7760367; + 7812450; + 7864533; + 7916616; + 7968699; + 8020782; + 8072865; + 8124948; + 8177031; + 8229114; + 8281197; + 8333280; + 8385363; + 8437446; + 8489529; + 8541612; + 8593695; + 8645778; + 8697861; + 8749944; + 8802027; + 8854110; + 8906193; + 8958276; + 9010359; + 9062442; + 9114525; + 9166608; + 9218691; + 9270774; + 9322857; + 9374940; + 9427023; + 9479106; + 9531189; + 9583272; + 9635355; + 9687438; + 9739521; + 9791604; + 9843687; + 9895770; + 9947853; + 9999936; + 10052019; + 10104102; + 10156185; + 10208268; + 10260351; + 10312434; + 10364517; + 10416600; + 10468683; + 10520766; + 10572849; + 10624932; + 10677015; + 10729098; + 10781181; + 10833264; + 10885347; + 10937430; + 10989513; + 11041596; + 11093679; + 11145762; + 11197845; + 11249928; + 11302011; + 11354094; + 11406177; + 11458260; + 11510343; + 11562426; + 11614509; + 11666592; + 11718675; + 11770758; + 11822841; + 11874924; + 11927007; + 11979090; + 12031173; + 12083256; + 12135339; + 12187422; + 12239505; + 12291588; + 12343671; + 12395754; + 12447837; + 12499920; + 12552003; + 12604086; + 12656169; + 12708252; + 12760335; + 12812418; + 12864501; + 12916584; + 12968667; + 13020750; + 13072833; + 13124916; + 13176999; + 13229082; + 13281165; + 13333248 |] |] diff --git a/src/proto_alpha/lib_protocol/test/main.ml b/src/proto_alpha/lib_protocol/test/main.ml index 7f70d29a11b9b8c54b9e6ada7bf6c72fc358b5ac..77b51f58a27a93579a69c728b563bdce0becbdf8 100644 --- a/src/proto_alpha/lib_protocol/test/main.ml +++ b/src/proto_alpha/lib_protocol/test/main.ml @@ -37,6 +37,7 @@ let () = ("origination", Test_origination.tests); ("activation", Test_activation.tests); ("revelation", Test_reveal.tests); + ("baking module", Test_baking_module.tests); ("endorsement", Test_endorsement.tests); ("double endorsement", Test_double_endorsement.tests); ("double baking", Test_double_baking.tests); @@ -59,5 +60,6 @@ let () = ("script deserialize gas", Test_script_gas.tests); ("failing_noop operation", Test_failing_noop.tests); ("storage description", Test_storage.tests); - ("time", Test_time_repr.tests) ] + ("time", Test_time_repr.tests); + ("constants", Test_constants.tests) ] |> Lwt_main.run diff --git a/src/proto_alpha/lib_protocol/test/test_baking.ml b/src/proto_alpha/lib_protocol/test/test_baking.ml index 5daa9183db5144f05c6edb1ecac28a3d8470e4b4..6db5928c7742fd5d47a5f84ebce61b3aae50d675 100644 --- a/src/proto_alpha/lib_protocol/test/test_baking.ml +++ b/src/proto_alpha/lib_protocol/test/test_baking.ml @@ -84,7 +84,9 @@ let test_cycle () = (** After baking and/or endorsing a block, the baker and the endorsers get their reward. *) let test_rewards_retrieval () = - Context.init 256 + let endorsers_per_block = 32 in + (* we want to have sufficient accounts so that find_block succeeds *) + Context.init (endorsers_per_block * 10) ~endorsers_per_block >>=? fun (b, _) -> Context.get_constants (B b) >>=? fun Constants. @@ -94,7 +96,7 @@ let test_rewards_retrieval () = endorsement_security_deposit; _ }; _ } -> - (* find block with 32 different endorsers *) + (* find block with endorsers_per_block different endorsers *) let open Alpha_services.Delegate.Endorsing_rights in let rec find_block b = Context.get_endorsers (B b) @@ -115,7 +117,7 @@ let test_rewards_retrieval () = Context.get_endorsers (B good_b) >>=? fun endorsers -> (* test 3 different priorities, too long otherwise *) - let block_priorities = 0 -- 10 in + let block_priorities = 0 -- 2 in let included_endorsements = 0 -- endorsers_per_block in let ranges = List.product block_priorities included_endorsements in List.iter_es @@ -124,7 +126,10 @@ let test_rewards_retrieval () = let real_endorsers = List.sub endorsers endorsing_power in List.map_ep (fun endorser -> - Op.endorsement ~delegate:endorser.delegate (B good_b) () + Op.endorsement_with_slot + ~delegate:(endorser.delegate, endorser.slots) + (B good_b) + () >|=? fun operation -> Operation.pack operation) real_endorsers >>=? fun operations -> diff --git a/src/proto_alpha/lib_protocol/test/test_baking_module.ml b/src/proto_alpha/lib_protocol/test/test_baking_module.ml new file mode 100644 index 0000000000000000000000000000000000000000..c2480cdf1279aa064a49822fe60738f17081efc5 --- /dev/null +++ b/src/proto_alpha/lib_protocol/test/test_baking_module.ml @@ -0,0 +1,186 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (baking) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^baking module$" + Subject: some functions in the Baking module +*) + +open Protocol +open Alpha_context + +let prepare_context (b : Block.t) = + Alpha_context.prepare + b.context + ~level:b.header.shell.level + ~predecessor_timestamp:b.header.shell.timestamp + ~timestamp:b.header.shell.timestamp + ~fitness:b.header.shell.fitness + >|= (fun e -> Environment.wrap_tzresult e) + >>=? fun (ctxt, _) -> return ctxt + +let minimal_time ~bd ~dp ~md ~p = if p = 0 then md else bd + (p * dp) + +let emmystar_delay ~te ~ie ~md ~bd ~dp ~de ~p ~e = + if p = 0 && e >= 3 * te / 5 then md else bd + (p * dp) + (de * max 0 (ie - e)) + +(* We test with three sets of constants: + - the test constants, which are the default ones in this test framework + - the mainnet constants + - the sandbox constants + For the last two, the values are picked manually, which means these + values may get out of sync with the real values. + (Actually, there are currently only two sets of relevant constants, as + the values of the relevant test and sandbox constants coincide.) *) +let test_minimal_time () = + Context.init 1 + >>=? fun (b, _) -> + Context.get_constants (B b) + >>=? fun constants -> + let bd = + Stdlib.List.hd constants.parametric.time_between_blocks + |> Period.to_seconds |> Int64.to_int + in + let dp = + Stdlib.List.nth constants.parametric.time_between_blocks 1 + |> Period.to_seconds |> Int64.to_int + in + let md = + constants.parametric.minimal_block_delay |> Period.to_seconds + |> Int64.to_int + in + let prio_range = [0; 1; 2; 3] in + let bd_dp_range = [(bd, dp); (60, 40)] in + let md_range = [md; 30] in + let range = + List.product prio_range (Stdlib.List.combine bd_dp_range md_range) + in + List.iter_es + (fun (priority, ((bd, dp), md)) -> + Context.init + ~time_between_blocks: + [ Period.of_seconds_exn (Int64.of_int bd); + Period.of_seconds_exn (Int64.of_int dp) ] + ~minimal_block_delay:(Period.of_seconds_exn (Int64.of_int md)) + 1 + >>=? fun (b, _) -> + Context.get_constants (B b) + >>=? fun constants -> + Baking.minimal_time + constants.parametric + ~priority + b.header.shell.timestamp + |> Environment.wrap_tzresult + >>?= fun ts -> + let expected_ts = + Time.Protocol.add + b.header.shell.timestamp + (Int64.of_int (minimal_time ~bd ~dp ~md ~p:priority)) + in + Assert.equal_int64 + ~loc:__LOC__ + (Time.Protocol.to_seconds ts) + (Time.Protocol.to_seconds expected_ts)) + range + +(* Same comment as for the previous test. *) +let test_minimal_valid_time () = + Context.init 1 + >>=? fun (b, _) -> + Context.get_constants (B b) + >>=? fun constants -> + let md = + constants.parametric.minimal_block_delay |> Period.to_seconds + |> Int64.to_int + in + let bd = + Stdlib.List.nth constants.parametric.time_between_blocks 0 + |> Period.to_seconds |> Int64.to_int + in + let dp = + Stdlib.List.nth constants.parametric.time_between_blocks 1 + |> Period.to_seconds |> Int64.to_int + in + let de = + constants.parametric.delay_per_missing_endorsement |> Period.to_seconds + |> Int64.to_int + in + let te_range = [constants.parametric.endorsers_per_block] in + let ie_range = [constants.parametric.initial_endorsers; 192] in + let md_range = [md; 30] in + let bd_dp_range = [(bd, dp); (60, 40)] in + let de_range = [de; 8] in + let p_range = 0 -- 2 in + let e_range = 0 -- constants.parametric.endorsers_per_block in + let range = + List.product + p_range + (List.product + e_range + (List.product + te_range + (Stdlib.List.combine + ie_range + (Stdlib.List.combine + md_range + (Stdlib.List.combine bd_dp_range de_range))))) + in + List.iter_es + (fun (p, (e, (te, (ie, (md, ((bd, dp), de)))))) -> + Context.init + ~endorsers_per_block:te + ~time_between_blocks: + [ Period.of_seconds_exn (Int64.of_int bd); + Period.of_seconds_exn (Int64.of_int dp) ] + ~minimal_block_delay:(Period.of_seconds_exn (Int64.of_int md)) + ~initial_endorsers:ie + ~delay_per_missing_endorsement: + (Period.of_seconds_exn (Int64.of_int de)) + 1 + >>=? fun (b, _) -> + Context.get_constants (B b) + >>=? fun constants -> + Baking.minimal_valid_time + constants.parametric + ~priority:p + ~endorsing_power:e + ~predecessor_timestamp:b.header.shell.timestamp + |> Environment.wrap_tzresult + >>?= fun timestamp -> + let delay = emmystar_delay ~te ~ie ~md ~bd ~dp ~de ~p ~e in + let expected_timestamp = + Time.Protocol.add b.header.shell.timestamp (Int64.of_int delay) + in + Assert.equal_int64 + ~loc:__LOC__ + (Time.Protocol.to_seconds timestamp) + (Time.Protocol.to_seconds expected_timestamp)) + range + +let tests = + [ Test_services.tztest "minimal time" `Quick test_minimal_time; + Test_services.tztest "minimal valid time" `Quick test_minimal_valid_time ] diff --git a/src/proto_alpha/lib_protocol/test/test_constants.ml b/src/proto_alpha/lib_protocol/test/test_constants.ml new file mode 100644 index 0000000000000000000000000000000000000000..acf31a93be8d603a323db8077a2346ab6dedd778 --- /dev/null +++ b/src/proto_alpha/lib_protocol/test/test_constants.ml @@ -0,0 +1,43 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (baking) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^constants$" + Subject: the consistency of parametric constants +*) + +let test_constants_consistency () = + let open Tezos_protocol_alpha_parameters.Default_parameters in + List.iter_es + Block.check_constants_consistency + [constants_mainnet; constants_sandbox; constants_test] + +let tests = + [ Test_services.tztest + "constants consistency" + `Quick + test_constants_consistency ] diff --git a/src/proto_alpha/lib_protocol/test/test_endorsement.ml b/src/proto_alpha/lib_protocol/test/test_endorsement.ml index 4a7c3b1e63180027d22dc26939434b03f17a3fb5..ba57d3a7c3a549937e1c7c451b4838b59205ce5f 100644 --- a/src/proto_alpha/lib_protocol/test/test_endorsement.ml +++ b/src/proto_alpha/lib_protocol/test/test_endorsement.ml @@ -680,8 +680,7 @@ let test_endorsement_threshold () = b >>= fun b2 -> Assert.proto_error ~loc:__LOC__ b2 (function - | Baking.Timestamp_too_early _ - | Apply.Not_enough_endorsements_for_priority _ -> + | Baking.Timestamp_too_early _ -> true | _ -> false)) diff --git a/src/proto_alpha/lib_protocol/test/test_gas_levels.ml b/src/proto_alpha/lib_protocol/test/test_gas_levels.ml index ea3cd6e9ac85858885d775ccb640171b47960e06..16acfdd7783db253a76fc2c13d3af422634962b2 100644 --- a/src/proto_alpha/lib_protocol/test/test_gas_levels.ml +++ b/src/proto_alpha/lib_protocol/test/test_gas_levels.ml @@ -93,7 +93,7 @@ let monitor initial_operation_level gas_level expectation () = ( match consume_gas context (S.safe_int 10000) (* in milligas. *) with | Ok context -> let remaining = gas_level context in - remaining = integral_of_int_exn expectation + remaining = integral_of_int_exn (expectation context) | _ -> false ) (err "Monitor operation gas at each gas consumption") @@ -109,15 +109,22 @@ let operation_gas_level context = (* Monitoring runs differently depending on the minimum between the operation gas level and the block gas level. Hence, we check that in both situations, the gas levels are correctly reported. *) - -let test_monitor_operation_gas_level = monitor 100 operation_gas_level 90 +let test_monitor_operation_gas_level = + monitor 100 operation_gas_level (fun _ -> 90) let test_monitor_operation_gas_level' = - monitor opg operation_gas_level (opg - 10) + monitor opg operation_gas_level (fun _ -> opg - 10) + +let block_limit ctxt = + let constants = Raw_context.constants ctxt in + let integral_limit = constants.Constants_repr.hard_gas_limit_per_block in + Z.to_int (Gas_limit_repr.Arith.integral_to_z integral_limit) -let test_monitor_block_gas_level = monitor 100 block_gas_level 10399990 +let test_monitor_block_gas_level = + monitor 100 block_gas_level (fun ctxt -> block_limit ctxt - 10) -let test_monitor_block_gas_level' = monitor opg block_gas_level 10399990 +let test_monitor_block_gas_level' = + monitor opg block_gas_level (fun ctxt -> block_limit ctxt - 10) let quick (what, how) = Test_services.tztest what `Quick how diff --git a/tests_python/tests_alpha/test_block_times_ideal_scenario.py b/tests_python/tests_alpha/test_block_times_ideal_scenario.py index 668237aa05fb951897cecbfcc96cffa37cfdb117..f7a3495a3ec12b4df80b93be0768163f298f339e 100644 --- a/tests_python/tests_alpha/test_block_times_ideal_scenario.py +++ b/tests_python/tests_alpha/test_block_times_ideal_scenario.py @@ -25,9 +25,10 @@ class TestBakers: def test_setup_network(self, sandbox: Sandbox): parameters = dict(protocol.PARAMETERS) - parameters["time_between_blocks"] = [str(BD), str(PD)] parameters["initial_endorsers"] = IE + parameters["minimal_block_delay"] = "1" + assert parameters["delay_per_missing_endorsement"] == '1' for i in range(NUM_NODES): sandbox.add_node(i, params=constants.NODE_PARAMS) @@ -68,7 +69,6 @@ class TestBakers: time_diff = (ts2 - ts1).total_seconds() # there will be initial_endorsers missing endorsements # so the block delay is BD + IE * 1 - assert protocol.PARAMETERS["delay_per_missing_endorsement"] == '1' assert time_diff == BD + IE @@ -84,6 +84,7 @@ class TestBakersAndEndorsers: def test_setup_network(self, sandbox: Sandbox): parameters = dict(protocol.PARAMETERS) parameters["time_between_blocks"] = [str(BD), str(PD)] + parameters["minimal_block_delay"] = "1" # we require all endorsements to be present parameters["initial_endorsers"] = parameters["endorsers_per_block"] for i in range(NUM_NODES): @@ -137,4 +138,4 @@ class TestBakersAndEndorsers: ts0 = client.get_block_timestamp(block=str(2)) ts1 = client.get_block_timestamp(block=str(max_level)) time_diff = (ts1 - ts0).total_seconds() - assert time_diff == BD * (max_level - 2) + assert time_diff == (max_level - 2) diff --git a/tests_python/tests_alpha/test_mockup.py b/tests_python/tests_alpha/test_mockup.py index 9b50d7824c0600947e78b7a665cbfccbb49db126..df9cdbeb3a37815b67d02d7988f88e90be8f1d5a 100644 --- a/tests_python/tests_alpha/test_mockup.py +++ b/tests_python/tests_alpha/test_mockup.py @@ -605,6 +605,7 @@ def _test_create_mockup_init_show_roundtrip( "blocks_per_commitment": 5, "blocks_per_cycle": 9, "preserved_cycles": 3, + "minimal_block_delay": "1", } ), ], diff --git a/tezt/_regressions/rpc/alpha.client.others.out b/tezt/_regressions/rpc/alpha.client.others.out index 1f65a7683e540998bb559917f4655c64f7b8b71e..20d0ff73847f20a835498e6fd623e6e3670abea3 100644 --- a/tezt/_regressions/rpc/alpha.client.others.out +++ b/tezt/_regressions/rpc/alpha.client.others.out @@ -6,18 +6,19 @@ tezt/_regressions/rpc/alpha.client.others.out "max_proposals_per_delegate": 20, "preserved_cycles": 2, "blocks_per_cycle": 8, "blocks_per_commitment": 4, "blocks_per_roll_snapshot": 4, "blocks_per_voting_period": 64, - "time_between_blocks": [ "1", "0" ], "endorsers_per_block": 32, + "time_between_blocks": [ "1", "0" ], "endorsers_per_block": 256, "hard_gas_limit_per_operation": "1040000", - "hard_gas_limit_per_block": "10400000", "proof_of_work_threshold": "-1", + "hard_gas_limit_per_block": "5200000", "proof_of_work_threshold": "-1", "tokens_per_roll": "8000000000", "michelson_maximum_type_size": 1000, "seed_nonce_revelation_tip": "125000", "origination_size": 257, - "block_security_deposit": "512000000", - "endorsement_security_deposit": "64000000", - "baking_reward_per_endorsement": [ "1250000", "187500" ], - "endorsement_reward": [ "1250000", "833333" ], "cost_per_byte": "250", + "block_security_deposit": "640000000", + "endorsement_security_deposit": "2500000", + "baking_reward_per_endorsement": [ "78125", "11719" ], + "endorsement_reward": [ "78125", "52083" ], "cost_per_byte": "250", "hard_storage_limit_per_operation": "60000", "test_chain_duration": "0", "quorum_min": 2000, "quorum_max": 7000, "min_proposal_quorum": 500, - "initial_endorsers": 1, "delay_per_missing_endorsement": "1" } + "initial_endorsers": 1, "delay_per_missing_endorsement": "1", + "minimal_block_delay": "1" } ./tezos-client rpc get /chains/main/blocks/head/helpers/baking_rights [ { "level": 2, "delegate": "[PUBLIC_KEY_HASH]", @@ -38,19 +39,37 @@ tezt/_regressions/rpc/alpha.client.others.out ./tezos-client rpc get /chains/main/blocks/head/helpers/endorsing_rights [ { "level": 1, "delegate": "[PUBLIC_KEY_HASH]", - "slots": [ 2, 13, 17, 19, 23, 24, 31 ], + "slots": + [ 2, 13, 17, 19, 23, 24, 31, 34, 40, 46, 48, 53, 56, 60, 61, 62, 68, + 70, 75, 76, 82, 87, 89, 90, 96, 105, 121, 122, 127, 129, 135, 139, + 140, 141, 148, 149, 156, 161, 162, 172, 184, 186, 190, 198, 202, 215, + 225, 229, 230, 232, 237, 238, 239, 244, 247, 252, 253, 255 ], "estimated_time": "[TIMESTAMP]" }, { "level": 1, "delegate": "[PUBLIC_KEY_HASH]", - "slots": [ 0, 4, 6, 11, 15, 20, 22 ], + "slots": + [ 0, 4, 6, 11, 15, 20, 22, 36, 37, 41, 44, 47, 55, 59, 65, 66, 67, 81, + 83, 91, 101, 108, 110, 112, 113, 115, 116, 130, 133, 136, 144, 151, + 154, 167, 177, 183, 185, 187, 201, 203, 206, 207, 209, 212, 219, 226, + 227, 234, 235, 236, 242, 246, 249, 250 ], "estimated_time": "[TIMESTAMP]" }, { "level": 1, "delegate": "[PUBLIC_KEY_HASH]", - "slots": [ 1, 7, 8, 10, 18, 25, 28 ], - "estimated_time": "[TIMESTAMP]" }, + "slots": + [ 1, 7, 8, 10, 18, 25, 28, 35, 39, 42, 43, 45, 54, 63, 69, 72, 92, 93, + 95, 98, 99, 103, 104, 114, 117, 118, 119, 124, 126, 138, 150, 155, + 158, 160, 163, 164, 165, 168, 173, 180, 189, 210, 211, 216, 217, 222, + 223, 233, 243 ], "estimated_time": "[TIMESTAMP]" }, { "level": 1, "delegate": "[PUBLIC_KEY_HASH]", - "slots": [ 3, 5, 12, 16, 27, 30 ], + "slots": + [ 3, 5, 12, 16, 27, 30, 32, 38, 49, 50, 51, 52, 58, 73, 74, 85, 86, 94, + 100, 107, 111, 123, 128, 131, 132, 134, 137, 142, 143, 153, 157, 166, + 169, 170, 175, 178, 181, 182, 194, 195, 196, 204, 205, 208, 213, 214, + 220, 221, 224, 228, 231, 240, 241, 251, 254 ], "estimated_time": "[TIMESTAMP]" }, { "level": 1, "delegate": "[PUBLIC_KEY_HASH]", - "slots": [ 9, 14, 21, 26, 29 ], + "slots": + [ 9, 14, 21, 26, 29, 33, 57, 64, 71, 77, 78, 79, 80, 84, 88, 97, 102, + 106, 109, 120, 125, 145, 146, 147, 152, 159, 171, 174, 176, 179, 188, + 191, 192, 193, 197, 199, 200, 218, 245, 248 ], "estimated_time": "[TIMESTAMP]" } ] ./tezos-client rpc get /chains/main/blocks/head/helpers/levels_in_current_cycle diff --git a/tezt/_regressions/rpc/alpha.proxy.others.out b/tezt/_regressions/rpc/alpha.proxy.others.out index df1fcc9a9b073af7587c2f024ffdab10ddb30a65..78956ef54309efdcf9fc1de2f26b44df8a4e98c5 100644 --- a/tezt/_regressions/rpc/alpha.proxy.others.out +++ b/tezt/_regressions/rpc/alpha.proxy.others.out @@ -7,18 +7,19 @@ protocol of proxy unspecified, using the node's protocol: ProtoGenesisGenesisGen "max_proposals_per_delegate": 20, "preserved_cycles": 2, "blocks_per_cycle": 8, "blocks_per_commitment": 4, "blocks_per_roll_snapshot": 4, "blocks_per_voting_period": 64, - "time_between_blocks": [ "1", "0" ], "endorsers_per_block": 32, + "time_between_blocks": [ "1", "0" ], "endorsers_per_block": 256, "hard_gas_limit_per_operation": "1040000", - "hard_gas_limit_per_block": "10400000", "proof_of_work_threshold": "-1", + "hard_gas_limit_per_block": "5200000", "proof_of_work_threshold": "-1", "tokens_per_roll": "8000000000", "michelson_maximum_type_size": 1000, "seed_nonce_revelation_tip": "125000", "origination_size": 257, - "block_security_deposit": "512000000", - "endorsement_security_deposit": "64000000", - "baking_reward_per_endorsement": [ "1250000", "187500" ], - "endorsement_reward": [ "1250000", "833333" ], "cost_per_byte": "250", + "block_security_deposit": "640000000", + "endorsement_security_deposit": "2500000", + "baking_reward_per_endorsement": [ "78125", "11719" ], + "endorsement_reward": [ "78125", "52083" ], "cost_per_byte": "250", "hard_storage_limit_per_operation": "60000", "test_chain_duration": "0", "quorum_min": 2000, "quorum_max": 7000, "min_proposal_quorum": 500, - "initial_endorsers": 1, "delay_per_missing_endorsement": "1" } + "initial_endorsers": 1, "delay_per_missing_endorsement": "1", + "minimal_block_delay": "1" } ./tezos-client --mode proxy rpc get /chains/main/blocks/head/helpers/baking_rights protocol of proxy unspecified, using the node's protocol: ProtoGenesisGenesisGenesisGenesisGenesisGenesk612im @@ -42,19 +43,37 @@ protocol of proxy unspecified, using the node's protocol: ProtoGenesisGenesisGen ./tezos-client --mode proxy rpc get /chains/main/blocks/head/helpers/endorsing_rights protocol of proxy unspecified, using the node's protocol: ProtoGenesisGenesisGenesisGenesisGenesisGenesk612im [ { "level": 1, "delegate": "[PUBLIC_KEY_HASH]", - "slots": [ 2, 13, 17, 19, 23, 24, 31 ], + "slots": + [ 2, 13, 17, 19, 23, 24, 31, 34, 40, 46, 48, 53, 56, 60, 61, 62, 68, + 70, 75, 76, 82, 87, 89, 90, 96, 105, 121, 122, 127, 129, 135, 139, + 140, 141, 148, 149, 156, 161, 162, 172, 184, 186, 190, 198, 202, 215, + 225, 229, 230, 232, 237, 238, 239, 244, 247, 252, 253, 255 ], "estimated_time": "[TIMESTAMP]" }, { "level": 1, "delegate": "[PUBLIC_KEY_HASH]", - "slots": [ 0, 4, 6, 11, 15, 20, 22 ], + "slots": + [ 0, 4, 6, 11, 15, 20, 22, 36, 37, 41, 44, 47, 55, 59, 65, 66, 67, 81, + 83, 91, 101, 108, 110, 112, 113, 115, 116, 130, 133, 136, 144, 151, + 154, 167, 177, 183, 185, 187, 201, 203, 206, 207, 209, 212, 219, 226, + 227, 234, 235, 236, 242, 246, 249, 250 ], "estimated_time": "[TIMESTAMP]" }, { "level": 1, "delegate": "[PUBLIC_KEY_HASH]", - "slots": [ 1, 7, 8, 10, 18, 25, 28 ], - "estimated_time": "[TIMESTAMP]" }, + "slots": + [ 1, 7, 8, 10, 18, 25, 28, 35, 39, 42, 43, 45, 54, 63, 69, 72, 92, 93, + 95, 98, 99, 103, 104, 114, 117, 118, 119, 124, 126, 138, 150, 155, + 158, 160, 163, 164, 165, 168, 173, 180, 189, 210, 211, 216, 217, 222, + 223, 233, 243 ], "estimated_time": "[TIMESTAMP]" }, { "level": 1, "delegate": "[PUBLIC_KEY_HASH]", - "slots": [ 3, 5, 12, 16, 27, 30 ], + "slots": + [ 3, 5, 12, 16, 27, 30, 32, 38, 49, 50, 51, 52, 58, 73, 74, 85, 86, 94, + 100, 107, 111, 123, 128, 131, 132, 134, 137, 142, 143, 153, 157, 166, + 169, 170, 175, 178, 181, 182, 194, 195, 196, 204, 205, 208, 213, 214, + 220, 221, 224, 228, 231, 240, 241, 251, 254 ], "estimated_time": "[TIMESTAMP]" }, { "level": 1, "delegate": "[PUBLIC_KEY_HASH]", - "slots": [ 9, 14, 21, 26, 29 ], + "slots": + [ 9, 14, 21, 26, 29, 33, 57, 64, 71, 77, 78, 79, 80, 84, 88, 97, 102, + 106, 109, 120, 125, 145, 146, 147, 152, 159, 171, 174, 176, 179, 188, + 191, 192, 193, 197, 199, 200, 218, 245, 248 ], "estimated_time": "[TIMESTAMP]" } ] ./tezos-client --mode proxy rpc get /chains/main/blocks/head/helpers/levels_in_current_cycle diff --git a/vendors/flextesa-lib/tezos_protocol.ml b/vendors/flextesa-lib/tezos_protocol.ml index 0e6195327b5f41a95788cdc2004564455ada03ef..26b860ddd24b7aad4fd2b3b906a1724e8c6a4d1f 100644 --- a/vendors/flextesa-lib/tezos_protocol.ml +++ b/vendors/flextesa-lib/tezos_protocol.ml @@ -74,11 +74,17 @@ module Voting_period = struct end module Protocol_kind = struct - type t = [`Athens | `Babylon | `Carthage | `Delphi | `Edo | `Florence | `Alpha] + type t = + [`Athens | `Babylon | `Carthage | `Delphi | `Edo | `Florence | `Alpha] let names = - [ ("Athens", `Athens); ("Babylon", `Babylon); ("Carthage", `Carthage) - ; ("Delphi", `Delphi); ("Edo", `Edo); ("Florence", `Florence); ("Alpha", `Alpha) ] + [ ("Athens", `Athens) + ; ("Babylon", `Babylon) + ; ("Carthage", `Carthage) + ; ("Delphi", `Delphi) + ; ("Edo", `Edo) + ; ("Florence", `Florence) + ; ("Alpha", `Alpha) ] let default = `Alpha @@ -87,13 +93,13 @@ module Protocol_kind = struct Arg.( value (opt (enum names) default - (info ["protocol-kind"] ~docs ~doc:"Set the protocol family.") )) + (info ["protocol-kind"] ~docs ~doc:"Set the protocol family."))) let pp ppf n = Fmt.string ppf (List.find_map_exn names ~f:(function | s, x when Poly.equal x n -> Some s - | _ -> None ) ) + | _ -> None)) end type t = @@ -106,6 +112,7 @@ type t = ; name: string (* e.g. alpha *) ; hash: string ; time_between_blocks: int list + ; minimal_block_delay: int ; baking_reward_per_endorsement: int list ; endorsement_reward: int list ; blocks_per_roll_snapshot: int @@ -132,8 +139,9 @@ let default () = ; name= "alpha" ; hash= "ProtoALphaALphaALphaALphaALphaALphaALphaALphaDdp3zK" ; time_between_blocks= [2; 3] - ; baking_reward_per_endorsement= [1_250_000; 187_500] - ; endorsement_reward= [1_250_000; 833_333] + ; minimal_block_delay= 2 + ; baking_reward_per_endorsement= [78_125; 11_719] + ; endorsement_reward= [78_125; 52_083] ; blocks_per_roll_snapshot= 4 ; blocks_per_voting_period= 16 ; blocks_per_cycle= 8 @@ -150,40 +158,56 @@ let protocol_parameters_json t : Ezjsonm.t = (* `src/proto_005_PsBabyM1/lib_protocol/parameters_repr.ml` `src/proto_006_PsCARTHA/lib_parameters/default_parameters.ml` `src/proto_007_PsDELPH1/lib_parameters/default_parameters.ml` *) + let alpha_specific_parameters = + match subkind with + | `Alpha -> + [ ( "minimal_block_delay" + , string (Int.to_string t.minimal_block_delay) ) ] + | _ -> [] in let op_gas_limit, block_gas_limit = match subkind with | `Babylon -> (800_000, 8_000_000) | `Carthage -> (1_040_000, 10_400_000) - | `Delphi | `Edo | `Florence | `Alpha -> (1_040_000, 10_400_000) in + | `Delphi | `Edo | `Florence -> (1_040_000, 10_400_000) + | `Alpha -> (1_040_000, 5_200_000) in let open Ezjsonm in let list_of_zs = list (fun i -> string (Int.to_string i)) in - [ ("blocks_per_commitment", int 4); ("endorsers_per_block", int 32) - ; ("hard_gas_limit_per_operation", string (Int.to_string op_gas_limit)) - ; ("hard_gas_limit_per_block", string (Int.to_string block_gas_limit)) - ; ("tokens_per_roll", string (Int.to_string 8_000_000_000)) - ; ("michelson_maximum_type_size", int 1_000) - ; ("seed_nonce_revelation_tip", string (Int.to_string 125_000)) - ; ("origination_size", int 257) - ; ("block_security_deposit", string (Int.to_string 512_000_000)) - ; ("endorsement_security_deposit", string (Int.to_string 64_000_000)) - ; ( match subkind with - | `Babylon -> ("block_reward", string (Int.to_string 16_000_000)) - | `Carthage | `Delphi | `Edo | `Florence | `Alpha -> - ( "baking_reward_per_endorsement" - , list_of_zs t.baking_reward_per_endorsement ) ) - ; ( "endorsement_reward" - , match subkind with - | `Babylon -> string (Int.to_string 2_000_000) - | `Carthage | `Delphi | `Edo | `Florence | `Alpha -> list_of_zs t.endorsement_reward - ); ("hard_storage_limit_per_operation", string (Int.to_string 60_000)) - ; ( "cost_per_byte" - , match subkind with - | `Babylon | `Carthage -> string (Int.to_string 1_000) - | `Delphi | `Edo | `Florence | `Alpha -> string (Int.to_string 250) ) - ; ("test_chain_duration", string (Int.to_string 1_966_080)) - ; ("quorum_min", int 3_000); ("quorum_max", int 7_000) - ; ("min_proposal_quorum", int 500); ("initial_endorsers", int 1) - ; ("delay_per_missing_endorsement", string (Int.to_string 1)) ] in + alpha_specific_parameters + @ [ ("blocks_per_commitment", int 4) + ; ("endorsers_per_block", int 256) + ; ("hard_gas_limit_per_operation", string (Int.to_string op_gas_limit)) + ; ("hard_gas_limit_per_block", string (Int.to_string block_gas_limit)) + ; ("tokens_per_roll", string (Int.to_string 8_000_000_000)) + ; ("michelson_maximum_type_size", int 1_000) + ; ("seed_nonce_revelation_tip", string (Int.to_string 125_000)) + ; ("origination_size", int 257) + ; ("block_security_deposit", string (Int.to_string 640_000_000)) + ; ("endorsement_security_deposit", string (Int.to_string 250_000)) + ; ( match subkind with + | `Babylon -> ("block_reward", string (Int.to_string 16_000_000)) + | `Carthage | `Delphi | `Edo | `Florence -> + ("baking_reward_per_endorsement", list_of_zs [1_250_000; 187_500]) + | `Alpha -> + ( "baking_reward_per_endorsement" + , list_of_zs t.baking_reward_per_endorsement ) ) + ; ( "endorsement_reward" + , match subkind with + | `Babylon -> string (Int.to_string 2_000_000) + | `Carthage | `Delphi | `Edo | `Florence -> + list_of_zs [1_250_000; 833_333] + | `Alpha -> list_of_zs t.endorsement_reward ) + ; ("hard_storage_limit_per_operation", string (Int.to_string 60_000)) + ; ( "cost_per_byte" + , match subkind with + | `Babylon | `Carthage -> string (Int.to_string 1_000) + | `Delphi | `Edo | `Florence | `Alpha -> string (Int.to_string 250) + ) + ; ("test_chain_duration", string (Int.to_string 1_966_080)) + ; ("quorum_min", int 3_000) + ; ("quorum_max", int 7_000) + ; ("min_proposal_quorum", int 500) + ; ("initial_endorsers", int 1) + ; ("delay_per_missing_endorsement", string (Int.to_string 1)) ] in let common = [ ( "bootstrap_accounts" , list make_account (t.bootstrap_accounts @ [(t.dictator, 10_000_000L)]) @@ -194,8 +218,8 @@ let protocol_parameters_json t : Ezjsonm.t = ; ("blocks_per_voting_period", int t.blocks_per_voting_period) ; ("blocks_per_cycle", int t.blocks_per_cycle) ; ("preserved_cycles", int t.preserved_cycles) - ; ("proof_of_work_threshold", ksprintf string "%d" t.proof_of_work_threshold) - ] in + ; ( "proof_of_work_threshold" + , ksprintf string "%d" t.proof_of_work_threshold ) ] in match t.custom_protocol_parameters with | Some s -> s | None -> @@ -239,7 +263,8 @@ let ensure_script state t = let ensure state t = Running_processes.run_successful_cmdf state "sh -c %s" - (Genspio.Compile.to_one_liner (ensure_script state t) |> Caml.Filename.quote) + ( Genspio.Compile.to_one_liner (ensure_script state t) + |> Caml.Filename.quote ) >>= fun _ -> return () let cli_term state = @@ -248,17 +273,17 @@ let cli_term state = let def = default () in let docs = Manpage_builder.section state ~rank:2 ~name:"PROTOCOL OPTIONS" in pure - (fun - bootstrap_accounts - (`Blocks_per_voting_period blocks_per_voting_period) - (`Protocol_hash hash) - (`Time_between_blocks time_between_blocks) - (`Blocks_per_cycle blocks_per_cycle) - (`Preserved_cycles preserved_cycles) - (`Timestamp_delay timestamp_delay) - (`Protocol_parameters custom_protocol_parameters) - kind - -> + (fun bootstrap_accounts + (`Blocks_per_voting_period blocks_per_voting_period) + (`Protocol_hash hash) + (`Time_between_blocks time_between_blocks) + (`Minimal_block_delay minimal_block_delay) + (`Blocks_per_cycle blocks_per_cycle) + (`Preserved_cycles preserved_cycles) + (`Timestamp_delay timestamp_delay) + (`Protocol_parameters custom_protocol_parameters) + kind + -> let id = "default-and-command-line" in { def with id @@ -268,13 +293,14 @@ let cli_term state = ; hash ; bootstrap_accounts ; time_between_blocks + ; minimal_block_delay ; preserved_cycles ; timestamp_delay - ; blocks_per_voting_period } ) + ; blocks_per_voting_period }) $ Arg.( pure (fun remove_all nb balance add_bootstraps -> add_bootstraps - @ make_bootstrap_accounts ~balance (if remove_all then 0 else nb) ) + @ make_bootstrap_accounts ~balance (if remove_all then 0 else nb)) $ value (flag (info @@ -282,20 +308,20 @@ let cli_term state = "Do not create any of the default bootstrap accounts (this \ overrides `--number-of-bootstrap-accounts` with 0)." ~docs - ["remove-default-bootstrap-accounts"] ) ) + ["remove-default-bootstrap-accounts"])) $ value (opt int 4 (info ["number-of-bootstrap-accounts"] - ~docs ~doc:"Set the number of generated bootstrap accounts." ) ) + ~docs ~doc:"Set the number of generated bootstrap accounts.")) $ ( pure (function | `Tez, f -> f *. 1_000_000. |> Int64.of_float - | `Mutez, f -> f |> Int64.of_float ) + | `Mutez, f -> f |> Int64.of_float) $ value (opt (pair ~sep:':' (enum [("tz", `Tez); ("tez", `Tez); ("mutez", `Mutez)]) - float ) + float) (`Tez, 4_000_000.) (info ["balance-of-bootstrap-accounts"] @@ -303,12 +329,12 @@ let cli_term state = ~doc: "Set the initial balance of bootstrap accounts, for \ instance: `tz:2_000_000.42` or \ - `mutez:42_000_000_000_000`." ) ) ) + `mutez:42_000_000_000_000`.")) ) $ Arg.( pure (fun l -> List.map l ~f:(fun ((name, pubkey, pubkey_hash, private_key), tez) -> - (Account.key_pair name ~pubkey ~pubkey_hash ~private_key, tez) ) ) + (Account.key_pair name ~pubkey ~pubkey_hash ~private_key, tez))) $ value (opt_all (pair ~sep:'@' (t4 ~sep:',' string string string string) int64) @@ -317,34 +343,43 @@ let cli_term state = ~docv:"NAME,PUBKEY,PUBKEY-HASH,PRIVATE-URI@MUTEZ-AMOUNT" ~doc: "Add a custom bootstrap account, e.g. \ - `LedgerBaker,edpku...,tz1YPS...,ledger://crouching-tiger.../ed25519/0'/0'@20_000_000_000`." ) ))) + `LedgerBaker,edpku...,tz1YPS...,ledger://crouching-tiger.../ed25519/0'/0'@20_000_000_000`.")))) $ Arg.( pure (fun x -> `Blocks_per_voting_period x) $ value (opt int def.blocks_per_voting_period (info ~docs ["blocks-per-voting-period"] - ~doc:"Set the length of voting periods." ) )) + ~doc:"Set the length of voting periods."))) $ Arg.( pure (fun x -> `Protocol_hash x) $ value (opt string def.hash (info ["protocol-hash"] ~docs - ~doc:"Set the (initial) protocol hash." ) )) + ~doc:"Set the (initial) protocol hash."))) $ Arg.( pure (fun x -> `Time_between_blocks x) $ value (opt (list ~sep:',' int) def.time_between_blocks - (info ["time-between-blocks"] ~docv:"COMMA-SEPARATED-SECONDS" ~docs + (info ["time-between-blocks"] ~docv:"COMMA-SEPARATED-SECONDS" + ~docs ~doc: "Set the time between blocks bootstrap-parameter, e.g. \ - `2,3,2`." ) )) + `2,3,2`."))) + $ Arg.( + pure (fun x -> `Minimal_block_delay x) + $ value + (opt int def.minimal_block_delay + (info ["minimal-block-delay"] ~docv:"SECONDS" ~docs + ~doc: + "Set the minimal delay between blocks bootstrap-parameter, \ + e.g. `2`."))) $ Arg.( pure (fun x -> `Blocks_per_cycle x) $ value (opt int def.blocks_per_cycle (info ["blocks-per-cycle"] ~docv:"NUMBER" ~docs - ~doc:"Number of blocks per cycle." ) )) + ~doc:"Number of blocks per cycle."))) $ Arg.( pure (fun x -> `Preserved_cycles x) $ value @@ -352,28 +387,28 @@ let cli_term state = (info ["preserved-cycles"] ~docv:"NUMBER" ~docs ~doc: "Base constant for baking rights (search for \ - `PRESERVED_CYCLES` in the white paper)." ) )) + `PRESERVED_CYCLES` in the white paper)."))) $ Arg.( pure (fun x -> `Timestamp_delay x) $ value (opt (some int) def.timestamp_delay (info ["timestamp-delay"] ~docv:"NUMBER" ~docs - ~doc:"Protocol activation timestamp delay in seconds." ) )) + ~doc:"Protocol activation timestamp delay in seconds."))) $ Arg.( pure (fun f -> `Protocol_parameters (Option.map f ~f:(fun path -> let i = Caml.open_in path in - Ezjsonm.from_channel i ) ) ) + Ezjsonm.from_channel i))) $ value (opt (some file) None (info ["override-protocol-parameters"] ~doc: - "Use these protocol parameters instead of the generated ones \ - (technically this invalidates most other options from a \ - tezos-node point of view, use at your own risk)." - ~docv:"JSON-FILE" ~docs ) )) + "Use these protocol parameters instead of the generated \ + ones (technically this invalidates most other options from \ + a tezos-node point of view, use at your own risk)." + ~docv:"JSON-FILE" ~docs))) $ Protocol_kind.cmdliner_term () ~docs module Pretty_print = struct @@ -393,7 +428,7 @@ module Pretty_print = struct match prev with | (kind, n) :: more when String.equal kind k -> (kind, n + 1) :: more - | other -> (k, 1) :: other ) + | other -> (k, 1) :: other) |> List.map ~f:(function k, 1 -> k | k, n -> str "%s×%d" k n) |> String.concat ~sep:"+" ) in let open Jqo in @@ -429,15 +464,16 @@ module Pretty_print = struct pf ppf "@, * [%a] %a" pp_op_list_short contents (long_string ~max:15) (field ~k:"hash" op |> get_string) ; - List.iter contents ~f:(pp_op_long ppf) ) + List.iter contents ~f:(pp_op_long ppf)) | _other -> List.iter l ~f:(function | `A [`String opid; op] -> let contents = field ~k:"contents" op |> get_list in - pf ppf "@, * [%s]: %a" opid pp_op_list_short contents ; + pf ppf "@, * [%s]: %a" opid pp_op_list_short + contents ; pf ppf "@, TODO: %a" json content - | _ -> fail_expecting "a operation tuple" ) ) - | _ -> fail_expecting "a list of operations" ) + | _ -> fail_expecting "a operation tuple") ) + | _ -> fail_expecting "a list of operations") | _ -> fail_expecting "a JSON object" let block_head_rpc ppf block_json = diff --git a/vendors/flextesa-lib/tezos_protocol.mli b/vendors/flextesa-lib/tezos_protocol.mli index f850fbdb45391530a4efcb172a01a428604cf06f..4c68be28057fefc8b20b1bc1cb87307fdd481979 100644 --- a/vendors/flextesa-lib/tezos_protocol.mli +++ b/vendors/flextesa-lib/tezos_protocol.mli @@ -64,6 +64,7 @@ type t = ; name: string ; hash: string ; time_between_blocks: int list + ; minimal_block_delay: int ; baking_reward_per_endorsement: int list ; endorsement_reward: int list ; blocks_per_roll_snapshot: int