diff --git a/src/proto_alpha/lib_client/injection.ml b/src/proto_alpha/lib_client/injection.ml index 36ad1384955c6f36a63509d7e5147845edfef507..864f085e931f66f8805421c94f5bc0b159a49de2 100644 --- a/src/proto_alpha/lib_client/injection.ml +++ b/src/proto_alpha/lib_client/injection.ml @@ -339,6 +339,7 @@ let estimated_gas_single (type kind) | Applied (Sc_rollup_timeout_result {consumed_gas; _}) -> Ok consumed_gas | Skipped _ -> Ok Gas.Arith.zero (* there must be another error for this to happen *) + | Applied (Das_slot_header_result {consumed_gas; _}) -> Ok consumed_gas | Backtracked (_, None) -> Ok Gas.Arith.zero (* there must be another error for this to happen *) | Backtracked (_, Some errs) -> Error (Environment.wrap_tztrace errs) @@ -403,6 +404,7 @@ let estimated_storage_single (type kind) ~tx_rollup_origination_size | Applied (Sc_rollup_timeout_result _) -> Ok Z.zero | Skipped _ -> Ok Z.zero (* there must be another error for this to happen *) + | Applied (Das_slot_header_result _) -> Ok Z.zero | Backtracked (_, None) -> Ok Z.zero (* there must be another error for this to happen *) | Backtracked (_, Some errs) -> Error (Environment.wrap_tztrace errs) @@ -467,6 +469,7 @@ let originated_contracts_single (type kind) | Applied (Sc_rollup_refute_result _) -> Ok [] | Applied (Sc_rollup_timeout_result _) -> Ok [] | Skipped _ -> Ok [] (* there must be another error for this to happen *) + | Applied (Das_slot_header_result _) -> Ok [] | Backtracked (_, None) -> Ok [] (* there must be another error for this to happen *) | Backtracked (_, Some errs) -> Error (Environment.wrap_tztrace errs) diff --git a/src/proto_alpha/lib_client/mockup.ml b/src/proto_alpha/lib_client/mockup.ml index 4b50846cb4dbd53234623e7b11d1cc236c685625..936f1e5cecf24845b64b70c345ac9ed89a0003ad 100644 --- a/src/proto_alpha/lib_client/mockup.ml +++ b/src/proto_alpha/lib_client/mockup.ml @@ -86,6 +86,7 @@ module Protocol_constants_overrides = struct tx_rollup_max_ticket_payload_size : int option; tx_rollup_rejection_max_proof_size : int option; tx_rollup_sunset_level : int32 option; + das : Constants.Parametric.das option; sc_rollup_enable : bool option; sc_rollup_origination_size : int option; sc_rollup_challenge_window_in_blocks : int option; @@ -158,7 +159,8 @@ module Protocol_constants_overrides = struct c.tx_rollup_max_ticket_payload_size, c.tx_rollup_rejection_max_proof_size, c.tx_rollup_sunset_level ) ), - ( c.sc_rollup_enable, + ( c.das, + c.sc_rollup_enable, c.sc_rollup_origination_size, c.sc_rollup_challenge_window_in_blocks, c.sc_rollup_max_available_messages, @@ -219,7 +221,8 @@ module Protocol_constants_overrides = struct tx_rollup_max_ticket_payload_size, tx_rollup_rejection_max_proof_size, tx_rollup_sunset_level ) ), - ( sc_rollup_enable, + ( das, + sc_rollup_enable, sc_rollup_origination_size, sc_rollup_challenge_window_in_blocks, sc_rollup_max_available_messages, @@ -278,6 +281,7 @@ module Protocol_constants_overrides = struct tx_rollup_max_ticket_payload_size; tx_rollup_rejection_max_proof_size; tx_rollup_sunset_level; + das; sc_rollup_enable; sc_rollup_origination_size; sc_rollup_challenge_window_in_blocks; @@ -361,7 +365,10 @@ module Protocol_constants_overrides = struct (opt "tx_rollup_max_ticket_payload_size" int31) (opt "tx_rollup_rejection_max_proof_size" int31) (opt "tx_rollup_sunset_level" int32))) - (obj8 + (obj9 + (opt + "das_parametric" + Constants.Parametric.das_encoding) (opt "sc_rollup_enable" bool) (opt "sc_rollup_origination_size" int31) (opt "sc_rollup_challenge_window_in_blocks" int31) @@ -460,6 +467,7 @@ module Protocol_constants_overrides = struct tx_rollup_rejection_max_proof_size = Some parametric.tx_rollup_rejection_max_proof_size; tx_rollup_sunset_level = Some parametric.tx_rollup_sunset_level; + das = Some parametric.das; sc_rollup_enable = Some parametric.sc_rollup_enable; sc_rollup_origination_size = Some parametric.sc_rollup_origination_size; sc_rollup_challenge_window_in_blocks = @@ -534,6 +542,7 @@ module Protocol_constants_overrides = struct tx_rollup_max_ticket_payload_size = None; tx_rollup_rejection_max_proof_size = None; tx_rollup_sunset_level = None; + das = None; sc_rollup_enable = None; sc_rollup_origination_size = None; sc_rollup_challenge_window_in_blocks = None; @@ -1016,6 +1025,7 @@ module Protocol_constants_overrides = struct Option.value ~default:c.tx_rollup_sunset_level o.tx_rollup_sunset_level; + das = Option.value ~default:c.das o.das; sc_rollup_enable = Option.value ~default:c.sc_rollup_enable o.sc_rollup_enable; sc_rollup_origination_size = diff --git a/src/proto_alpha/lib_client/operation_result.ml b/src/proto_alpha/lib_client/operation_result.ml index 58e3cb4c80c0e7e322b90fe2cd8827da1346c1c1..66cd12c905e15744b7800a22845162d9db801c74 100644 --- a/src/proto_alpha/lib_client/operation_result.ml +++ b/src/proto_alpha/lib_client/operation_result.ml @@ -339,6 +339,14 @@ let pp_manager_operation_content (type kind) source internal pp_result ppf Sc_rollup.Address.pp rollup pp_result + result + | Das_slot_header {slot} -> + Format.fprintf + ppf + "@[Publish slot %a%a@]" + Das.Slot.pp + slot + pp_result result) ; Format.fprintf ppf "@]" @@ -712,6 +720,9 @@ let pp_manager_operation_contents_and_result ppf Sc_rollup.Game.pp_status status in + let pp_das_slot_header_result (Das_slot_header_result {consumed_gas}) = + Format.fprintf ppf "@,Consumed gas: %a" Gas.Arith.pp consumed_gas + in let pp_result (type kind) ppf (result : kind manager_operation_result) = Format.fprintf ppf "@," ; match result with @@ -913,6 +924,11 @@ let pp_manager_operation_contents_and_result ppf "This operation publishing a commitment on a smart contract rollup \ was successfully applied" ; pp_sc_rollup_publish_result op + | Applied (Das_slot_header_result _ as op) -> + Format.fprintf + ppf + "This operation publishing a slot header was successfully applied" ; + pp_das_slot_header_result op | Backtracked ((Sc_rollup_publish_result _ as op), _errs) -> Format.fprintf ppf @@ -946,6 +962,12 @@ let pp_manager_operation_contents_and_result ppf rollup by timeout was BACKTRACKED, its expected effects (as follow) \ were NOT applied.@]" ; pp_sc_rollup_timeout_result op + | Backtracked ((Das_slot_header_result _ as op), _errs) -> + Format.fprintf + ppf + "@[This operation publishing a slot header was BACKTRACKED, its \ + expected effects (as follow) were NOT applied.@]" ; + pp_das_slot_header_result op in Format.fprintf diff --git a/src/proto_alpha/lib_delegate/baking_actions.ml b/src/proto_alpha/lib_delegate/baking_actions.ml index 81dfefc9f74b02bff03fdde1ef009eb296c2e954..2a161b5364a655963f9fd8963f5bb50ce2b4fa17 100644 --- a/src/proto_alpha/lib_delegate/baking_actions.ml +++ b/src/proto_alpha/lib_delegate/baking_actions.ml @@ -129,7 +129,7 @@ type action = updated_state : state; } | Inject_endorsements of { - endorsements : (delegate * consensus_content) list; + endorsements : (delegate * consensus_content_with_data) list; updated_state : state; } | Update_to_level of level_update diff --git a/src/proto_alpha/lib_delegate/baking_actions.mli b/src/proto_alpha/lib_delegate/baking_actions.mli index 83789e84892f8ec3b83f6af4b7c45d9c02c77b65..02d5d9c23d61d4dd9f9476ea41c9882696650e44 100644 --- a/src/proto_alpha/lib_delegate/baking_actions.mli +++ b/src/proto_alpha/lib_delegate/baking_actions.mli @@ -51,7 +51,7 @@ type action = updated_state : state; } | Inject_endorsements of { - endorsements : (delegate * consensus_content) list; + endorsements : (delegate * consensus_content_with_data) list; updated_state : state; } | Update_to_level of level_update @@ -95,13 +95,13 @@ val inject_preendorsements : val sign_endorsements : state -> - (delegate * consensus_content) list -> + (delegate * consensus_content_with_data) list -> (delegate * packed_operation) list tzresult Lwt.t val inject_endorsements : state_recorder:(new_state:state -> unit tzresult Lwt.t) -> state -> - endorsements:(delegate * consensus_content) list -> + endorsements:(delegate * consensus_content_with_data) list -> updated_state:state -> state tzresult Lwt.t diff --git a/src/proto_alpha/lib_delegate/baking_lib.ml b/src/proto_alpha/lib_delegate/baking_lib.ml index f47d397a1a31028ffb807487d78af3337d705242..4e4a6746c7f7910bb2e59eff8af2a0279083e3bf 100644 --- a/src/proto_alpha/lib_delegate/baking_lib.ml +++ b/src/proto_alpha/lib_delegate/baking_lib.ml @@ -76,7 +76,9 @@ let preendorse (cctxt : Protocol_client_context.full) ?(force = false) delegates cctxt#error "Cannot preendorse an outdated proposal" | Valid_proposal -> return_unit in - let consensus_list = make_consensus_list state proposal in + let consensus_list = + make_consensus_list state proposal ~data_availibility:() + in let*! () = cctxt#message "@[Preendorsing for:@ %a@]" @@ -113,7 +115,10 @@ let endorse (cctxt : Protocol_client_context.full) ?(force = false) delegates = | Outdated_proposal -> cctxt#error "Cannot endorse an outdated proposal" | Valid_proposal -> return_unit in - let consensus_list = make_consensus_list state proposal in + (* DAS/FIXME: Implement this *) + let consensus_list = + make_consensus_list state proposal ~data_availibility:Das.Endorsement.empty + in let*! () = cctxt#message "@[Endorsing for:@ %a@]" @@ -178,8 +183,9 @@ let endorsements_endorsing_power state endorsements = power + get_endorsement_voting_power endorsement) 0 -let generic_endorsing_power (filter : packed_operation list -> 'a list) - (extract : 'a -> consensus_content) state = +let generic_endorsing_power (type data) + (filter : packed_operation list -> 'a list) + (extract : 'a -> data raw_consensus_content) state = let current_mempool = Operation_worker.get_current_operations state.global_state.operation_worker in @@ -418,7 +424,11 @@ let baking_minimal_timestamp state = let cctxt = state.global_state.cctxt in let latest_proposal = state.level_state.latest_proposal in let own_endorsements = - State_transitions.make_consensus_list state latest_proposal + (* DAS/FIXME: Implement this *) + State_transitions.make_consensus_list + state + latest_proposal + ~data_availibility:Das.Endorsement.empty in let current_mempool = Operation_worker.get_current_operations state.global_state.operation_worker diff --git a/src/proto_alpha/lib_delegate/client_baking_denunciation.ml b/src/proto_alpha/lib_delegate/client_baking_denunciation.ml index 4f36381313075b1a4ffa8331938dccb2d3cecc10..76e3022b7f269a5b2ae09c73029aec64b7880af4 100644 --- a/src/proto_alpha/lib_delegate/client_baking_denunciation.ml +++ b/src/proto_alpha/lib_delegate/client_baking_denunciation.ml @@ -114,16 +114,17 @@ let get_block_offset level = Events.(emit invalid_level_conversion) (Environment.wrap_tztrace errs) >>= fun () -> Lwt.return (`Head 0) -let get_payload_hash (type kind) (op_kind : kind consensus_operation_type) - (op : kind Operation.t) = +let get_payload_hash (type kind data) + (op_kind : (kind, data) consensus_operation_type) (op : kind Operation.t) = match (op_kind, op.protocol_data.contents) with - | Preendorsement, Single (Preendorsement consensus_content) + | Preendorsement, Single (Preendorsement consensus_content) -> + consensus_content.block_payload_hash | Endorsement, Single (Endorsement consensus_content) -> consensus_content.block_payload_hash | _ -> . -let double_consensus_op_evidence (type kind) : - kind consensus_operation_type -> +let double_consensus_op_evidence (type kind data) : + (kind, data) consensus_operation_type -> #Protocol_client_context.full -> 'a -> branch:Block_hash.t -> @@ -134,9 +135,9 @@ let double_consensus_op_evidence (type kind) : | Endorsement -> Plugin.RPC.Forge.double_endorsement_evidence | Preendorsement -> Plugin.RPC.Forge.double_preendorsement_evidence -let process_consensus_op (type kind) cctxt - (op_kind : kind consensus_operation_type) (new_op : kind Operation.t) - chain_id level round slot ops_table = +let process_consensus_op (type kind data) cctxt + (op_kind : (kind, data) consensus_operation_type) + (new_op : kind Operation.t) chain_id level round slot ops_table = let map = Option.value ~default:Slot_Map.empty @@ HLevel.find ops_table (chain_id, level, round) diff --git a/src/proto_alpha/lib_delegate/state_transitions.ml b/src/proto_alpha/lib_delegate/state_transitions.ml index dd978072e535c5c9e5f04c1944b05bda45151b7d..0d3422ef4b83eb398d73747115517e8ada7d41ef 100644 --- a/src/proto_alpha/lib_delegate/state_transitions.ml +++ b/src/proto_alpha/lib_delegate/state_transitions.ml @@ -68,7 +68,7 @@ let is_acceptable_proposal_for_current_level state is a predecessor therefore the proposal is valid *) Lwt.return Valid_proposal -let make_consensus_list state proposal = +let make_consensus_list state proposal ~data_availibility = (* TODO efficiently iterate on the slot map instead of removing duplicate endorsements *) let level = @@ -81,7 +81,13 @@ let make_consensus_list state proposal = SlotMap.fold (fun _slot (delegate, slots) acc -> ( delegate, - {slot = Stdlib.List.hd slots.slots; level; round; block_payload_hash} ) + { + slot = Stdlib.List.hd slots.slots; + level; + round; + block_payload_hash; + data_availibility; + } ) :: acc) state.level_state.delegate_slots.own_delegate_slots [] @@ -97,7 +103,7 @@ let make_preendorse_action state proposal = {state with round_state} in let preendorsements : (delegate * consensus_content) list = - make_consensus_list state proposal + make_consensus_list state proposal ~data_availibility:() in Inject_preendorsements {preendorsements; updated_state} @@ -598,8 +604,9 @@ let make_endorse_action state proposal = proposal.block.round proposal.block.payload_hash in - let endorsements : (delegate * consensus_content) list = - make_consensus_list state proposal + let endorsements : (delegate * consensus_content_with_data) list = + (* DAS/FIXME: Implement this *) + make_consensus_list state proposal ~data_availibility:Das.Endorsement.empty in Inject_endorsements {endorsements; updated_state} diff --git a/src/proto_alpha/lib_delegate/state_transitions.mli b/src/proto_alpha/lib_delegate/state_transitions.mli index 4b14864cb1de36a6cc8f3d828ace4cbc8fb735cd..4528f3b420cb1d89950cdda6e8a47cdcf90f4b3a 100644 --- a/src/proto_alpha/lib_delegate/state_transitions.mli +++ b/src/proto_alpha/lib_delegate/state_transitions.mli @@ -36,7 +36,10 @@ val is_acceptable_proposal_for_current_level : state -> proposal -> proposal_acceptance Lwt.t val make_consensus_list : - state -> proposal -> (delegate * consensus_content) list + state -> + proposal -> + data_availibility:'a -> + (delegate * 'a raw_consensus_content) list val make_preendorse_action : state -> proposal -> action diff --git a/src/proto_alpha/lib_injector/l1_operation.ml b/src/proto_alpha/lib_injector/l1_operation.ml index 53ee27416bf6f318d45d3acaed5c6b949330da36..9135626d41b8b93c289e89959805f346e0997654 100644 --- a/src/proto_alpha/lib_injector/l1_operation.ml +++ b/src/proto_alpha/lib_injector/l1_operation.ml @@ -65,6 +65,7 @@ module Manager_operation = struct make sc_rollup_publish_case; make sc_rollup_refute_case; make sc_rollup_timeout_case; + make das_slot_header_case; ] let get_case : @@ -94,6 +95,7 @@ module Manager_operation = struct | Sc_rollup_publish _ -> sc_rollup_publish_case | Sc_rollup_refute _ -> sc_rollup_refute_case | Sc_rollup_timeout _ -> sc_rollup_timeout_case + | Das_slot_header _ -> das_slot_header_case let pp_kind ppf op = let open Operation.Encoding.Manager_operations in diff --git a/src/proto_alpha/lib_parameters/default_parameters.ml b/src/proto_alpha/lib_parameters/default_parameters.ml index d22d07ac466a57ebd6b620e6e344bbae4b219115..581cb9d06326f94b6ec831ced9e977411cd0d530 100644 --- a/src/proto_alpha/lib_parameters/default_parameters.ml +++ b/src/proto_alpha/lib_parameters/default_parameters.ml @@ -29,6 +29,16 @@ open Protocol.Alpha_context let tx_rollup_finality_period = 40_000 +(* DAS/FIXME: Thinkg harder about those values. *) +let default_das = + Constants.Parametric. + { + number_of_slots = 256; + number_of_shards = 2048; + endorsement_lag = 2; + availibility_threshold = 50; + } + let constants_mainnet = let consensus_committee_size = 7000 in let block_time = 30 in @@ -147,6 +157,7 @@ let constants_mainnet = about one year after the activation of protocol J. See https://tzstats.com/cycle/618 *) tx_rollup_sunset_level = 3_473_409l; + das = default_das; sc_rollup_enable = false; (* The following value is chosen to prevent spam. *) sc_rollup_origination_size = 6_314; diff --git a/src/proto_alpha/lib_plugin/plugin.ml b/src/proto_alpha/lib_plugin/plugin.ml index fa563890968c644ffe8f66ee13c297b6c1115e0e..dd44870d7205d7eefb0a21cbf2dbe0f13f3b452e 100644 --- a/src/proto_alpha/lib_plugin/plugin.ml +++ b/src/proto_alpha/lib_plugin/plugin.ml @@ -906,11 +906,11 @@ module Mempool = struct acceptable *) acceptable ~drift ~op_earliest_ts ~now_timestamp - let pre_filter_far_future_consensus_ops config + let pre_filter_far_future_consensus_ops (type data) config ~filter_state:({grandparent_level_start; round_zero_duration; _} : state) ?validation_state_before - ({level = op_level; round = op_round; _} : consensus_content) : bool Lwt.t - = + ({level = op_level; round = op_round; _} : data raw_consensus_content) : + bool Lwt.t = match (grandparent_level_start, validation_state_before, round_zero_duration) with @@ -990,7 +990,18 @@ module Mempool = struct match contents with | Single (Failing_noop _) -> Lwt.return (`Refused [Environment.wrap_tzerror Wrong_operation]) - | Single (Preendorsement consensus_content) + | Single (Preendorsement consensus_content) -> + pre_filter_far_future_consensus_ops + ~filter_state + config + ?validation_state_before + consensus_content + >>= fun keep -> + if keep then Lwt.return @@ `Passed_prefilter consensus_prio + else + Lwt.return + (`Branch_refused + [Environment.wrap_tzerror Consensus_operation_in_far_future]) | Single (Endorsement consensus_content) -> pre_filter_far_future_consensus_ops ~filter_state @@ -4337,6 +4348,49 @@ module RPC = struct RPC_context.make_call0 S.validators ctxt block {levels; delegates} () end + module DAS = struct + module S = struct + open Data_encoding + + let custom_root = RPC_path.(open_root / "helpers" / "das") + + type query = { + level : Raw_level.t option; + delegate : Signature.Public_key_hash.t option; + } + + let query : query RPC_query.t = + let open RPC_query in + query (fun level delegate -> {level; delegate}) + |+ opt_field "level" Raw_level.rpc_arg (fun t -> t.level) + |+ opt_field "delegate" Signature.Public_key_hash.rpc_arg (fun t -> + t.delegate) + |> seal + + let slots_rights = + RPC_service.get_service + ~description:"DAS/FIXME" + ~query + ~output:(list int31) + RPC_path.(custom_root / "rights") + + let availibility = + RPC_service.post_service + ~description:"DAS/FIXME" + ~input:Raw_level.encoding + ~query:RPC_query.empty + ~output:(option (list (option Das.Slot.encoding))) + RPC_path.(custom_root / "availability") + end + + let register () = + let open Services_registration in + register0 S.slots_rights ~chunked:false (fun _ctxt _q () -> + Stdlib.failwith "TODO") ; + register0 S.availibility ~chunked:false @@ fun ctxt () level -> + Das.Slot.find ctxt level + end + module S = struct open Data_encoding @@ -4404,6 +4458,7 @@ module RPC = struct Validators.register () ; Sc_rollup.register () ; Tx_rollup.register () ; + DAS.register () ; Registration.register0 ~chunked:false S.current_level (fun ctxt q () -> if q.offset < 0l then fail Negative_level_offset else diff --git a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL index 72597091ad41491601db20196737c5c9470b5a9f..c4431ae0bf1e22a1400242aef5c4d877a9bb8ed9 100644 --- a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL +++ b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL @@ -66,6 +66,11 @@ "Tx_rollup_commitment_repr", "Tx_rollup_errors_repr", "Tx_rollup_state_repr", + + "Das_slot_repr", + "Das_state_repr", + "Das_endorsement_repr", + "Bond_id_repr", "Vote_repr", "Liquidity_baking_repr", @@ -134,6 +139,8 @@ "Sc_rollup_costs", "Sc_rollup_storage", + "Das_slot_storage", + "Alpha_context", "Script_string", "Script_int", @@ -187,6 +194,8 @@ "Sc_rollup_arith", "Sc_rollups", + "Das_apply", + "Baking", "Amendment", "Apply", diff --git a/src/proto_alpha/lib_protocol/alpha_context.ml b/src/proto_alpha/lib_protocol/alpha_context.ml index b963576c8f14f8a3541fa82182dd2817e05d1bc4..37961666b395e02d3eed1d25aceef0b80660a702 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.ml +++ b/src/proto_alpha/lib_protocol/alpha_context.ml @@ -60,6 +60,19 @@ module Sc_rollup = struct include Sc_rollup_storage end +module Das = struct + module Endorsement = struct + include Das_endorsement_repr + include Raw_context.Das + end + + module Slot = struct + include Das_slot_repr + include Das_slot_storage + include Raw_context.Das + end +end + module Entrypoint = Entrypoint_repr include Operation_repr diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index 69671f95b943c37f3c23e01b39e0d8e333bb3c28..d2625f94d908d6db1fd05a6a25a80f4674949eb7 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -721,6 +721,15 @@ module Constants : sig (** Constants parameterized by context *) module Parametric : sig + type das = { + number_of_slots : int; + number_of_shards : int; + endorsement_lag : int; + availibility_threshold : int; + } + + val das_encoding : das Data_encoding.t + type t = { preserved_cycles : int; blocks_per_cycle : int32; @@ -773,6 +782,7 @@ module Constants : sig tx_rollup_max_withdrawals_per_batch : int; tx_rollup_rejection_max_proof_size : int; tx_rollup_sunset_level : int32; + das : das; sc_rollup_enable : bool; sc_rollup_origination_size : int; sc_rollup_challenge_window_in_blocks : int; @@ -2731,6 +2741,44 @@ module Sc_rollup : sig end end +module Das : sig + module Endorsement : sig + type t + + val empty : t + + val size : t -> int + + val expected_size : max_index:int -> int + + val shards : context -> endorser:Signature.Public_key_hash.t -> int list + + val record_available_shards : context -> t -> int list -> unit + end + + module Slot : sig + type t + + val encoding : t Data_encoding.t + + val pp : Format.formatter -> t -> unit + + val current_slot_fees : context -> t -> Tez.t option + + val update_slot : context -> t -> Tez.t -> unit + + val index : t -> int + + val find : context -> Raw_level.t -> t option list option tzresult Lwt.t + + val finalize_pending_slots : context -> context Lwt.t + + val finalize_confirmed_slots : context -> context Lwt.t + + val finalize_unavailable_slots : context -> context tzresult Lwt.t + end +end + module Block_payload : sig val hash : predecessor:Block_hash.t -> @@ -2917,6 +2965,8 @@ module Kind : sig type sc_rollup_timeout = Sc_rollup_timeout_kind + type das_slot_header = Das_slot_header_kind + type 'a manager = | Reveal_manager_kind : reveal manager | Transaction_manager_kind : transaction manager @@ -2942,16 +2992,17 @@ module Kind : sig | Sc_rollup_publish_manager_kind : sc_rollup_publish manager | Sc_rollup_refute_manager_kind : sc_rollup_refute manager | Sc_rollup_timeout_manager_kind : sc_rollup_timeout manager + | Das_slot_header_manager_kind : das_slot_header manager end -type 'a consensus_operation_type = - | Endorsement : Kind.endorsement consensus_operation_type - | Preendorsement : Kind.preendorsement consensus_operation_type +type (_, _) consensus_operation_type = + | Endorsement : (Kind.endorsement, Das.Endorsement.t) consensus_operation_type + | Preendorsement : (Kind.preendorsement, unit) consensus_operation_type val pp_operation_kind : - Format.formatter -> 'kind consensus_operation_type -> unit + Format.formatter -> ('kind, _) consensus_operation_type -> unit -type consensus_content = { +type 'data_availibility raw_consensus_content = { slot : Slot.t; level : Raw_level.t; (* The level is not required to validate an endorsement when it corresponds @@ -2959,10 +3010,18 @@ type consensus_content = { the level. *) round : Round.t; block_payload_hash : Block_payload_hash.t; + data_availibility : 'data_availibility; } +type consensus_content = unit raw_consensus_content + +type consensus_content_with_data = Das.Endorsement.t raw_consensus_content + val consensus_content_encoding : consensus_content Data_encoding.t +val consensus_content_with_data_encoding : + consensus_content_with_data Data_encoding.t + val pp_consensus_content : Format.formatter -> consensus_content -> unit type origination = { @@ -2989,7 +3048,7 @@ and _ contents_list = and _ contents = | Preendorsement : consensus_content -> Kind.preendorsement contents - | Endorsement : consensus_content -> Kind.endorsement contents + | Endorsement : consensus_content_with_data -> Kind.endorsement contents | Seed_nonce_revelation : { level : Raw_level.t; nonce : Nonce.t; @@ -3145,6 +3204,10 @@ and _ manager_operation = stakers : Sc_rollup.Staker.t * Sc_rollup.Staker.t; } -> Kind.sc_rollup_timeout manager_operation + | Das_slot_header : { + slot : Das.Slot.t; + } + -> Kind.das_slot_header manager_operation and counter = Z.t @@ -3310,6 +3373,8 @@ module Operation : sig val sc_rollup_timeout_case : Kind.sc_rollup_timeout Kind.manager case + val das_slot_header_case : Kind.das_slot_header Kind.manager case + module Manager_operations : sig type 'b case = | MCase : { @@ -3371,6 +3436,8 @@ module Operation : sig val sc_rollup_refute_case : Kind.sc_rollup_refute case val sc_rollup_timeout_case : Kind.sc_rollup_timeout case + + val das_slot_header_case : Kind.das_slot_header case end end diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index 32df61a1941ba5cfab5409eee6891a59ae8a267c..0db15d306c3bd31a06863469d27a780230a0345a 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -1232,13 +1232,14 @@ let apply_external_manager_operation_content : source:public_key_hash -> chain_id:Chain_id.t -> gas_consumed_in_precheck:Gas.cost option -> + fee:Tez.t -> kind manager_operation -> (context * kind successful_manager_operation_result * Script_typed_ir.packed_internal_operation list) tzresult Lwt.t = - fun ctxt mode ~source ~chain_id ~gas_consumed_in_precheck operation -> + fun ctxt mode ~source ~chain_id ~gas_consumed_in_precheck ~fee operation -> let source_contract = Contract.Implicit source in prepare_apply_manager_operation_content ~ctxt @@ -1771,6 +1772,11 @@ let apply_external_manager_operation_content : let consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt in let result = Sc_rollup_timeout_result {status; consumed_gas} in return (ctxt, result, []) + | Das_slot_header {slot} -> + Das_apply.apply_publish_slot_header ctxt slot fee >>?= fun () -> + let consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt in + let result = Das_slot_header_result {consumed_gas} in + return (ctxt, result, []) type success_or_failure = Success of context | Failure @@ -1977,7 +1983,10 @@ let precheck_manager_contents (type kind) ctxt (op : kind Kind.manager contents) >>?= fun () -> return ctxt | Sc_rollup_originate _ | Sc_rollup_add_messages _ | Sc_rollup_cement _ | Sc_rollup_publish _ | Sc_rollup_refute _ | Sc_rollup_timeout _ -> - assert_sc_rollup_feature_enabled ctxt >|=? fun () -> ctxt) + assert_sc_rollup_feature_enabled ctxt >|=? fun () -> ctxt + | Das_slot_header {slot} -> + Das_apply.validate_publish_slot_header ctxt slot >>?= fun () -> + return ctxt) >>=? fun ctxt -> Contract.increment_counter ctxt source >>=? fun ctxt -> Token.transfer ctxt (`Contract source_contract) `Block_fees fee @@ -2128,6 +2137,7 @@ let burn_storage_fees : | Sc_rollup_publish_result _ -> return (ctxt, storage_limit, smopr) | Sc_rollup_refute_result _ -> return (ctxt, storage_limit, smopr) | Sc_rollup_timeout_result _ -> return (ctxt, storage_limit, smopr) + | Das_slot_header_result _ -> return (ctxt, storage_limit, smopr) let apply_manager_contents (type kind) ctxt mode chain_id ~gas_consumed_in_precheck (op : kind Kind.manager contents) : @@ -2141,6 +2151,7 @@ let apply_manager_contents (type kind) ctxt mode chain_id operation; gas_limit; storage_limit; + fee; _; }) = op @@ -2154,6 +2165,7 @@ let apply_manager_contents (type kind) ctxt mode chain_id ~source ~gas_consumed_in_precheck ~chain_id + ~fee operation >>= function | Ok (ctxt, operation_results, internal_operations) -> ( @@ -2502,10 +2514,10 @@ type 'consensus_op_kind expected_consensus_content = { (* The [Alpha_context] is modified only in [Full_construction] mode when we check a preendorsement if the [preendorsement_quorum_round] was not set. *) -let compute_expected_consensus_content (type consensus_op_kind) +let compute_expected_consensus_content (type consensus_op_kind data) ~(current_level : Level.t) ~(proposal_level : Level.t) (ctxt : context) (application_mode : apply_mode) - (operation_kind : consensus_op_kind consensus_operation_type) + (operation_kind : (consensus_op_kind, data) consensus_operation_type) (operation_round : Round.t) (operation_level : Raw_level.t) : (context * consensus_op_kind expected_consensus_content) tzresult Lwt.t = match operation_kind with @@ -2610,7 +2622,8 @@ let check_operation_branch ~expected ~provided = (Block_hash.equal expected provided) (Wrong_consensus_operation_branch (expected, provided)) -let check_round (type kind) (operation_kind : kind consensus_operation_type) +let check_round (type kind data) + (operation_kind : (kind, data) consensus_operation_type) (apply_mode : apply_mode) ~(expected : Round.t) ~(provided : Round.t) : unit tzresult = match apply_mode with @@ -2634,9 +2647,9 @@ let check_round (type kind) (operation_kind : kind consensus_operation_type) (Round.equal expected provided) (Wrong_round_for_consensus_operation {expected; provided}) -let check_consensus_content (type kind) (apply_mode : apply_mode) - (content : consensus_content) (operation_branch : Block_hash.t) - (operation_kind : kind consensus_operation_type) +let check_consensus_content (type kind data) (apply_mode : apply_mode) + (content : data raw_consensus_content) (operation_branch : Block_hash.t) + (operation_kind : (kind, data) consensus_operation_type) (expected_content : kind expected_consensus_content) : unit tzresult = let expected_level = expected_content.level.level in let provided_level = content.level in @@ -2663,10 +2676,10 @@ let check_consensus_content (type kind) (apply_mode : apply_mode) to the grandfather: the block hash used in the payload_hash. Otherwise we could produce a preendorsement pointing to the direct proposal. This preendorsement wouldn't be able to propagate for a subsequent proposal using it as a locked_round evidence. *) -let validate_consensus_contents (type kind) ctxt chain_id - (operation_kind : kind consensus_operation_type) +let validate_consensus_contents (type kind data) ctxt chain_id + (operation_kind : (kind, data) consensus_operation_type) (operation : kind operation) (apply_mode : apply_mode) - (content : consensus_content) : + (content : data raw_consensus_content) : (context * public_key_hash * int) tzresult Lwt.t = let current_level = Level.current ctxt in let proposal_level = get_predecessor_level apply_mode in @@ -2691,6 +2704,11 @@ let validate_consensus_contents (type kind) ctxt chain_id operation_kind expected_content >>?= fun () -> + (match operation_kind with + | Preendorsement -> ok () + | Endorsement -> + Das_apply.validate_data_availibility ctxt content.data_availibility) + >>?= fun () -> match Slot.Map.find content.slot slot_map with | None -> fail Wrong_slot_used_for_consensus_operation | Some (delegate_pk, delegate_pkh, voting_power) -> @@ -2771,45 +2789,50 @@ let punish_double_endorsement_or_preendorsement (type kind) ctxt ~chain_id | Single (Endorsement _) -> Double_endorsement_evidence_result balance_updates in - match (op1.protocol_data.contents, op2.protocol_data.contents) with - | Single (Preendorsement e1), Single (Preendorsement e2) - | Single (Endorsement e1), Single (Endorsement e2) -> - let kind = if preendorsement then Preendorsement else Endorsement in - let op1_hash = Operation.hash op1 in - let op2_hash = Operation.hash op2 in - fail_unless - (Raw_level.(e1.level = e2.level) - && Round.(e1.round = e2.round) - && (not - (Block_payload_hash.equal - e1.block_payload_hash - e2.block_payload_hash)) - && (* we require an order on hashes to avoid the existence of - equivalent evidences *) - Operation_hash.(op1_hash < op2_hash)) - (Invalid_denunciation kind) - >>=? fun () -> - (* Disambiguate: levels are equal *) - let level = Level.from_raw ctxt e1.level in - check_denunciation_age ctxt kind level.level >>=? fun () -> - Stake_distribution.slot_owner ctxt level e1.slot - >>=? fun (ctxt, (delegate1_pk, delegate1)) -> - Stake_distribution.slot_owner ctxt level e2.slot - >>=? fun (ctxt, (_delegate2_pk, delegate2)) -> - fail_unless - (Signature.Public_key_hash.equal delegate1 delegate2) - (Inconsistent_denunciation {kind; delegate1; delegate2}) - >>=? fun () -> - let delegate_pk, delegate = (delegate1_pk, delegate1) in - Operation.check_signature delegate_pk chain_id op1 >>?= fun () -> - Operation.check_signature delegate_pk chain_id op2 >>?= fun () -> - punish_delegate - ctxt - delegate - level - `Double_endorsing - mk_result - ~payload_producer + let check_consensus_content (type a) (e1 : a raw_consensus_content) + (e2 : a raw_consensus_content) = + let kind = if preendorsement then Preendorsement else Endorsement in + let op1_hash = Operation.hash op1 in + let op2_hash = Operation.hash op2 in + fail_unless + (Raw_level.(e1.level = e2.level) + && Round.(e1.round = e2.round) + && (not + (Block_payload_hash.equal + e1.block_payload_hash + e2.block_payload_hash)) + && (* we require an order on hashes to avoid the existence of + equivalent evidences *) + Operation_hash.(op1_hash < op2_hash)) + (Invalid_denunciation kind) + >>=? fun () -> + (* Disambiguate: levels are equal *) + let level = Level.from_raw ctxt e1.level in + check_denunciation_age ctxt kind level.level >>=? fun () -> + Stake_distribution.slot_owner ctxt level e1.slot + >>=? fun (ctxt, (delegate1_pk, delegate1)) -> + Stake_distribution.slot_owner ctxt level e2.slot + >>=? fun (ctxt, (_delegate2_pk, delegate2)) -> + fail_unless + (Signature.Public_key_hash.equal delegate1 delegate2) + (Inconsistent_denunciation {kind; delegate1; delegate2}) + >>=? fun () -> return (ctxt, delegate1_pk, delegate1, level) + in + (match (op1.protocol_data.contents, op2.protocol_data.contents) with + | (Single (Preendorsement e1), Single (Preendorsement e2)) -> + check_consensus_content e1 e2 + | (Single (Endorsement e1), Single (Endorsement e2)) -> + check_consensus_content e1 e2) + >>=? fun (ctxt, delegate_pk, delegate, level) -> + Operation.check_signature delegate_pk chain_id op1 >>?= fun () -> + Operation.check_signature delegate_pk chain_id op2 >>?= fun () -> + punish_delegate + ctxt + delegate + level + `Double_endorsing + mk_result + ~payload_producer let punish_double_baking ctxt chain_id bh1 bh2 ~payload_producer = let hash1 = Block_header.hash bh1 in @@ -2854,8 +2877,9 @@ let punish_double_baking ctxt chain_id bh1 bh2 ~payload_producer = ~payload_producer (fun balance_updates -> Double_baking_evidence_result balance_updates) -let is_parent_endorsement ctxt ~proposal_level ~grand_parent_round - (operation : 'a operation) (operation_content : consensus_content) = +let is_parent_endorsement (type data) ctxt ~proposal_level ~grand_parent_round + (operation : 'a operation) (operation_content : data raw_consensus_content) + = match Consensus.grand_parent_branch ctxt with | None -> false | Some (great_grand_parent_hash, grand_parent_payload_hash) -> @@ -2948,6 +2972,11 @@ let apply_contents_list (type kind) ctxt chain_id (apply_mode : apply_mode) mode ~initial_slot:consensus_content.slot ~power:voting_power >>?= fun ctxt -> + Das_apply.apply_data_availibility + ctxt + consensus_content.data_availibility + ~endorser:delegate + >>=? fun () -> return ( ctxt, Single_result @@ -3491,6 +3520,7 @@ let finalize_application ctxt (mode : finalize_application_mode) protocol_data Consensus.store_grand_parent_branch ctxt predecessor_branch >>= return | None -> return ctxt) >>=? fun ctxt -> + Das_apply.das_finalisation ctxt >>=? fun ctxt -> (* We mark the current payload hash as the predecessor one => this will only be accessed by the successor block now. *) Consensus.store_endorsement_branch ctxt (predecessor, block_payload_hash) diff --git a/src/proto_alpha/lib_protocol/apply_results.ml b/src/proto_alpha/lib_protocol/apply_results.ml index 312d09ab8f1bb4b9ac0c944ec34d517f80205860..29852922911a54af45cf78ab364ca12074867b9e 100644 --- a/src/proto_alpha/lib_protocol/apply_results.ml +++ b/src/proto_alpha/lib_protocol/apply_results.ml @@ -249,6 +249,10 @@ type _ successful_manager_operation_result = status : Sc_rollup.Game.status; } -> Kind.sc_rollup_timeout successful_manager_operation_result + | Das_slot_header_result : { + consumed_gas : Gas.Arith.fp; + } + -> Kind.das_slot_header successful_manager_operation_result let migration_origination_result_to_successful_manager_operation_result ({ @@ -1338,6 +1342,9 @@ let equal_manager_kind : | Kind.Sc_rollup_timeout_manager_kind, Kind.Sc_rollup_timeout_manager_kind -> Some Eq | Kind.Sc_rollup_timeout_manager_kind, _ -> None + | Kind.Das_slot_header_manager_kind, Kind.Das_slot_header_manager_kind -> + Some Eq + | Kind.Das_slot_header_manager_kind, _ -> None module Encoding = struct type 'kind case = @@ -2639,6 +2646,23 @@ let kind_equal : } ) -> Some Eq | Manager_operation {operation = Sc_rollup_timeout _; _}, _ -> None + | ( Manager_operation {operation = Das_slot_header _; _}, + Manager_operation_result + { + operation_result = + Failed (Alpha_context.Kind.Das_slot_header_manager_kind, _); + _; + } ) -> + Some Eq + | ( Manager_operation {operation = Das_slot_header _; _}, + Manager_operation_result + { + operation_result = + Skipped Alpha_context.Kind.Das_slot_header_manager_kind; + _; + } ) -> + Some Eq + | Manager_operation {operation = Das_slot_header _; _}, _ -> None let rec kind_equal_list : type kind kind2. diff --git a/src/proto_alpha/lib_protocol/apply_results.mli b/src/proto_alpha/lib_protocol/apply_results.mli index 70a2ddadfb44e5950ccf000e2b909b8159ae4e53..757c4dc394b51ec31295100b7ebf526d8b89ae45 100644 --- a/src/proto_alpha/lib_protocol/apply_results.mli +++ b/src/proto_alpha/lib_protocol/apply_results.mli @@ -285,6 +285,10 @@ and _ successful_manager_operation_result = status : Sc_rollup.Game.status; } -> Kind.sc_rollup_timeout successful_manager_operation_result + | Das_slot_header_result : { + consumed_gas : Gas.Arith.fp; + } + -> Kind.das_slot_header successful_manager_operation_result and packed_successful_manager_operation_result = | Successful_manager_result : diff --git a/src/proto_alpha/lib_protocol/bitset.ml b/src/proto_alpha/lib_protocol/bitset.ml index ab0bfd4d264aa0c71301d5ccafc53a2141056639..9b2b9ba21666e9ea24e55efaeeee16452f204536 100644 --- a/src/proto_alpha/lib_protocol/bitset.ml +++ b/src/proto_alpha/lib_protocol/bitset.ml @@ -49,3 +49,5 @@ let () = (obj1 (req "position" int31)) (function Invalid_position i -> Some i | _ -> None) (fun i -> Invalid_position i) + +let size = Z.numbits diff --git a/src/proto_alpha/lib_protocol/bitset.mli b/src/proto_alpha/lib_protocol/bitset.mli index 0d8038eb61903879b796d03bd9a0f073d63ff0c5..fd9b029b40f7eb569c74b8931715e1b2a66b3187 100644 --- a/src/proto_alpha/lib_protocol/bitset.mli +++ b/src/proto_alpha/lib_protocol/bitset.mli @@ -43,3 +43,5 @@ val mem : t -> int -> bool tzresult This functions returns [Invalid_input i] if [i] is negative. *) val add : t -> int -> t tzresult + +val size : t -> int diff --git a/src/proto_alpha/lib_protocol/constants_parametric_repr.ml b/src/proto_alpha/lib_protocol/constants_parametric_repr.ml index b06fad40921523a680ec6f62b399e93b28b1cb6f..f725cb64a2007402873b2f1844fc3c27adfa420a 100644 --- a/src/proto_alpha/lib_protocol/constants_parametric_repr.ml +++ b/src/proto_alpha/lib_protocol/constants_parametric_repr.ml @@ -25,6 +25,42 @@ (* *) (*****************************************************************************) +type das = { + number_of_slots : int; + number_of_shards : int; + endorsement_lag : int; + availibility_threshold : int; +} + +let das_encoding = + let open Data_encoding in + conv + (fun { + number_of_slots; + number_of_shards; + endorsement_lag; + availibility_threshold; + } -> + ( number_of_slots, + number_of_shards, + endorsement_lag, + availibility_threshold )) + (fun ( number_of_slots, + number_of_shards, + endorsement_lag, + availibility_threshold ) -> + { + number_of_slots; + number_of_shards; + endorsement_lag; + availibility_threshold; + }) + (obj4 + (req "number_of_slots" Data_encoding.int16) + (req "number_of_shards" Data_encoding.int16) + (req "endorsement_lag" Data_encoding.int16) + (req "availibility_threshold" Data_encoding.int16)) + (* The encoded representation of this type is stored in the context as bytes. Changing the encoding, or the value of these constants from the previous protocol may break the context migration, or (even @@ -87,6 +123,7 @@ type t = { tx_rollup_max_withdrawals_per_batch : int; tx_rollup_rejection_max_proof_size : int; tx_rollup_sunset_level : int32; + das : das; sc_rollup_enable : bool; sc_rollup_origination_size : int; sc_rollup_challenge_window_in_blocks : int; @@ -152,7 +189,8 @@ let encoding = c.tx_rollup_max_ticket_payload_size, c.tx_rollup_rejection_max_proof_size, c.tx_rollup_sunset_level ) ), - ( c.sc_rollup_enable, + ( c.das, + c.sc_rollup_enable, c.sc_rollup_origination_size, c.sc_rollup_challenge_window_in_blocks, c.sc_rollup_max_available_messages, @@ -211,7 +249,8 @@ let encoding = tx_rollup_max_ticket_payload_size, tx_rollup_rejection_max_proof_size, tx_rollup_sunset_level ) ), - ( sc_rollup_enable, + ( das, + sc_rollup_enable, sc_rollup_origination_size, sc_rollup_challenge_window_in_blocks, sc_rollup_max_available_messages, @@ -271,6 +310,7 @@ let encoding = tx_rollup_max_ticket_payload_size; tx_rollup_rejection_max_proof_size; tx_rollup_sunset_level; + das; sc_rollup_enable; sc_rollup_origination_size; sc_rollup_challenge_window_in_blocks; @@ -351,7 +391,8 @@ let encoding = (req "tx_rollup_max_ticket_payload_size" int31) (req "tx_rollup_rejection_max_proof_size" int31) (req "tx_rollup_sunset_level" int32))) - (obj8 + (obj9 + (req "das_parametric" das_encoding) (req "sc_rollup_enable" bool) (req "sc_rollup_origination_size" int31) (req "sc_rollup_challenge_window_in_blocks" int31) diff --git a/src/proto_alpha/lib_protocol/constants_parametric_repr.mli b/src/proto_alpha/lib_protocol/constants_parametric_repr.mli index 11a3374952252f38164b1be0cb6e837bd8b3fb4a..34de03b9cdb3ebb6a58b3fb1a0cc588fd02cf811 100644 --- a/src/proto_alpha/lib_protocol/constants_parametric_repr.mli +++ b/src/proto_alpha/lib_protocol/constants_parametric_repr.mli @@ -25,6 +25,15 @@ (* *) (*****************************************************************************) +type das = { + number_of_slots : int; + number_of_shards : int; + endorsement_lag : int; + availibility_threshold : int; +} + +val das_encoding : das Data_encoding.t + type t = { preserved_cycles : int; blocks_per_cycle : int32; @@ -116,6 +125,7 @@ type t = { require proofs larger than this should be no-ops. *) tx_rollup_rejection_max_proof_size : int; tx_rollup_sunset_level : int32; + das : das; sc_rollup_enable : bool; sc_rollup_origination_size : int; sc_rollup_challenge_window_in_blocks : int; diff --git a/src/proto_alpha/lib_protocol/das_apply.ml b/src/proto_alpha/lib_protocol/das_apply.ml new file mode 100644 index 0000000000000000000000000000000000000000..3e4bd23c73c5b28d8843444ff6526f46f41a2a59 --- /dev/null +++ b/src/proto_alpha/lib_protocol/das_apply.ml @@ -0,0 +1,85 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 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. *) +(* *) +(*****************************************************************************) + +open Alpha_context + +(* DAS/FIXME Register error *) +type error += Data_availibility_size_exceeded + +let validate_data_availibility ctxt data_availibility = + let open Constants in + let Parametric.{das = {number_of_slots; _}; _} = parametric ctxt in + let expected_size = + Das.Endorsement.expected_size ~max_index:(number_of_slots - 1) + in + let size = Das.Endorsement.size data_availibility in + error_unless + Compare.Int.(size = expected_size) + Data_availibility_size_exceeded + +let apply_data_availibility ctxt data_availibility ~endorser = + let shards = Das.Endorsement.shards ctxt ~endorser in + Das.Endorsement.record_available_shards ctxt data_availibility shards ; + return_unit + +type error += + | Validate_publish_slot_header_invalid_index of { + given : int; + upper_bound : int; + } + +let validate_publish_slot_header ctxt slot = + let open Constants in + let slot_index = Das.Slot.index slot in + let Parametric.{das = {number_of_slots; _}; _} = parametric ctxt in + error_unless + Compare.Int.(0 <= slot_index && slot_index < number_of_slots) + (Validate_publish_slot_header_invalid_index + {given = slot_index; upper_bound = number_of_slots}) + +(* DAS/FIXME Register error *) +type error += + | Slot_header_candidate_with_low_fees of { + recorded_fees : Tez.t; + proposed_fees : Tez.t; + } + +let apply_publish_slot_header ctxt slot proposed_fees = + match Das.Slot.current_slot_fees ctxt slot with + | Some recorded_fees -> + if Tez.(recorded_fees < proposed_fees) then ( + Das.Slot.update_slot ctxt slot proposed_fees ; + ok ()) + else + error + (Slot_header_candidate_with_low_fees {recorded_fees; proposed_fees}) + | None -> + Das.Slot.update_slot ctxt slot proposed_fees ; + ok () + +let das_finalisation ctxt = + Das.Slot.finalize_pending_slots ctxt >>= fun ctxt -> + Das.Slot.finalize_confirmed_slots ctxt >>= fun ctxt -> + Das.Slot.finalize_unavailable_slots ctxt diff --git a/src/proto_alpha/lib_protocol/das_apply.mli b/src/proto_alpha/lib_protocol/das_apply.mli new file mode 100644 index 0000000000000000000000000000000000000000..a0ca788b113dc19a7f78c64663d5a6dd7dcb5eb4 --- /dev/null +++ b/src/proto_alpha/lib_protocol/das_apply.mli @@ -0,0 +1,40 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 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. *) +(* *) +(*****************************************************************************) + +open Alpha_context + +val validate_data_availibility : t -> Das.Endorsement.t -> unit tzresult + +val apply_data_availibility : + t -> + Das.Endorsement.t -> + endorser:Signature.Public_key_hash.t -> + unit tzresult Lwt.t + +val validate_publish_slot_header : t -> Das.Slot.t -> unit tzresult + +val apply_publish_slot_header : t -> Das.Slot.t -> Tez.t -> unit tzresult + +val das_finalisation : t -> t tzresult Lwt.t diff --git a/src/proto_alpha/lib_protocol/das_endorsement_repr.ml b/src/proto_alpha/lib_protocol/das_endorsement_repr.ml new file mode 100644 index 0000000000000000000000000000000000000000..4a38b042fe916ea8b0251d6e944e0de07878d476 --- /dev/null +++ b/src/proto_alpha/lib_protocol/das_endorsement_repr.ml @@ -0,0 +1,64 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 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. *) +(* *) +(*****************************************************************************) + +(* DAS/FIXME: This may be a bit heavy in practice. We could also + assume that in practice, this bitfield will contain many bits to + one. Hence, we could consider a better encoding which is smaller in + the optimistic case. For example: + + 1. When all the slot is endorsed, the encoding can be represented + in one octet. + + 2. Otherwise, we can pack slots by [8]. Have a header of [slots/8] + which is [1] if all the slots in this set are [1], [0] + otherwise. For all pack with a bit set to [0], we give the explicit + representation. Hence, if there are [256] slots, and [2] are not + endorsed, this representation will be of size [32] bits + [16] bits = + [48] bits which is better than [256]. *) +type t = Bitset.t + +let encoding = Bitset.encoding + +let empty = Bitset.empty + +let mem t index = + match Bitset.mem t index with + | Ok b -> b + | Error _ -> (* DAS/FIXME Should we do something here? *) false + +let add t index = + match Bitset.add t index with + | Ok t -> t + | Error _ -> (* DAS/FIXME Should we do something here? *) t + +let expected_size ~max_index = + (* We compute an encoding of the data-availability endorsements + which is a (tight) upper bound of what we expect. *) + let open Bitset in + match add empty (max_index - 1) with + | Error _ -> (* Happens if max_index < 1 *) 0 + | Ok t -> size t + +let size = Bitset.size diff --git a/src/proto_alpha/lib_protocol/das_endorsement_repr.mli b/src/proto_alpha/lib_protocol/das_endorsement_repr.mli new file mode 100644 index 0000000000000000000000000000000000000000..c42259f5fd009b6455681b37f10b6bcccf802e63 --- /dev/null +++ b/src/proto_alpha/lib_protocol/das_endorsement_repr.mli @@ -0,0 +1,38 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 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. *) +(* *) +(*****************************************************************************) + +type t + +val encoding : t Data_encoding.t + +val empty : t + +val mem : t -> int -> bool + +val add : t -> int -> t + +val expected_size : max_index:int -> int + +val size : t -> int diff --git a/src/proto_alpha/lib_protocol/das_slot_repr.ml b/src/proto_alpha/lib_protocol/das_slot_repr.ml new file mode 100644 index 0000000000000000000000000000000000000000..edfe745582755a8c9ab4f494baab68d78993f704 --- /dev/null +++ b/src/proto_alpha/lib_protocol/das_slot_repr.ml @@ -0,0 +1,60 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 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. *) +(* *) +(*****************************************************************************) + +module Header = struct + (* DAS/FIXME *) + type t = int + + let encoding = Data_encoding.int31 + + let pp = Format.pp_print_int +end + +type index = int + +type t = {level : Raw_level_repr.t; slot : index; header : Header.t} + +let encoding = + let open Data_encoding in + conv + (fun {level; slot; header} -> (level, slot, header)) + (fun (level, slot, header) -> {level; slot; header}) + (obj3 + (req "level" Raw_level_repr.encoding) + (req "slot" Data_encoding.int8) + (req "header" Header.encoding)) + +let pp fmt {level; slot; header} = + Format.fprintf + fmt + "level: %a slot: %a header: %a" + Raw_level_repr.pp + level + Format.pp_print_int + slot + Header.pp + header + +let index {slot; _} = slot diff --git a/src/proto_alpha/lib_protocol/das_slot_repr.mli b/src/proto_alpha/lib_protocol/das_slot_repr.mli new file mode 100644 index 0000000000000000000000000000000000000000..d38c1dd6cc0c053aea6c2b38e2e5f556c7937ee5 --- /dev/null +++ b/src/proto_alpha/lib_protocol/das_slot_repr.mli @@ -0,0 +1,40 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 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. *) +(* *) +(*****************************************************************************) + +module Header : sig + type t + + val encoding : t Data_encoding.t +end + +type index = int + +type t = {level : Raw_level_repr.t; slot : index; header : Header.t} + +val encoding : t Data_encoding.t + +val pp : Format.formatter -> t -> unit + +val index : t -> index diff --git a/src/proto_alpha/lib_protocol/das_slot_storage.ml b/src/proto_alpha/lib_protocol/das_slot_storage.ml new file mode 100644 index 0000000000000000000000000000000000000000..4ea86d24fbf77f96cfa1e8a687e289a23efba8e9 --- /dev/null +++ b/src/proto_alpha/lib_protocol/das_slot_storage.ml @@ -0,0 +1,84 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 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. *) +(* *) +(*****************************************************************************) + +let find ctxt level = + Storage.Das.Slot_headers.find ctxt level >|=? function + | None -> None + | Some headers -> + Some + (List.mapi + (fun slot -> function + | None -> None + | Some header -> Some Das_slot_repr.{level; slot; header}) + headers) + +let finalize_pending_slots ctxt = + let current_level = Raw_context.current_level ctxt in + let headers = Raw_context.Das.get_pending_slot_headers ctxt in + Storage.Das.Slot_headers.add ctxt current_level.level headers + +let finalize_confirmed_slots ctxt = + let current_level = Raw_context.current_level ctxt in + let Constants_parametric_repr.{das; _} = Raw_context.constants ctxt in + let delay = das.endorsement_lag in + match Raw_level_repr.(sub current_level.level delay) with + | None -> Lwt.return ctxt + | Some level -> + (* DAS/FIXME Integration with SCORU should be probably done here. *) + Storage.Das.Slot_headers.remove ctxt level + +let finalize_unavailable_slots ctxt = + let current_level = Raw_context.current_level ctxt in + let shards_by_slot = Raw_context.Das.get_shards_availibility ctxt in + let Constants_parametric_repr.{das; _} = Raw_context.constants ctxt in + match Raw_level_repr.(sub current_level.level das.endorsement_lag) with + | None -> return ctxt + | Some level_endorsed -> ( + Storage.Das.Slot_headers.find ctxt level_endorsed >>=? function + | None -> return ctxt + | Some slots -> + let available_slots = + List.mapi + (fun slot_index slot_header -> + match slot_header with + | None -> + (* DAS/FIXME Should we do something? If an endorser said this slot was available? *) + None + | Some slot -> + let shards_available = + FallbackArray.fold + (fun acc x -> if x then acc + 1 else acc) + (FallbackArray.get shards_by_slot slot_index) + 0 + in + if + Compare.Int.( + shards_available >= das.availibility_threshold) + then None + else Some slot) + slots + in + Storage.Das.Slot_headers.add ctxt level_endorsed available_slots + >|= ok) diff --git a/src/proto_alpha/lib_protocol/das_slot_storage.mli b/src/proto_alpha/lib_protocol/das_slot_storage.mli new file mode 100644 index 0000000000000000000000000000000000000000..b7f72408f5039e8cdc8cd7dc03b8b96b7635e8bf --- /dev/null +++ b/src/proto_alpha/lib_protocol/das_slot_storage.mli @@ -0,0 +1,35 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 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. *) +(* *) +(*****************************************************************************) + +val find : + Raw_context.t -> + Raw_level_repr.t -> + Das_slot_repr.t option list option tzresult Lwt.t + +val finalize_pending_slots : Raw_context.t -> Raw_context.t Lwt.t + +val finalize_confirmed_slots : Raw_context.t -> Raw_context.t Lwt.t + +val finalize_unavailable_slots : Raw_context.t -> Raw_context.t tzresult Lwt.t diff --git a/src/proto_alpha/lib_protocol/das_state_repr.ml b/src/proto_alpha/lib_protocol/das_state_repr.ml new file mode 100644 index 0000000000000000000000000000000000000000..5a9526d1269a8eb0b3c504e057d1db5ab90622c5 --- /dev/null +++ b/src/proto_alpha/lib_protocol/das_state_repr.ml @@ -0,0 +1,26 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 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. *) +(* *) +(*****************************************************************************) + +type t = {last_slot_level_availible : Raw_level_repr.t} diff --git a/src/proto_alpha/lib_protocol/das_state_repr.mli b/src/proto_alpha/lib_protocol/das_state_repr.mli new file mode 100644 index 0000000000000000000000000000000000000000..5a9526d1269a8eb0b3c504e057d1db5ab90622c5 --- /dev/null +++ b/src/proto_alpha/lib_protocol/das_state_repr.mli @@ -0,0 +1,26 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 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. *) +(* *) +(*****************************************************************************) + +type t = {last_slot_level_availible : Raw_level_repr.t} diff --git a/src/proto_alpha/lib_protocol/dune.inc b/src/proto_alpha/lib_protocol/dune.inc index c2a5f6a6ff2fbf1ec5390b78f9e4124ebf02a344..b1d4133fadba78843231f84cd44f1ded2b8ad07e 100644 --- a/src/proto_alpha/lib_protocol/dune.inc +++ b/src/proto_alpha/lib_protocol/dune.inc @@ -91,6 +91,9 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end tx_rollup_commitment_repr.mli tx_rollup_commitment_repr.ml tx_rollup_errors_repr.ml tx_rollup_state_repr.mli tx_rollup_state_repr.ml + das_slot_repr.mli das_slot_repr.ml + das_state_repr.mli das_state_repr.ml + das_endorsement_repr.mli das_endorsement_repr.ml bond_id_repr.mli bond_id_repr.ml vote_repr.mli vote_repr.ml liquidity_baking_repr.mli liquidity_baking_repr.ml @@ -151,6 +154,7 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end tx_rollup_storage.mli tx_rollup_storage.ml sc_rollup_costs.mli sc_rollup_costs.ml sc_rollup_storage.mli sc_rollup_storage.ml + das_slot_storage.mli das_slot_storage.ml alpha_context.mli alpha_context.ml script_string.mli script_string.ml script_int.mli script_int.ml @@ -198,6 +202,7 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end sc_rollup_PVM_sem.ml sc_rollup_arith.mli sc_rollup_arith.ml sc_rollups.mli sc_rollups.ml + das_apply.mli das_apply.ml baking.mli baking.ml amendment.mli amendment.ml apply.mli apply.ml @@ -281,6 +286,9 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end tx_rollup_commitment_repr.mli tx_rollup_commitment_repr.ml tx_rollup_errors_repr.ml tx_rollup_state_repr.mli tx_rollup_state_repr.ml + das_slot_repr.mli das_slot_repr.ml + das_state_repr.mli das_state_repr.ml + das_endorsement_repr.mli das_endorsement_repr.ml bond_id_repr.mli bond_id_repr.ml vote_repr.mli vote_repr.ml liquidity_baking_repr.mli liquidity_baking_repr.ml @@ -341,6 +349,7 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end tx_rollup_storage.mli tx_rollup_storage.ml sc_rollup_costs.mli sc_rollup_costs.ml sc_rollup_storage.mli sc_rollup_storage.ml + das_slot_storage.mli das_slot_storage.ml alpha_context.mli alpha_context.ml script_string.mli script_string.ml script_int.mli script_int.ml @@ -388,6 +397,7 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end sc_rollup_PVM_sem.ml sc_rollup_arith.mli sc_rollup_arith.ml sc_rollups.mli sc_rollups.ml + das_apply.mli das_apply.ml baking.mli baking.ml amendment.mli amendment.ml apply.mli apply.ml @@ -471,6 +481,9 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end tx_rollup_commitment_repr.mli tx_rollup_commitment_repr.ml tx_rollup_errors_repr.ml tx_rollup_state_repr.mli tx_rollup_state_repr.ml + das_slot_repr.mli das_slot_repr.ml + das_state_repr.mli das_state_repr.ml + das_endorsement_repr.mli das_endorsement_repr.ml bond_id_repr.mli bond_id_repr.ml vote_repr.mli vote_repr.ml liquidity_baking_repr.mli liquidity_baking_repr.ml @@ -531,6 +544,7 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end tx_rollup_storage.mli tx_rollup_storage.ml sc_rollup_costs.mli sc_rollup_costs.ml sc_rollup_storage.mli sc_rollup_storage.ml + das_slot_storage.mli das_slot_storage.ml alpha_context.mli alpha_context.ml script_string.mli script_string.ml script_int.mli script_int.ml @@ -578,6 +592,7 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end sc_rollup_PVM_sem.ml sc_rollup_arith.mli sc_rollup_arith.ml sc_rollups.mli sc_rollups.ml + das_apply.mli das_apply.ml baking.mli baking.ml amendment.mli amendment.ml apply.mli apply.ml @@ -683,6 +698,9 @@ include Tezos_raw_protocol_alpha.Main Tx_rollup_commitment_repr Tx_rollup_errors_repr Tx_rollup_state_repr + Das_slot_repr + Das_state_repr + Das_endorsement_repr Bond_id_repr Vote_repr Liquidity_baking_repr @@ -743,6 +761,7 @@ include Tezos_raw_protocol_alpha.Main Tx_rollup_storage Sc_rollup_costs Sc_rollup_storage + Das_slot_storage Alpha_context Script_string Script_int @@ -790,6 +809,7 @@ include Tezos_raw_protocol_alpha.Main Sc_rollup_PVM_sem Sc_rollup_arith Sc_rollups + Das_apply Baking Amendment Apply @@ -914,6 +934,9 @@ include Tezos_raw_protocol_alpha.Main tx_rollup_commitment_repr.mli tx_rollup_commitment_repr.ml tx_rollup_errors_repr.ml tx_rollup_state_repr.mli tx_rollup_state_repr.ml + das_slot_repr.mli das_slot_repr.ml + das_state_repr.mli das_state_repr.ml + das_endorsement_repr.mli das_endorsement_repr.ml bond_id_repr.mli bond_id_repr.ml vote_repr.mli vote_repr.ml liquidity_baking_repr.mli liquidity_baking_repr.ml @@ -974,6 +997,7 @@ include Tezos_raw_protocol_alpha.Main tx_rollup_storage.mli tx_rollup_storage.ml sc_rollup_costs.mli sc_rollup_costs.ml sc_rollup_storage.mli sc_rollup_storage.ml + das_slot_storage.mli das_slot_storage.ml alpha_context.mli alpha_context.ml script_string.mli script_string.ml script_int.mli script_int.ml @@ -1021,6 +1045,7 @@ include Tezos_raw_protocol_alpha.Main sc_rollup_PVM_sem.ml sc_rollup_arith.mli sc_rollup_arith.ml sc_rollups.mli sc_rollups.ml + das_apply.mli das_apply.ml baking.mli baking.ml amendment.mli amendment.ml apply.mli apply.ml diff --git a/src/proto_alpha/lib_protocol/operation_repr.ml b/src/proto_alpha/lib_protocol/operation_repr.ml index ea4f9d380fa6fcf686b3d9b5e06c114ceff8a9b5..19c6dc43019230afc66a38bc9138c5c447aeb347 100644 --- a/src/proto_alpha/lib_protocol/operation_repr.ml +++ b/src/proto_alpha/lib_protocol/operation_repr.ml @@ -101,6 +101,8 @@ module Kind = struct type sc_rollup_timeout = Sc_rollup_timeout_kind + type das_slot_header = Das_slot_header_kind + type 'a manager = | Reveal_manager_kind : reveal manager | Transaction_manager_kind : transaction manager @@ -126,19 +128,21 @@ module Kind = struct | Sc_rollup_publish_manager_kind : sc_rollup_publish manager | Sc_rollup_refute_manager_kind : sc_rollup_refute manager | Sc_rollup_timeout_manager_kind : sc_rollup_timeout manager + | Das_slot_header_manager_kind : das_slot_header manager end -type 'a consensus_operation_type = - | Endorsement : Kind.endorsement consensus_operation_type - | Preendorsement : Kind.preendorsement consensus_operation_type +type (_, _) consensus_operation_type = + | Endorsement + : (Kind.endorsement, Das_endorsement_repr.t) consensus_operation_type + | Preendorsement : (Kind.preendorsement, unit) consensus_operation_type -let pp_operation_kind (type kind) ppf - (operation_kind : kind consensus_operation_type) = +let pp_operation_kind (type kind data) ppf + (operation_kind : (kind, data) consensus_operation_type) = match operation_kind with | Endorsement -> Format.fprintf ppf "Endorsement" | Preendorsement -> Format.fprintf ppf "Preendorsement" -type consensus_content = { +type 'data_availibility raw_consensus_content = { slot : Slot_repr.t; level : Raw_level_repr.t; (* The level is not required to validate an endorsement when it corresponds @@ -146,24 +150,40 @@ type consensus_content = { the level. *) round : Round_repr.t; block_payload_hash : Block_payload_hash.t; - (* NOTE: This could be just the hash of the set of operations (the - actual payload). The grandfather block hash should already be - fixed by the operation.shell.branch field. This is not really - important but could make things easier for debugging *) + (* NOTE: This could be just the hash of the set of operations (the + actual payload). The grandfather block hash should already be + fixed by the operation.shell.branch field. This is not really + important but could make things easier for debugging *) + data_availibility : 'data_availibility; + (* This field is not part of the Tenderbake consensus, but is used + to get a consensus on the data-available. This is only used for + [endorsements]. *) } -let consensus_content_encoding = +type consensus_content = unit raw_consensus_content + +type consensus_content_with_data = Das_endorsement_repr.t raw_consensus_content + +let raw_consensus_content_encoding data_availibility_encoding = let open Data_encoding in conv - (fun {slot; level; round; block_payload_hash} -> - (slot, level, round, block_payload_hash)) - (fun (slot, level, round, block_payload_hash) -> - {slot; level; round; block_payload_hash}) - (obj4 + (fun {slot; level; round; block_payload_hash; data_availibility} -> + (slot, level, round, block_payload_hash, data_availibility)) + (fun (slot, level, round, block_payload_hash, data_availibility) -> + {slot; level; round; block_payload_hash; data_availibility}) + (* DAS/FIXME: Is the last field cost-free when [data_availibility_encoding] is [unit] ? *) + (obj5 (req "slot" Slot_repr.encoding) (req "level" Raw_level_repr.encoding) (req "round" Round_repr.encoding) - (req "block_payload_hash" Block_payload_hash.encoding)) + (req "block_payload_hash" Block_payload_hash.encoding) + (req "data_availibility" data_availibility_encoding)) + +let consensus_content_encoding = + raw_consensus_content_encoding Data_encoding.unit + +let consensus_content_with_data_encoding = + raw_consensus_content_encoding Das_endorsement_repr.encoding let pp_consensus_content ppf content = Format.fprintf @@ -233,7 +253,7 @@ and _ contents_list = and _ contents = | Preendorsement : consensus_content -> Kind.preendorsement contents - | Endorsement : consensus_content -> Kind.endorsement contents + | Endorsement : consensus_content_with_data -> Kind.endorsement contents | Seed_nonce_revelation : { level : Raw_level_repr.t; nonce : Seed_repr.nonce; @@ -389,6 +409,10 @@ and _ manager_operation = stakers : Sc_rollup_repr.Staker.t * Sc_rollup_repr.Staker.t; } -> Kind.sc_rollup_timeout manager_operation + | Das_slot_header : { + slot : Das_slot_repr.t; + } + -> Kind.das_slot_header manager_operation and counter = Z.t @@ -417,6 +441,7 @@ let manager_kind : type kind. kind manager_operation -> kind Kind.manager = | Sc_rollup_publish _ -> Kind.Sc_rollup_publish_manager_kind | Sc_rollup_refute _ -> Kind.Sc_rollup_refute_manager_kind | Sc_rollup_timeout _ -> Kind.Sc_rollup_timeout_manager_kind + | Das_slot_header _ -> Kind.Das_slot_header_manager_kind type packed_manager_operation = | Manager : 'kind manager_operation -> packed_manager_operation @@ -504,6 +529,10 @@ let sc_rollup_operation_refute_tag = sc_rollup_operation_tag_offset + 4 let sc_rollup_operation_timeout_tag = sc_rollup_operation_tag_offset + 5 +let das_offset = 300 + +let das_slot_header_tag = das_offset + 0 + module Encoding = struct open Data_encoding @@ -1027,6 +1056,19 @@ module Encoding = struct | Sc_rollup_timeout {rollup; stakers} -> (rollup, stakers)); inj = (fun (rollup, stakers) -> Sc_rollup_timeout {rollup; stakers}); } + + let[@coq_axiom_with_reason "gadt"] das_slot_header_case = + MCase + { + tag = das_slot_header_tag; + name = "das_slot_header"; + encoding = obj1 (req "das_slot" Das_slot_repr.encoding); + select = + (function + | Manager (Das_slot_header _ as op) -> Some op | _ -> None); + proj = (function Das_slot_header {slot} -> slot); + inj = (fun slot -> Das_slot_header {slot}); + } end type 'b case = @@ -1078,30 +1120,18 @@ module Encoding = struct @@ union [make preendorsement_case])) (varopt "signature" Signature.encoding))) - let endorsement_encoding = - obj4 - (req "slot" Slot_repr.encoding) - (req "level" Raw_level_repr.encoding) - (req "round" Round_repr.encoding) - (req "block_payload_hash" Block_payload_hash.encoding) - let endorsement_case = Case { tag = 21; name = "endorsement"; - encoding = endorsement_encoding; + encoding = consensus_content_with_data_encoding; select = (function Contents (Endorsement _ as op) -> Some op | _ -> None); proj = - (fun [@coq_match_with_default] (Endorsement consensus_content) -> - ( consensus_content.slot, - consensus_content.level, - consensus_content.round, - consensus_content.block_payload_hash )); - inj = - (fun (slot, level, round, block_payload_hash) -> - Endorsement {slot; level; round; block_payload_hash}); + (fun [@coq_match_with_default] (Endorsement endorsement) -> + endorsement); + inj = (fun endorsement -> Endorsement endorsement); } let[@coq_axiom_with_reason "gadt"] endorsement_encoding = @@ -1397,6 +1427,11 @@ module Encoding = struct sc_rollup_operation_timeout_tag Manager_operations.sc_rollup_timeout_case + let das_slot_header_case = + make_manager_case + das_slot_header_tag + Manager_operations.das_slot_header_case + let contents_encoding = let make (Case {tag; name; encoding; select; proj; inj}) = case @@ -1656,6 +1691,8 @@ let equal_manager_operation_kind : | Sc_rollup_refute _, _ -> None | Sc_rollup_timeout _, Sc_rollup_timeout _ -> Some Eq | Sc_rollup_timeout _, _ -> None + | Das_slot_header _, Das_slot_header _ -> Some Eq + | Das_slot_header _, _ -> None let equal_contents_kind : type a b. a contents -> b contents -> (a, b) eq option = diff --git a/src/proto_alpha/lib_protocol/operation_repr.mli b/src/proto_alpha/lib_protocol/operation_repr.mli index 47371a1c23bef5b2490198dde1175dcc9099e210..084206b8a10f37a80db75597eeaec30e8986c192 100644 --- a/src/proto_alpha/lib_protocol/operation_repr.mli +++ b/src/proto_alpha/lib_protocol/operation_repr.mli @@ -130,6 +130,8 @@ module Kind : sig type sc_rollup_timeout = Sc_rollup_timeout_kind + type das_slot_header = Das_slot_header_kind + type 'a manager = | Reveal_manager_kind : reveal manager | Transaction_manager_kind : transaction manager @@ -155,16 +157,18 @@ module Kind : sig | Sc_rollup_publish_manager_kind : sc_rollup_publish manager | Sc_rollup_refute_manager_kind : sc_rollup_refute manager | Sc_rollup_timeout_manager_kind : sc_rollup_timeout manager + | Das_slot_header_manager_kind : das_slot_header manager end -type 'a consensus_operation_type = - | Endorsement : Kind.endorsement consensus_operation_type - | Preendorsement : Kind.preendorsement consensus_operation_type +type (_, _) consensus_operation_type = + | Endorsement + : (Kind.endorsement, Das_endorsement_repr.t) consensus_operation_type + | Preendorsement : (Kind.preendorsement, unit) consensus_operation_type val pp_operation_kind : - Format.formatter -> 'kind consensus_operation_type -> unit + Format.formatter -> ('kind, 'data) consensus_operation_type -> unit -type consensus_content = { +type 'data_availibility raw_consensus_content = { slot : Slot_repr.t; (* By convention, this is the validator's first slot. *) level : Raw_level_repr.t; @@ -172,11 +176,19 @@ type consensus_content = { round : Round_repr.t; (* The round of (pre)endorsed block. *) block_payload_hash : Block_payload_hash.t; - (* The payload hash of (pre)endorsed block. *) + (* The payload hash of (pre)endorsed block. *) + data_availibility : 'data_availibility; } +type consensus_content = unit raw_consensus_content + +type consensus_content_with_data = Das_endorsement_repr.t raw_consensus_content + val consensus_content_encoding : consensus_content Data_encoding.t +val consensus_content_with_data_encoding : + consensus_content_with_data Data_encoding.t + val pp_consensus_content : Format.formatter -> consensus_content -> unit type consensus_watermark = @@ -230,7 +242,7 @@ and _ contents = | Preendorsement : consensus_content -> Kind.preendorsement contents (* Endorsement: About consensus, endorsement of a block held by a validator. *) - | Endorsement : consensus_content -> Kind.endorsement contents + | Endorsement : consensus_content_with_data -> Kind.endorsement contents (* Seed_nonce_revelation: Nonces are created by bakers and are combined to create pseudo-random seeds. Bakers are urged to reveal their nonces after a given number of cycles to keep their block rewards @@ -458,6 +470,10 @@ and _ manager_operation = stakers : Sc_rollup_repr.Staker.t * Sc_rollup_repr.Staker.t; } -> Kind.sc_rollup_timeout manager_operation + | Das_slot_header : { + slot : Das_slot_repr.t; + } + -> Kind.das_slot_header manager_operation (** Counters are used as anti-replay protection mechanism in manager operations: each manager account stores a counter and @@ -603,6 +619,8 @@ module Encoding : sig val sc_rollup_timeout_case : Kind.sc_rollup_timeout Kind.manager case + val das_slot_header_case : Kind.das_slot_header Kind.manager case + module Manager_operations : sig type 'b case = | MCase : { @@ -663,5 +681,7 @@ module Encoding : sig val sc_rollup_refute_case : Kind.sc_rollup_refute case val sc_rollup_timeout_case : Kind.sc_rollup_timeout case + + val das_slot_header_case : Kind.das_slot_header case end end diff --git a/src/proto_alpha/lib_protocol/raw_context.ml b/src/proto_alpha/lib_protocol/raw_context.ml index 37a2728b6fa394464a30f0db73fe8e9ead994339..0664122b02671cd1bfed2123cb2b7c4a22674979 100644 --- a/src/proto_alpha/lib_protocol/raw_context.ml +++ b/src/proto_alpha/lib_protocol/raw_context.ml @@ -247,6 +247,25 @@ type back = { tx_rollup_current_messages : Tx_rollup_inbox_repr.Merkle.tree Tx_rollup_repr.Map.t; sc_rollup_current_messages : Context.tree Sc_rollup_address_map_builder.t; + das_current_slot_proposals : + (Das_slot_repr.Header.t * Tez_repr.t) option FallbackArray.t; + (* DAS/FIXME We associate to a slot header some fees. This enable + the use of a fee market for slot publication. However, this is + not resiliant from the game theory point of view. Probably we can + find better incentives here. In any case, because we want the + following invariant: + + - For each level and for each slot there is at most one slot + header. + + We need to provide an incentive to avoid byzantines to post + dummy slot headers. *) + das_endorsement_slot_accountibility : bool FallbackArray.t FallbackArray.t; + (* DAS/FIXME Think harder about this representation: + + - For each slot, we record the shards which are available + + So we have an array of 256 * 2048 cells. *) } (* @@ -817,6 +836,18 @@ let prepare ~level ~predecessor_timestamp ~timestamp ctxt = stake_distribution_for_current_cycle = None; tx_rollup_current_messages = Tx_rollup_repr.Map.empty; sc_rollup_current_messages = Sc_rollup_carbonated_map.empty; + das_current_slot_proposals = + FallbackArray.make + constants.Constants_parametric_repr.das.number_of_slots + None; + das_endorsement_slot_accountibility = + FallbackArray.of_list + ~fallback:(FallbackArray.make 0 false) + ~proj:(fun _ -> + FallbackArray.make + constants.Constants_parametric_repr.das.number_of_shards + false) + Misc.(1 --> constants.Constants_parametric_repr.das.number_of_slots); }; } @@ -885,6 +916,15 @@ let prepare_first_block ~level ~timestamp ctxt = add_constants ctxt param.constants >|= ok | Jakarta_013 -> get_previous_protocol_constants ctxt >>= fun c -> + let das = + Constants_parametric_repr. + { + number_of_slots = 256; + number_of_shards = 2048; + endorsement_lag = 2; + availibility_threshold = 50; + } + in let constants = Constants_parametric_repr. { @@ -949,6 +989,7 @@ let prepare_first_block ~level ~timestamp ctxt = tx_rollup_rejection_max_proof_size = c.tx_rollup_rejection_max_proof_size; tx_rollup_sunset_level = c.tx_rollup_sunset_level; + das; sc_rollup_enable = false; (* The following value is chosen to prevent spam. *) sc_rollup_origination_size = 6_314; @@ -1424,3 +1465,60 @@ module Sc_rollup_in_memory_inbox = struct let back = {ctxt.back with sc_rollup_current_messages} in {ctxt with back} end + +module Das = struct + (* DAS/FIXME Can we find a better/faster representation? *) + let record_available_shards ctxt slots committed_shards = + let das_endorsement_slot_accountibility = + ctxt.back.das_endorsement_slot_accountibility + in + List.iter + (fun index -> + if Das_endorsement_repr.mem slots index then + let shards = + FallbackArray.get das_endorsement_slot_accountibility index + in + List.iter + (fun shard_index -> FallbackArray.set shards shard_index true) + committed_shards) + Misc.(0 --> (ctxt.back.constants.das.number_of_shards - 1)) + + let current_slot_fees ctxt Das_slot_repr.{slot; _} = + FallbackArray.get ctxt.back.das_current_slot_proposals slot + |> Option.map snd + + let update_slot ctxt Das_slot_repr.{slot; header; _} fees = + FallbackArray.set + ctxt.back.das_current_slot_proposals + slot + (Some (header, fees)) + + let get_pending_slot_headers ctxt = + FallbackArray.fold + (fun l x -> (x |> Option.map fst) :: l) + ctxt.back.das_current_slot_proposals + [] + |> List.rev + + let get_shards_availibility ctxt = + ctxt.back.das_endorsement_slot_accountibility + + (* DAS/FIXME We have to choose for the sampling. Here we use the one + used by the consensus which is hackish and probably not what we + want at the end. However, it should be enough for a + prototype. This has a very bad complexity too. *) + let shards ctxt ~endorser = + let max_shards = ctxt.back.constants.das.number_of_shards in + Slot_repr.Map.fold_e + (fun slot (_, public_key_hash, _) shards -> + (* Early fail because 2048 < 7000 *) + if Compare.Int.(Slot_repr.to_int slot >= max_shards) then Error shards + else if Signature.Public_key_hash.(public_key_hash = endorser) then + Ok (Slot_repr.to_int slot :: shards) + else Ok shards) + ctxt.back.consensus.allowed_endorsements + [] + |> function + | Ok shards -> shards + | Error shards -> shards +end diff --git a/src/proto_alpha/lib_protocol/raw_context.mli b/src/proto_alpha/lib_protocol/raw_context.mli index 913ccadb75d13fe97b7c0c7a4ff87200fac09993..e1097840bf76d2452ffb94d8cbecec2d45d72a47 100644 --- a/src/proto_alpha/lib_protocol/raw_context.mli +++ b/src/proto_alpha/lib_protocol/raw_context.mli @@ -370,3 +370,25 @@ module Sc_rollup_in_memory_inbox : sig val set_current_messages : t -> Sc_rollup_repr.t -> Context.tree -> t tzresult end + +module Das : sig + (* [record_available_shards records slots shards] records that the + list of shards [shards] were declared available. The function + assumes that a shard belongs to the interval [0; + number_of_shards]. + + This function has a side-effect and consequently should be used + carefully. In particular, we should not expect any backtracking + here. *) + val record_available_shards : t -> Das_endorsement_repr.t -> int list -> unit + + val current_slot_fees : t -> Das_slot_repr.t -> Tez_repr.t option + + val update_slot : t -> Das_slot_repr.t -> Tez_repr.t -> unit + + val get_pending_slot_headers : t -> Das_slot_repr.Header.t option list + + val get_shards_availibility : t -> bool FallbackArray.t FallbackArray.t + + val shards : t -> endorser:Signature.Public_key_hash.t -> int list +end diff --git a/src/proto_alpha/lib_protocol/storage.ml b/src/proto_alpha/lib_protocol/storage.ml index d4b0e00d6e3963d635932054eebf2a46e19d0fbc..b5290204aa1b4e9ede535523257c858615e1de3a 100644 --- a/src/proto_alpha/lib_protocol/storage.ml +++ b/src/proto_alpha/lib_protocol/storage.ml @@ -1647,3 +1647,35 @@ module Sc_rollup = struct let encoding = Sc_rollup_repr.Staker.encoding end) end + +module Das = struct + module Raw_context = + Make_subcontext (Registered) (Raw_context) + (struct + let name = ["das"] + end) + + module Level_context = + Make_indexed_subcontext + (Make_subcontext (Registered) (Raw_context) + (struct + let name = ["level"] + end)) + (Make_index (Raw_level_repr.Index)) + + (* DAS/FIXME: + + This is only for prototyping. Probably something smarter would be + to index each header directly. *) + module Slot_headers = + Level_context.Make_map + (struct + let name = ["slots"] + end) + (struct + type t = Das_slot_repr.Header.t option list + + let encoding = + Data_encoding.(list (option Das_slot_repr.Header.encoding)) + end) +end diff --git a/src/proto_alpha/lib_protocol/storage.mli b/src/proto_alpha/lib_protocol/storage.mli index e97d724f49b9f0b839d0896f37bc411e08ee02d6..9f856359d41c338951a0bde42c9c92811779310d 100644 --- a/src/proto_alpha/lib_protocol/storage.mli +++ b/src/proto_alpha/lib_protocol/storage.mli @@ -797,3 +797,11 @@ module Sc_rollup : sig and type value = Sc_rollup_repr.Staker.t and type t = Raw_context.t * Sc_rollup_repr.t end + +module Das : sig + module Slot_headers : + Non_iterable_indexed_data_storage + with type t = Raw_context.t + and type key = Raw_level_repr.t + and type value = Das_slot_repr.Header.t option list +end diff --git a/src/proto_alpha/lib_protocol/test/helpers/block.ml b/src/proto_alpha/lib_protocol/test/helpers/block.ml index f705a39183d1acc08cb7d0a6050038791e855a29..a46e59db709408d65fa08949c91fb7fc8546b5d9 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/block.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/block.ml @@ -743,7 +743,8 @@ let bake_n_with_all_balance_updates ?(baking_mode = Application) ?policy | Tx_rollup_dispatch_tickets_result _ | Sc_rollup_originate_result _ | Sc_rollup_add_messages_result _ | Sc_rollup_cement_result _ | Sc_rollup_publish_result _ - | Sc_rollup_refute_result _ | Sc_rollup_timeout_result _ -> + | Sc_rollup_refute_result _ | Sc_rollup_timeout_result _ + | Das_slot_header_result _ -> balance_updates_rev | Transaction_result (Transaction_to_contract_result {balance_updates; _}) @@ -788,7 +789,8 @@ let bake_n_with_origination_results ?(baking_mode = Application) ?policy n b = | Successful_manager_result (Sc_rollup_cement_result _) | Successful_manager_result (Sc_rollup_publish_result _) | Successful_manager_result (Sc_rollup_refute_result _) - | Successful_manager_result (Sc_rollup_timeout_result _) -> + | Successful_manager_result (Sc_rollup_timeout_result _) + | Successful_manager_result (Das_slot_header_result _) -> origination_results_rev | Successful_manager_result (Origination_result x) -> Origination_result x :: origination_results_rev) diff --git a/src/proto_alpha/lib_protocol/test/helpers/op.ml b/src/proto_alpha/lib_protocol/test/helpers/op.ml index cd795053dbe58acd196af107ed44674f4b52b84d..6562524dfeffa12014e1b9740528eb69fdc592c8 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/op.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/op.ml @@ -53,7 +53,7 @@ let mk_block_payload_hash pred_hash payload_round (b : Block.t) = (* ctxt is used for getting the branch in sign *) let endorsement ?delegate ?slot ?level ?round ?block_payload_hash - ~endorsed_block ctxt ?(signing_context = ctxt) () = + ?data_availibility ~endorsed_block ctxt ?(signing_context = ctxt) () = let pred_hash = match ctxt with Context.B b -> b.hash | _ -> assert false in (match delegate with | None -> Context.get_endorser (B endorsed_block) @@ -75,7 +75,14 @@ let endorsement ?delegate ?slot ?level ?round ?block_payload_hash | None -> mk_block_payload_hash pred_hash round endorsed_block | Some block_payload_hash -> block_payload_hash in - let consensus_content = {slot; level; round; block_payload_hash} in + let data_availibility = + match data_availibility with + | None -> Das.Endorsement.empty + | Some data_availibility -> data_availibility + in + let consensus_content = + {slot; level; round; block_payload_hash; data_availibility} + in let op = Single (Endorsement consensus_content) in Account.find delegate_pkh >>=? fun delegate -> return @@ -108,7 +115,10 @@ let preendorsement ?delegate ?slot ?level ?round ?block_payload_hash | None -> mk_block_payload_hash pred_hash round endorsed_block | Some block_payload_hash -> block_payload_hash in - let consensus_content = {slot; level; round; block_payload_hash} in + let data_availibility = () in + let consensus_content = + {slot; level; round; block_payload_hash; data_availibility} + in let op = Single (Preendorsement consensus_content) in Account.find delegate_pkh >>=? fun delegate -> return diff --git a/src/proto_alpha/lib_protocol/test/helpers/op.mli b/src/proto_alpha/lib_protocol/test/helpers/op.mli index 5a4165ccb78090cc5a30748fc2c9032f89daec2b..6198f613713d0e0178690f4fe768bcf9b66caa0e 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/op.mli +++ b/src/proto_alpha/lib_protocol/test/helpers/op.mli @@ -32,6 +32,7 @@ val endorsement : ?level:Raw_level.t -> ?round:Round.t -> ?block_payload_hash:Block_payload_hash.t -> + ?data_availibility:Das.Endorsement.t -> endorsed_block:Block.t -> Context.t -> ?signing_context:Context.t ->