From 7e28a89c4ec68554459e6df7b61d31429db485c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Thir=C3=A9?= Date: Wed, 20 Apr 2022 09:23:08 +0200 Subject: [PATCH 01/15] Protocol/Das/Misc: Implement size function --- src/proto_alpha/lib_protocol/bitset.ml | 2 ++ src/proto_alpha/lib_protocol/bitset.mli | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/proto_alpha/lib_protocol/bitset.ml b/src/proto_alpha/lib_protocol/bitset.ml index ab0bfd4d264a..9b2b9ba21666 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 0d8038eb6190..fd9b029b40f7 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 -- GitLab From a7ca7627ea281186d0ef37f581d14bebfd4415c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Thir=C3=A9?= Date: Mon, 11 Apr 2022 11:46:13 +0200 Subject: [PATCH 02/15] Protocol/Das: Implement slot representation --- src/proto_alpha/lib_protocol/TEZOS_PROTOCOL | 3 + src/proto_alpha/lib_protocol/das_slot_repr.ml | 60 +++++++++++++++++++ .../lib_protocol/das_slot_repr.mli | 40 +++++++++++++ src/proto_alpha/lib_protocol/dune.inc | 5 ++ 4 files changed, 108 insertions(+) create mode 100644 src/proto_alpha/lib_protocol/das_slot_repr.ml create mode 100644 src/proto_alpha/lib_protocol/das_slot_repr.mli diff --git a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL index 72597091ad41..728eeb24217f 100644 --- a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL +++ b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL @@ -66,6 +66,9 @@ "Tx_rollup_commitment_repr", "Tx_rollup_errors_repr", "Tx_rollup_state_repr", + + "Das_slot_repr", + "Bond_id_repr", "Vote_repr", "Liquidity_baking_repr", 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 000000000000..edfe74558275 --- /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 000000000000..d38c1dd6cc0c --- /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/dune.inc b/src/proto_alpha/lib_protocol/dune.inc index c2a5f6a6ff2f..7924547b39cc 100644 --- a/src/proto_alpha/lib_protocol/dune.inc +++ b/src/proto_alpha/lib_protocol/dune.inc @@ -91,6 +91,7 @@ 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 bond_id_repr.mli bond_id_repr.ml vote_repr.mli vote_repr.ml liquidity_baking_repr.mli liquidity_baking_repr.ml @@ -281,6 +282,7 @@ 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 bond_id_repr.mli bond_id_repr.ml vote_repr.mli vote_repr.ml liquidity_baking_repr.mli liquidity_baking_repr.ml @@ -471,6 +473,7 @@ 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 bond_id_repr.mli bond_id_repr.ml vote_repr.mli vote_repr.ml liquidity_baking_repr.mli liquidity_baking_repr.ml @@ -683,6 +686,7 @@ include Tezos_raw_protocol_alpha.Main Tx_rollup_commitment_repr Tx_rollup_errors_repr Tx_rollup_state_repr + Das_slot_repr Bond_id_repr Vote_repr Liquidity_baking_repr @@ -914,6 +918,7 @@ 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 bond_id_repr.mli bond_id_repr.ml vote_repr.mli vote_repr.ml liquidity_baking_repr.mli liquidity_baking_repr.ml -- GitLab From c3ee74988e881367411dae3cf2d8c1d906e16883 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Thir=C3=A9?= Date: Mon, 11 Apr 2022 14:59:29 +0200 Subject: [PATCH 03/15] Protocol/Das: Implement das state module --- src/proto_alpha/lib_protocol/TEZOS_PROTOCOL | 3 ++- .../lib_protocol/das_state_repr.ml | 26 +++++++++++++++++++ .../lib_protocol/das_state_repr.mli | 26 +++++++++++++++++++ src/proto_alpha/lib_protocol/dune.inc | 5 ++++ 4 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 src/proto_alpha/lib_protocol/das_state_repr.ml create mode 100644 src/proto_alpha/lib_protocol/das_state_repr.mli diff --git a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL index 728eeb24217f..359fe7f2bde2 100644 --- a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL +++ b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL @@ -68,7 +68,8 @@ "Tx_rollup_state_repr", "Das_slot_repr", - + "Das_state_repr", + "Bond_id_repr", "Vote_repr", "Liquidity_baking_repr", 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 000000000000..5a9526d1269a --- /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 000000000000..5a9526d1269a --- /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 7924547b39cc..cd30545e38ac 100644 --- a/src/proto_alpha/lib_protocol/dune.inc +++ b/src/proto_alpha/lib_protocol/dune.inc @@ -92,6 +92,7 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end 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 bond_id_repr.mli bond_id_repr.ml vote_repr.mli vote_repr.ml liquidity_baking_repr.mli liquidity_baking_repr.ml @@ -283,6 +284,7 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end 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 bond_id_repr.mli bond_id_repr.ml vote_repr.mli vote_repr.ml liquidity_baking_repr.mli liquidity_baking_repr.ml @@ -474,6 +476,7 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end 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 bond_id_repr.mli bond_id_repr.ml vote_repr.mli vote_repr.ml liquidity_baking_repr.mli liquidity_baking_repr.ml @@ -687,6 +690,7 @@ include Tezos_raw_protocol_alpha.Main Tx_rollup_errors_repr Tx_rollup_state_repr Das_slot_repr + Das_state_repr Bond_id_repr Vote_repr Liquidity_baking_repr @@ -919,6 +923,7 @@ include Tezos_raw_protocol_alpha.Main 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 bond_id_repr.mli bond_id_repr.ml vote_repr.mli vote_repr.ml liquidity_baking_repr.mli liquidity_baking_repr.ml -- GitLab From 0e53b7bdc72fbc9f3fb51f72f111778d44e07bba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Thir=C3=A9?= Date: Mon, 11 Apr 2022 16:56:10 +0200 Subject: [PATCH 04/15] Protocol/Das: Implement endorsement data for das --- src/proto_alpha/lib_protocol/TEZOS_PROTOCOL | 1 + .../lib_protocol/das_endorsement_repr.ml | 64 +++++++++++++++++++ .../lib_protocol/das_endorsement_repr.mli | 38 +++++++++++ src/proto_alpha/lib_protocol/dune.inc | 5 ++ 4 files changed, 108 insertions(+) create mode 100644 src/proto_alpha/lib_protocol/das_endorsement_repr.ml create mode 100644 src/proto_alpha/lib_protocol/das_endorsement_repr.mli diff --git a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL index 359fe7f2bde2..eef0c501fb9f 100644 --- a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL +++ b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL @@ -69,6 +69,7 @@ "Das_slot_repr", "Das_state_repr", + "Das_endorsement_repr", "Bond_id_repr", "Vote_repr", 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 000000000000..4a38b042fe91 --- /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 000000000000..c42259f5fd00 --- /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/dune.inc b/src/proto_alpha/lib_protocol/dune.inc index cd30545e38ac..bc4bae68bd08 100644 --- a/src/proto_alpha/lib_protocol/dune.inc +++ b/src/proto_alpha/lib_protocol/dune.inc @@ -93,6 +93,7 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end 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 @@ -285,6 +286,7 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end 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 @@ -477,6 +479,7 @@ module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end 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 @@ -691,6 +694,7 @@ include Tezos_raw_protocol_alpha.Main Tx_rollup_state_repr Das_slot_repr Das_state_repr + Das_endorsement_repr Bond_id_repr Vote_repr Liquidity_baking_repr @@ -924,6 +928,7 @@ include Tezos_raw_protocol_alpha.Main 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 -- GitLab From d8242c6fe54f7dad9bbf0bb3aeeab3ae567a4ff1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Thir=C3=A9?= Date: Mon, 11 Apr 2022 16:43:34 +0200 Subject: [PATCH 05/15] Protocol/Das: Implement das parametric constants --- src/proto_alpha/lib_client/mockup.ml | 16 +++++-- .../lib_parameters/default_parameters.ml | 11 +++++ .../lib_protocol/alpha_context.mli | 10 ++++ .../lib_protocol/constants_parametric_repr.ml | 47 +++++++++++++++++-- .../constants_parametric_repr.mli | 10 ++++ src/proto_alpha/lib_protocol/raw_context.ml | 10 ++++ 6 files changed, 98 insertions(+), 6 deletions(-) diff --git a/src/proto_alpha/lib_client/mockup.ml b/src/proto_alpha/lib_client/mockup.ml index 4b50846cb4db..936f1e5cecf2 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_parameters/default_parameters.ml b/src/proto_alpha/lib_parameters/default_parameters.ml index d22d07ac466a..581cb9d06326 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_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index 69671f95b943..5403d585e0c3 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; diff --git a/src/proto_alpha/lib_protocol/constants_parametric_repr.ml b/src/proto_alpha/lib_protocol/constants_parametric_repr.ml index b06fad409215..f725cb64a200 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 11a337495225..34de03b9cdb3 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/raw_context.ml b/src/proto_alpha/lib_protocol/raw_context.ml index 37a2728b6fa3..4772f311b6c7 100644 --- a/src/proto_alpha/lib_protocol/raw_context.ml +++ b/src/proto_alpha/lib_protocol/raw_context.ml @@ -885,6 +885,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 +958,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; -- GitLab From 2cb7852b3de5efd5773ec9f2f617e797db0bcefa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Thir=C3=A9?= Date: Mon, 11 Apr 2022 11:53:18 +0200 Subject: [PATCH 06/15] Protocol/Das: Implement das in raw context --- src/proto_alpha/lib_protocol/raw_context.ml | 88 ++++++++++++++++++++ src/proto_alpha/lib_protocol/raw_context.mli | 22 +++++ 2 files changed, 110 insertions(+) diff --git a/src/proto_alpha/lib_protocol/raw_context.ml b/src/proto_alpha/lib_protocol/raw_context.ml index 4772f311b6c7..0664122b0267 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); }; } @@ -1434,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 913ccadb75d1..e1097840bf76 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 -- GitLab From 47d8091cce34a8b91677e72eb9d3297010665edb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Thir=C3=A9?= Date: Mon, 11 Apr 2022 14:44:54 +0200 Subject: [PATCH 07/15] Protocol/Das: Implement storage --- src/proto_alpha/lib_protocol/storage.ml | 32 ++++++++++++++++++++++++ src/proto_alpha/lib_protocol/storage.mli | 8 ++++++ 2 files changed, 40 insertions(+) diff --git a/src/proto_alpha/lib_protocol/storage.ml b/src/proto_alpha/lib_protocol/storage.ml index d4b0e00d6e39..b5290204aa1b 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 e97d724f49b9..9f856359d41c 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 -- GitLab From 1d6065c10109a8be1186e05426720cb5f78352cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Thir=C3=A9?= Date: Tue, 26 Apr 2022 14:46:29 +0200 Subject: [PATCH 08/15] Protocol/Das: Implement `das_slot_storage` --- src/proto_alpha/lib_protocol/TEZOS_PROTOCOL | 2 + .../lib_protocol/das_slot_storage.ml | 84 +++++++++++++++++++ .../lib_protocol/das_slot_storage.mli | 35 ++++++++ src/proto_alpha/lib_protocol/dune.inc | 5 ++ 4 files changed, 126 insertions(+) create mode 100644 src/proto_alpha/lib_protocol/das_slot_storage.ml create mode 100644 src/proto_alpha/lib_protocol/das_slot_storage.mli diff --git a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL index eef0c501fb9f..9107a1bd5e37 100644 --- a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL +++ b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL @@ -139,6 +139,8 @@ "Sc_rollup_costs", "Sc_rollup_storage", + "Das_slot_storage", + "Alpha_context", "Script_string", "Script_int", 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 000000000000..4ea86d24fbf7 --- /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 000000000000..b7f72408f503 --- /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/dune.inc b/src/proto_alpha/lib_protocol/dune.inc index bc4bae68bd08..ef31a7b4c92d 100644 --- a/src/proto_alpha/lib_protocol/dune.inc +++ b/src/proto_alpha/lib_protocol/dune.inc @@ -154,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 @@ -347,6 +348,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 @@ -540,6 +542,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 @@ -755,6 +758,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 @@ -989,6 +993,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 -- GitLab From 9f7210b930499324f6debe696c59f0a2af7ad3cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Thir=C3=A9?= Date: Mon, 11 Apr 2022 14:04:35 +0200 Subject: [PATCH 09/15] Protocol/Das: Exporting Alpha_context signature --- src/proto_alpha/lib_protocol/alpha_context.ml | 13 +++++ .../lib_protocol/alpha_context.mli | 50 ++++++++++++++++++- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/proto_alpha/lib_protocol/alpha_context.ml b/src/proto_alpha/lib_protocol/alpha_context.ml index b963576c8f14..37961666b395 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 5403d585e0c3..32ad0e07788d 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -2741,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 -> @@ -2961,7 +2999,7 @@ type 'a consensus_operation_type = val pp_operation_kind : 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 @@ -2969,10 +3007,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 = { @@ -2999,7 +3045,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; -- GitLab From d9a60f4b99e0820e8f2a7494992844788a312f8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Thir=C3=A9?= Date: Wed, 20 Apr 2022 09:29:32 +0200 Subject: [PATCH 10/15] Protocol/Das: Add "das_apply.ml" file --- src/proto_alpha/lib_protocol/TEZOS_PROTOCOL | 2 + src/proto_alpha/lib_protocol/das_apply.ml | 85 +++++++++++++++++++++ src/proto_alpha/lib_protocol/das_apply.mli | 40 ++++++++++ src/proto_alpha/lib_protocol/dune.inc | 5 ++ 4 files changed, 132 insertions(+) create mode 100644 src/proto_alpha/lib_protocol/das_apply.ml create mode 100644 src/proto_alpha/lib_protocol/das_apply.mli diff --git a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL index 9107a1bd5e37..c4431ae0bf1e 100644 --- a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL +++ b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL @@ -194,6 +194,8 @@ "Sc_rollup_arith", "Sc_rollups", + "Das_apply", + "Baking", "Amendment", "Apply", 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 000000000000..3e4bd23c73c5 --- /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 000000000000..a0ca788b113d --- /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/dune.inc b/src/proto_alpha/lib_protocol/dune.inc index ef31a7b4c92d..b1d4133fadba 100644 --- a/src/proto_alpha/lib_protocol/dune.inc +++ b/src/proto_alpha/lib_protocol/dune.inc @@ -202,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 @@ -396,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 @@ -590,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 @@ -806,6 +809,7 @@ include Tezos_raw_protocol_alpha.Main Sc_rollup_PVM_sem Sc_rollup_arith Sc_rollups + Das_apply Baking Amendment Apply @@ -1041,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 -- GitLab From 8da133910f3a0a07ce39848a96265992d2118b29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Thir=C3=A9?= Date: Mon, 11 Apr 2022 14:04:57 +0200 Subject: [PATCH 11/15] Protocol/Das: Add a way to publish a slot header operation --- src/proto_alpha/lib_client/injection.ml | 3 ++ .../lib_client/operation_result.ml | 22 +++++++++++++ src/proto_alpha/lib_injector/l1_operation.ml | 2 ++ .../lib_protocol/alpha_context.mli | 11 +++++++ src/proto_alpha/lib_protocol/apply.ml | 16 ++++++++-- src/proto_alpha/lib_protocol/apply_results.ml | 24 ++++++++++++++ .../lib_protocol/apply_results.mli | 4 +++ .../lib_protocol/operation_repr.ml | 32 +++++++++++++++++++ .../lib_protocol/operation_repr.mli | 11 +++++++ .../lib_protocol/test/helpers/block.ml | 6 ++-- 10 files changed, 127 insertions(+), 4 deletions(-) diff --git a/src/proto_alpha/lib_client/injection.ml b/src/proto_alpha/lib_client/injection.ml index 36ad1384955c..864f085e931f 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/operation_result.ml b/src/proto_alpha/lib_client/operation_result.ml index 58e3cb4c80c0..66cd12c905e1 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_injector/l1_operation.ml b/src/proto_alpha/lib_injector/l1_operation.ml index 53ee27416bf6..9135626d41b8 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_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index 32ad0e07788d..e4b893414d36 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -2965,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 @@ -2990,6 +2992,7 @@ 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 = @@ -3201,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 @@ -3366,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 : { @@ -3427,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 32df61a1941b..b1e035e94173 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) -> ( diff --git a/src/proto_alpha/lib_protocol/apply_results.ml b/src/proto_alpha/lib_protocol/apply_results.ml index 312d09ab8f1b..29852922911a 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 70a2ddadfb44..757c4dc394b5 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/operation_repr.ml b/src/proto_alpha/lib_protocol/operation_repr.ml index ea4f9d380fa6..fcd1d1418340 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,6 +128,7 @@ 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 = @@ -389,6 +392,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 +424,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 +512,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 +1039,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 = @@ -1397,6 +1422,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 +1686,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 47371a1c23be..9bb4658ad5aa 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,6 +157,7 @@ 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 = @@ -458,6 +461,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 +610,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 +672,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/test/helpers/block.ml b/src/proto_alpha/lib_protocol/test/helpers/block.ml index f705a39183d1..a46e59db7094 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) -- GitLab From ef1374353abdbd27cf62402aeaa96aac7b296e91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Thir=C3=A9?= Date: Tue, 19 Apr 2022 18:31:07 +0200 Subject: [PATCH 12/15] Protocol/Das: Implement slots availibility in endorsements --- .../lib_delegate/baking_actions.ml | 2 +- .../lib_delegate/baking_actions.mli | 6 +- src/proto_alpha/lib_delegate/baking_lib.ml | 20 ++- .../client_baking_denunciation.ml | 17 +-- .../lib_delegate/state_transitions.ml | 17 ++- .../lib_delegate/state_transitions.mli | 5 +- src/proto_alpha/lib_plugin/plugin.ml | 19 ++- .../lib_protocol/alpha_context.mli | 8 +- src/proto_alpha/lib_protocol/apply.ml | 117 ++++++++++-------- .../lib_protocol/operation_repr.ml | 73 ++++++----- .../lib_protocol/operation_repr.mli | 23 ++-- .../lib_protocol/test/helpers/op.ml | 16 ++- .../lib_protocol/test/helpers/op.mli | 1 + 13 files changed, 199 insertions(+), 125 deletions(-) diff --git a/src/proto_alpha/lib_delegate/baking_actions.ml b/src/proto_alpha/lib_delegate/baking_actions.ml index 81dfefc9f74b..2a161b5364a6 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 83789e84892f..02d5d9c23d61 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 f47d397a1a31..4e4a6746c7f7 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 4f3638131307..76e3022b7f26 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 dd978072e535..0d3422ef4b83 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 4b14864cb1de..4528f3b420cb 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_plugin/plugin.ml b/src/proto_alpha/lib_plugin/plugin.ml index fa563890968c..68cf341d7c07 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 diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index e4b893414d36..d2625f94d908 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -2995,12 +2995,12 @@ module Kind : sig | 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 'data_availibility raw_consensus_content = { slot : Slot.t; diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index b1e035e94173..b1bc49f44981 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -2514,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 @@ -2622,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 @@ -2646,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 @@ -2675,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 @@ -2703,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) -> @@ -2783,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 @@ -2866,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) -> @@ -2960,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 diff --git a/src/proto_alpha/lib_protocol/operation_repr.ml b/src/proto_alpha/lib_protocol/operation_repr.ml index fcd1d1418340..19c6dc430192 100644 --- a/src/proto_alpha/lib_protocol/operation_repr.ml +++ b/src/proto_alpha/lib_protocol/operation_repr.ml @@ -131,17 +131,18 @@ module Kind = struct | 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 @@ -149,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 @@ -236,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; @@ -1103,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 = diff --git a/src/proto_alpha/lib_protocol/operation_repr.mli b/src/proto_alpha/lib_protocol/operation_repr.mli index 9bb4658ad5aa..084206b8a10f 100644 --- a/src/proto_alpha/lib_protocol/operation_repr.mli +++ b/src/proto_alpha/lib_protocol/operation_repr.mli @@ -160,14 +160,15 @@ module Kind : sig | 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; @@ -175,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 = @@ -233,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 diff --git a/src/proto_alpha/lib_protocol/test/helpers/op.ml b/src/proto_alpha/lib_protocol/test/helpers/op.ml index cd795053dbe5..6562524dfeff 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 5a4165ccb780..6198f613713d 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 -> -- GitLab From d3ec6bcb2eba0dd6c5db8355af0b6e822713549f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Thir=C3=A9?= Date: Tue, 26 Apr 2022 14:56:55 +0200 Subject: [PATCH 13/15] Protocol/Das: Implement das finalization --- src/proto_alpha/lib_protocol/apply.ml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index b1bc49f44981..0db15d306c3b 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -3520,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) -- GitLab From 96388b1d41358383cfd71a629bd31da2e31b88a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Thir=C3=A9?= Date: Fri, 29 Apr 2022 19:26:53 +0200 Subject: [PATCH 14/15] Plugin/Das: Implement RPCs --- src/proto_alpha/lib_plugin/plugin.ml | 44 ++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/proto_alpha/lib_plugin/plugin.ml b/src/proto_alpha/lib_plugin/plugin.ml index 68cf341d7c07..dd44870d7205 100644 --- a/src/proto_alpha/lib_plugin/plugin.ml +++ b/src/proto_alpha/lib_plugin/plugin.ml @@ -4348,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 @@ -4415,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 -- GitLab From d31b5c0208782ddc1d818db32fc9c4764c9e2e64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Thir=C3=A9?= Date: Tue, 17 May 2022 17:56:51 +0200 Subject: [PATCH 15/15] [skip-ci] -- GitLab