123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152(*****************************************************************************)(* *)(* Open Source License *)(* Copyright (c) 2022 Nomadic Labs <contact@nomadic-labs.com> *)(* *)(* 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. *)(* *)(*****************************************************************************)(* DAL/FIXME https://gitlab.com/tezos/tezos/-/issues/3103
This may be a bit heavy in practice. We could also assume that in
practice, many bits in this bitfield will be set to one. Hence, we
could consider a better encoding which is smaller in the optimistic
case. For example:
1. When all the slots are attested, the encoding can be represented
in one bit.
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
attested, this representation will be of size [32] bits + [16] bits
= [48] bits which is better than [256] bits. *)(* A set of (attested) slot indexes. *)typet=Bitset.ttypeoperation={attestor:Signature.Public_key_hash.t;(* FIXME/DAL: https://gitlab.com/tezos/tezos/-/issues/4165
Compute the attester from the attested slots in [slot_attestation] below,
or provide a field `min_attester_slot : int / int32` *)attestation:t;level:Raw_level_repr.t;}letencoding=Bitset.encodingletempty=Bitset.emptyletis_attestedtindex=letopenDal_slot_index_reprinmatchBitset.memt(to_intindex)with|Okb->b|Error_->(* DAL/FIXME https://gitlab.com/tezos/tezos/-/issues/3104
Should we do something here? *)falseletcommittindex=letopenDal_slot_index_reprinmatchBitset.addt(to_intindex)with|Okt->t|Error_->(* DAL/FIXME https://gitlab.com/tezos/tezos/-/issues/3104
Should we do something here? *)tletoccupied_size_in_bits=Bitset.occupied_size_in_bitsletexpected_size_in_bits~max_index=(* We compute an encoding of the data-availability attestations
which is a (tight) upper bound of what we expect. *)letopenBitsetinletopenDal_slot_index_reprinmatchaddempty@@to_intmax_indexwith|Error_->(* Happens if max_index < 1 *)0|Okt->occupied_size_in_bitsttypeshard_index=intmoduleShard_map=Map.Make(structtypet=shard_indexletcompare=Compare.Int.compareend)moduleAccountability=structtypeattested_slots=t(* DAL/FIXME https://gitlab.com/tezos/tezos/-/issues/3109
Think hard about this data structure and whether it needs to be
optimized.
*)(* A list of set of shard indexes (a set of shards per slot) *)typet=Bitset.tlistletinit~length=letl=List.init~when_negative_length:"Dal_attestation_repr.Accountability.init: length cannot be negative"length(fun_->Bitset.empty)inmatchlwithErrormsg->invalid_argmsg|Okl->lletrecord_slot_shard_availabilitybitsetshards=List.fold_left(funbitsetshard->Bitset.addbitsetshard|>Result.value~default:bitset)bitsetshardsletrecord_attested_shardsshard_bitset_per_slotattested_slotsshards=List.mapi(funslotbitset->matchBitset.memattested_slotsslotwith|Error_->(* slot index is above the length provided at initialisation *)bitset|Okslot_attested->ifslot_attestedthenrecord_slot_shard_availabilitybitsetshardselsebitset)shard_bitset_per_slotletis_slot_attestedshard_bitset_per_slot~threshold~number_of_shardsindex=matchList.nthshard_bitset_per_slot(Dal_slot_index_repr.to_intindex)with|None->false|Somebitset->letacc=ref0inList.iter(funx->matchBitset.membitsetxwith|Error_|Okfalse->()|Oktrue->incracc)Misc.(0-->(number_of_shards-1));Compare.Int.(!acc>=threshold*number_of_shards/100)end