12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182(*****************************************************************************)(* *)(* Open Source License *)(* Copyright (c) 2021 Nomadic Labs <contact@nomadic-labs.com> *)(* Copyright (c) 2022 TriliTech <contact@trili.tech> *)(* *)(* 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. *)(* *)(*****************************************************************************)letlevel_indexctxtlevel=letmax_active_levels=Constants_storage.sc_rollup_max_active_outbox_levelsctxtinInt32.rem(Raw_level_repr.to_int32level)max_active_levelsletrecord_applied_messagectxtrolluplevel~message_index=letopenLwt_result_syntaxin(* Check that the 0 <= message index < maximum number of outbox messages per
level. *)let*?()=letmax_outbox_messages_per_level=Constants_storage.sc_rollup_max_outbox_messages_per_levelctxtinerror_unlessCompare.Int.(0<=message_index&&message_index<max_outbox_messages_per_level)Sc_rollup_errors.Sc_rollup_invalid_outbox_message_indexinletlevel_index=level_indexctxtlevelinlet*ctxt,level_and_bitset_opt=Storage.Sc_rollup.Applied_outbox_messages.find(ctxt,rollup)level_indexinlet*?bitset,ctxt=letopenResult_syntaxinlet*bitset,ctxt=matchlevel_and_bitset_optwith|Some(existing_level,bitset)whenRaw_level_repr.(existing_level=level)->(* The level at the index is the same as requested. Fail if the
message has been applied already. *)let*already_applied=Bitset.membitsetmessage_indexinlet*()=error_whenalready_appliedSc_rollup_errors.Sc_rollup_outbox_message_already_appliedinreturn(bitset,ctxt)|Some(existing_level,_bitset)whenRaw_level_repr.(level<existing_level)->tzfailSc_rollup_errors.Sc_rollup_outbox_level_expired|Some_|None->(* The old level is outdated or there is no previous bitset at
this index. *)return(Bitset.empty,ctxt)inlet*bitset=Bitset.addbitsetmessage_indexinreturn(bitset,ctxt)inlet+ctxt,size_diff,_is_new=Storage.Sc_rollup.Applied_outbox_messages.add(ctxt,rollup)level_index(level,bitset)in(Z.of_intsize_diff,ctxt)